import bcrypt from 'bcryptjs'
import crypto from 'crypto'
import { AppError } from '../../http/errors'
import { prisma } from '../../lib/prisma'
import { sendTransactionalEmail } from '../../services/notificationService'
import * as repo from './auth.company.repo'
import type { output } from 'zod'
import type { accountStartSchema } from './auth.account.schemas'

type AccountStartInput = output<typeof accountStartSchema>

function ensureDashboardBasePath(baseUrl: string) {
  try {
    const url = new URL(baseUrl)
    const pathname = url.pathname.replace(/\/$/, '')
    if (!pathname.endsWith('/dashboard')) url.pathname = `${pathname}/dashboard`
    return url.toString().replace(/\/$/, '')
  } catch {
    const trimmed = baseUrl.replace(/\/$/, '')
    return trimmed.endsWith('/dashboard') ? trimmed : `${trimmed}/dashboard`
  }
}

/**
 * Minimal account creation — Step 0 of progressive signup.
 * Creates a DRAFT company + OWNER employee, sends a verification email.
 * The user must verify their email before they can log in.
 */
export async function startAccount(body: AccountStartInput) {
  if (await repo.findEmployeeByEmail(body.email)) {
    throw new AppError('An account with this email already exists', 409, 'email_taken')
  }

  const slug = `company-${Date.now().toString(36)}`
  const passwordHash = await bcrypt.hash(body.password, 12)
  const verificationToken = crypto.randomBytes(32).toString('hex')

  const result = await prisma.$transaction(async (tx: any) => {
    const now = new Date()
    const trialEndAt = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)

    const company = await tx.company.create({
      data: {
        name: '',
        slug,
        email: body.email,
        address: {},
        status: 'TRIALING',
      },
    })

    await tx.brandSettings.create({
      data: {
        companyId: company.id,
        displayName: body.email.split('@')[0] || 'My Workspace',
        subdomain: slug,
        defaultLocale: body.preferredLanguage,
        defaultCurrency: 'MAD',
      },
    })

    await tx.subscription.create({
      data: {
        companyId: company.id,
        plan: 'STARTER',
        billingPeriod: 'MONTHLY',
        currency: 'MAD',
        status: 'TRIALING',
        trialStartAt: now,
        trialEndAt,
        currentPeriodStart: now,
        currentPeriodEnd: trialEndAt,
      },
    })

    const employee = await tx.employee.create({
      data: {
        companyId: company.id,
        clerkUserId: `local_owner_${company.id}`,
        firstName: '',
        lastName: '',
        email: body.email,
        passwordHash,
        emailVerificationToken: verificationToken,
        role: 'OWNER',
        preferredLanguage: body.preferredLanguage,
        isActive: true,
      },
      include: { company: true },
    })

    return { employee, company }
  })

  const dashboardUrl = ensureDashboardBasePath(
    process.env.DASHBOARD_URL ?? process.env.NEXT_PUBLIC_DASHBOARD_URL ?? 'http://localhost:3000/dashboard',
  )
  const verifyUrl = `${dashboardUrl}/verify-email?token=${encodeURIComponent(verificationToken)}`

  const emailSubjects: Record<'en' | 'fr' | 'ar', string> = {
    en: 'Verify your email — RentalDriveGo',
    fr: 'Vérifiez votre email — RentalDriveGo',
    ar: 'تحقق من بريدك الإلكتروني — RentalDriveGo',
  }
  const emailBodies: Record<'en' | 'fr' | 'ar', string> = {
    en: `<p>Welcome to RentalDriveGo!</p><p>Click the link below to verify your email and activate your account:</p><p><a href="${verifyUrl}">Verify Email</a></p><p>If you did not create this account, you can safely ignore this email.</p>`,
    fr: `<p>Bienvenue sur RentalDriveGo !</p><p>Cliquez sur le lien ci-dessous pour vérifier votre email et activer votre compte :</p><p><a href="${verifyUrl}">Vérifier l'email</a></p><p>Si vous n'avez pas créé ce compte, ignorez cet email.</p>`,
    ar: `<p>مرحباً بك في RentalDriveGo!</p><p>انقر على الرابط أدناه للتحقق من بريدك الإلكتروني وتفعيل حسابك:</p><p><a href="${verifyUrl}">تحقق من البريد الإلكتروني</a></p><p>إذا لم تقم بإنشاء هذا الحساب، يمكنك تجاهل هذا البريد الإلكتروني.</p>`,
  }
  const emailTexts: Record<'en' | 'fr' | 'ar', string> = {
    en: `Welcome to RentalDriveGo!\n\nVerify your email by visiting:\n${verifyUrl}\n\nIf you did not create this account, you can safely ignore this email.`,
    fr: `Bienvenue sur RentalDriveGo !\n\nVérifiez votre email en visitant :\n${verifyUrl}\n\nSi vous n'avez pas créé ce compte, ignorez cet email.`,
    ar: `مرحباً بك في RentalDriveGo!\n\nتحقق من بريدك الإلكتروني بزيارة:\n${verifyUrl}\n\nإذا لم تقم بإنشاء هذا الحساب، يمكنك تجاهل هذا البريد الإلكتروني.`,
  }

  const lang: 'en' | 'fr' | 'ar' =
    body.preferredLanguage === 'ar' || body.preferredLanguage === 'fr'
      ? body.preferredLanguage
      : 'en'

  await sendTransactionalEmail({
    to: body.email,
    subject: emailSubjects[lang],
    html: emailBodies[lang],
    text: emailTexts[lang],
  }).catch((err) => {
    console.error('[AccountStart] Verification email delivery failed:', err?.message ?? String(err))
    console.error('[AccountStart] SMTP config — host:', process.env.MAIL_HOST ?? 'not set', '| port:', process.env.MAIL_PORT ?? 'not set', '| user:', process.env.MAIL_USERNAME ? '***' : 'not set', '| pass:', process.env.MAIL_PASSWORD ? '***' : 'not set')
    console.error('[AccountStart] Resend config — apiKey:', process.env.RESEND_API_KEY ? (process.env.RESEND_API_KEY.startsWith('re_') ? 'valid' : 'placeholder') : 'not set')
  })

  return {
    message: 'Account created. Please check your email to verify your address before signing in.',
    email: body.email,
  }
}
