import * as React from 'npm:react@18.3.1'
import { renderAsync } from 'npm:@react-email/components@0.0.22'
import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0'
import { createClient } from 'npm:@supabase/supabase-js@2'
import { SignupEmail } from '../_shared/email-templates/signup.tsx'
import { InviteEmail } from '../_shared/email-templates/invite.tsx'
import { MagicLinkEmail } from '../_shared/email-templates/magic-link.tsx'
import { RecoveryEmail } from '../_shared/email-templates/recovery.tsx'
import { EmailChangeEmail } from '../_shared/email-templates/email-change.tsx'
import { ReauthenticationEmail } from '../_shared/email-templates/reauthentication.tsx'

// This is the Supabase Auth "Send Email" hook. Supabase Auth POSTs a
// Standard Webhooks-signed payload here whenever it needs to send an auth email
// (signup confirmation, password reset, invite, magic link, email change,
// reauthentication). We verify the signature, render the matching branded
// template, and enqueue it for the dispatcher (process-email-queue) to send.
//
// Migrated off Lovable: verification now uses the native Supabase hook secret
// (SEND_EMAIL_HOOK_SECRET, format "v1,whsec_<base64>") via the standardwebhooks
// library — no @lovable.dev/* dependencies.

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers':
    'authorization, x-client-info, apikey, content-type, webhook-id, webhook-timestamp, webhook-signature',
}

const EMAIL_SUBJECTS: Record<string, string> = {
  signup: 'Confirm your email',
  invite: "You've been invited",
  magiclink: 'Your login link',
  recovery: 'Reset your password',
  email_change: 'Confirm your new email',
  reauthentication: 'Your verification code',
}

const EMAIL_TEMPLATES: Record<string, React.ComponentType<any>> = {
  signup: SignupEmail,
  invite: InviteEmail,
  magiclink: MagicLinkEmail,
  recovery: RecoveryEmail,
  email_change: EmailChangeEmail,
  reauthentication: ReauthenticationEmail,
}

const SITE_NAME = 'Avria Community Management, LLC'
const ROOT_DOMAIN = 'avria.cloud'
const FROM_ADDRESS = `"${SITE_NAME.replace(/"/g, '\\"')}" <noreply@${ROOT_DOMAIN}>`

// Normalize GoTrue email_action_type to our template keys.
function normalizeActionType(actionType: string): string {
  if (actionType.startsWith('email_change')) return 'email_change'
  return actionType
}

// Build the GoTrue verification URL from the hashed token. Hitting this URL
// consumes the token and then redirects the user to redirect_to.
function buildConfirmationUrl(supabaseUrl: string, emailData: any): string {
  const params = new URLSearchParams({
    token: emailData.token_hash ?? '',
    type: emailData.email_action_type ?? '',
  })
  if (emailData.redirect_to) params.set('redirect_to', emailData.redirect_to)
  return `${supabaseUrl.replace(/\/$/, '')}/auth/v1/verify?${params.toString()}`
}

async function handleWebhook(req: Request): Promise<Response> {
  const hookSecret = Deno.env.get('SEND_EMAIL_HOOK_SECRET')
  if (!hookSecret) {
    console.error('SEND_EMAIL_HOOK_SECRET not configured')
    return new Response(
      JSON.stringify({ error: 'Server configuration error' }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }

  const payloadRaw = await req.text()
  const headers = Object.fromEntries(req.headers)

  // Verify the Standard Webhooks signature. The library expects the base64
  // secret without the "v1,whsec_" prefix Supabase displays.
  let verified: any
  try {
    const wh = new Webhook(hookSecret.replace(/^v1,whsec_/, ''))
    verified = wh.verify(payloadRaw, headers)
  } catch (error) {
    console.error('Auth hook signature verification failed', {
      error: error instanceof Error ? error.message : String(error),
    })
    return new Response(
      JSON.stringify({ error: 'Invalid signature' }),
      { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }

  const user = verified.user
  const emailData = verified.email_data
  const recipient: string | undefined = user?.email
  const rawActionType: string = emailData?.email_action_type ?? ''
  const emailType = normalizeActionType(rawActionType)

  console.log('Received auth send-email hook', { emailType, rawActionType, recipient })

  const EmailTemplate = EMAIL_TEMPLATES[emailType]
  if (!EmailTemplate || !recipient) {
    console.error('Unknown email type or missing recipient', { emailType, hasRecipient: !!recipient })
    return new Response(
      JSON.stringify({ error: `Unsupported email action type: ${rawActionType}` }),
      { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }

  const supabaseUrl = Deno.env.get('SUPABASE_URL')!
  const confirmationUrl = buildConfirmationUrl(supabaseUrl, emailData)

  const templateProps = {
    siteName: SITE_NAME,
    siteUrl: `https://${ROOT_DOMAIN}`,
    recipient,
    confirmationUrl,
    token: emailData?.token,
    email: recipient,
    newEmail: user?.new_email ?? recipient,
  }

  const html = await renderAsync(React.createElement(EmailTemplate, templateProps))
  const text = await renderAsync(React.createElement(EmailTemplate, templateProps), {
    plainText: true,
  })

  const supabase = createClient(
    supabaseUrl,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  )

  const messageId = crypto.randomUUID()

  // Log pending BEFORE enqueue so we have a record even if enqueue crashes
  await supabase.from('email_send_log').insert({
    message_id: messageId,
    template_name: emailType,
    recipient_email: recipient,
    status: 'pending',
  })

  const { error: enqueueError } = await supabase.rpc('enqueue_email', {
    queue_name: 'auth_emails',
    payload: {
      message_id: messageId,
      to: recipient,
      from: FROM_ADDRESS,
      subject: EMAIL_SUBJECTS[emailType] || 'Notification',
      html,
      text,
      purpose: 'transactional',
      label: emailType,
      queued_at: new Date().toISOString(),
    },
  })

  if (enqueueError) {
    console.error('Failed to enqueue auth email', { error: enqueueError, emailType })
    await supabase.from('email_send_log').insert({
      message_id: messageId,
      template_name: emailType,
      recipient_email: recipient,
      status: 'failed',
      error_message: 'Failed to enqueue email',
    })
    return new Response(JSON.stringify({ error: 'Failed to enqueue email' }), {
      status: 500,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    })
  }

  console.log('Auth email enqueued', { emailType, recipient })

  // Supabase expects a 200 with an empty/again-acknowledged body on success.
  return new Response(
    JSON.stringify({}),
    { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
  )
}

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders })
  }
  try {
    return await handleWebhook(req)
  } catch (error) {
    console.error('Auth hook handler error:', error)
    const message = error instanceof Error ? error.message : 'Unknown error'
    return new Response(JSON.stringify({ error: message }), {
      status: 500,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    })
  }
})
