import { normalizePhilippinePhone } from '../lib/phone';
import { sendEmail } from './email.service';
import prisma from '../lib/prisma';

const OTP_LENGTH = parseInt(process.env.OTP_LENGTH || '6', 10);
const OTP_EXPIRY_MINUTES = parseInt(process.env.OTP_EXPIRY_MINUTES || '10', 10);

function generateCode(): string {
  return Math.floor(100000 + Math.random() * 900000)
    .toString()
    .slice(0, OTP_LENGTH);
}

/** Normalize destination: email (lowercase) or Philippine phone. */
export function normalizeOtpDestination(destination: string): {
  value: string;
  channel: 'email' | 'phone';
} {
  const trimmed = destination.trim();
  if (trimmed.includes('@')) {
    return { value: trimmed.toLowerCase(), channel: 'email' };
  }
  return { value: normalizePhilippinePhone(trimmed), channel: 'phone' };
}

/**
 * Create an OTP for email or phone.
 * Stored in OTPVerification.phone (destination key) for both channels.
 */
export async function createOTP(
  destination: string,
  purpose: string,
  userId?: string,
  metadata?: Record<string, unknown>
) {
  const { value, channel } = normalizeOtpDestination(destination);
  const code = generateCode();
  const expiresAt = new Date(Date.now() + OTP_EXPIRY_MINUTES * 60 * 1000);

  await prisma.oTPVerification.create({
    data: {
      phone: value,
      code,
      purpose,
      userId,
      expiresAt,
      metadata: metadata
        ? ({ ...metadata, channel } as object)
        : ({ channel } as object),
    },
  });

  if (channel === 'email') {
    await sendEmail({
      to: value,
      subject: `Your eHandyHire verification code: ${code}`,
      text: `Your verification code is ${code}. It expires in ${OTP_EXPIRY_MINUTES} minutes.\n\nIf you did not request this, you can ignore this email.`,
      html: `<p>Your verification code is <strong style="font-size:1.25rem;letter-spacing:0.08em">${code}</strong>.</p><p>It expires in ${OTP_EXPIRY_MINUTES} minutes.</p><p style="color:#64748b;font-size:12px">If you did not request this, you can ignore this email.</p>`,
    });
  } else if (process.env.NODE_ENV !== 'production') {
    console.log(`📱 OTP for ${value}: ${code} (expires in ${OTP_EXPIRY_MINUTES} min)`);
  }

  return { code, expiresAt, channel, destination: value };
}

export async function verifyOTP(destination: string, code: string, purpose: string) {
  const { value } = normalizeOtpDestination(destination);
  const otp = await prisma.oTPVerification.findFirst({
    where: {
      phone: value,
      code,
      purpose,
      isUsed: false,
      expiresAt: { gt: new Date() },
    },
    orderBy: { createdAt: 'desc' },
  });

  if (!otp) {
    return { valid: false, otp: null };
  }

  await prisma.oTPVerification.update({
    where: { id: otp.id },
    data: { isUsed: true },
  });

  return { valid: true, otp };
}
