import type { EmailConfig, EmailUserConfig } from '@auth/core/providers/email';
import { generateRandomString, RandomReader } from '@oslojs/crypto/random';
import { alphabet } from 'oslo/crypto';
import { UseSend } from 'usesend-js';

export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
  return {
    id: 'usesend',
    type: 'email',
    name: 'UseSend',
    from: process.env.USESEND_FROM_EMAIL ?? 'noreply@example.com',
    maxAge: 24 * 60 * 60, // 24 hours

    generateVerificationToken: () => {
      const random: RandomReader = {
        read: (bytes) => {
          crypto.getRandomValues(bytes as Uint8Array<ArrayBuffer>);
        },
      };
      return generateRandomString(random, alphabet('0-9'), 6);
    },

    sendVerificationRequest: async (params) => {
      const { identifier: to, provider, url, token } = params;
      // Derive a display name from the site URL, fallback to 'App'
      const siteUrl = process.env.USESEND_FROM_EMAIL ?? '';
      const appName = siteUrl.split('@')[1]?.split('.')[0] ?? 'App';

      const apiKey = process.env.USESEND_API_KEY;
      const useSendUrl = process.env.USESEND_URL;
      if (!apiKey || !useSendUrl) {
        throw new Error('USESEND_API_KEY and USESEND_URL must be set.');
      }

      const useSend = new UseSend(apiKey, useSendUrl);

      // For password reset, we want to send the code, not the magic link
      const isPasswordReset =
        url.includes('reset') || provider.id.includes('reset');

      const result = await useSend.emails.send({
        from: provider.from ?? 'noreply@example.com',
        to: [to],
        subject: isPasswordReset
          ? `Reset your password - ${appName}`
          : `Sign in to ${appName}`,
        text: isPasswordReset
          ? `Your password reset code is ${token}`
          : `Your sign in code is ${token}`,
        html: isPasswordReset
          ? `
          <div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">
            <h2>Password Reset Request</h2>
            <p>You requested a password reset. Your reset code is:</p>
            <div style="font-size: 32px; font-weight: bold; text-align: center; padding: 20px; background: #f5f5f5; margin: 20px 0; border-radius: 8px;">
              ${token}
            </div>
            <p>This code expires in 1 hour.</p>
            <p>If you didn't request this, please ignore this email.</p>
          </div>
        `
          : `
          <div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">
            <h2>Your Sign In Code</h2>
            <p>Your verification code is:</p>
            <div style="font-size: 32px; font-weight: bold; text-align: center; padding: 20px; background: #f5f5f5; margin: 20px 0; border-radius: 8px;">
              ${token}
            </div>
            <p>This code expires in 24 hours.</p>
          </div>
        `,
      });

      if (result.error) {
        throw new Error('UseSend error: ' + JSON.stringify(result.error));
      }
    },

    options: config,
  };
}

// Create specific instances for password reset and email verification
export const UseSendOTPPasswordReset = UseSendProvider({
  id: 'usesend-otp-password-reset',
  apiKey: process.env.USESEND_API_KEY,
  maxAge: 60 * 60, // 1 hour
});

export const UseSendOTP = UseSendProvider({
  id: 'usesend-otp',
  apiKey: process.env.USESEND_API_KEY,
  maxAge: 60 * 20, // 20 minutes
});
