import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.45.0'

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

const formatEST = (iso?: string | null) => {
  if (!iso) return ''
  try {
    const d = new Date(iso)
    return new Intl.DateTimeFormat('en-US', {
      timeZone: 'America/New_York',
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: 'numeric',
      minute: '2-digit',
      hour12: true,
    }).format(d) + ' ET'
  } catch {
    return ''
  }
}

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders })

  try {
    const { announcement_id } = await req.json()
    if (!announcement_id) {
      return new Response(JSON.stringify({ error: 'announcement_id required' }), {
        status: 400,
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      })
    }

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

    const { data: ann, error: annErr } = await supabase
      .from('announcements')
      .select('*')
      .eq('id', announcement_id)
      .single()

    if (annErr || !ann) {
      return new Response(JSON.stringify({ error: 'announcement not found' }), {
        status: 404,
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      })
    }

    // Skip if expired or not active
    if (ann.status !== 'active') {
      return new Response(JSON.stringify({ ok: true, skipped: 'inactive' }), {
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      })
    }
    if (ann.expires_at && new Date(ann.expires_at) <= new Date()) {
      return new Response(JSON.stringify({ ok: true, skipped: 'expired' }), {
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      })
    }

    // public_only is community page only — do not email
    if (ann.visibility === 'public_only') {
      return new Response(JSON.stringify({ ok: true, skipped: 'public_only' }), {
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      })
    }

    // Determine recipient user_ids based on visibility
    const recipientUserIds = new Set<string>()

    // Always include staff (admin + manager)
    const { data: staffRows } = await supabase
      .from('user_roles')
      .select('user_id')
      .in('role', ['admin', 'manager'])
    for (const r of staffRows || []) if (r.user_id) recipientUserIds.add(r.user_id)

    // Board members — scope to association if set, else all
    let boardQuery = supabase.from('board_members').select('user_id, association_id')
    if (ann.association_id) boardQuery = boardQuery.eq('association_id', ann.association_id)
    const { data: boardRows } = await boardQuery
    for (const r of boardRows || []) if (r.user_id) recipientUserIds.add(r.user_id)

    // Homeowners (only when visibility is 'all' or 'public')
    const includeHomeowners = ann.visibility === 'all' || ann.visibility === 'public'
    let homeownerEmails: { email: string; name: string }[] = []
    if (includeHomeowners) {
      let ownerQuery = supabase
        .from('owners')
        .select('user_id, email, first_name, last_name, status')
        .eq('status', 'active')
      if (ann.association_id) ownerQuery = ownerQuery.eq('association_id', ann.association_id)
      const { data: ownerRows } = await ownerQuery
      for (const o of ownerRows || []) {
        if (o.user_id) recipientUserIds.add(o.user_id)
        else if (o.email) {
          homeownerEmails.push({
            email: String(o.email).trim(),
            name: [o.first_name, o.last_name].filter(Boolean).join(' '),
          })
        }
      }
    }

    // Look up emails from auth.users for collected user_ids
    const userIdList = Array.from(recipientUserIds)
    const recipients: { email: string; name: string; id: string }[] = []

    if (userIdList.length > 0) {
      // paginate auth users
      let page = 1
      while (true) {
        const { data: authData, error: authErr } = await supabase.auth.admin.listUsers({ page, perPage: 1000 })
        if (authErr || !authData?.users?.length) break
        for (const u of authData.users) {
          if (recipientUserIds.has(u.id) && u.email) {
            const meta: any = u.user_metadata || {}
            recipients.push({
              email: u.email,
              name: meta.full_name || meta.first_name || '',
              id: u.id,
            })
          }
        }
        if (authData.users.length < 1000) break
        page++
        if (page > 10) break
      }
    }

    // Add homeowner emails (no auth account)
    for (const h of homeownerEmails) {
      recipients.push({ email: h.email, name: h.name, id: `owner-${h.email}` })
    }

    // Dedupe by lowercased email
    const seen = new Set<string>()
    const uniqueRecipients = recipients.filter(r => {
      const key = r.email.toLowerCase()
      if (seen.has(key)) return false
      seen.add(key)
      return true
    })

    // Look up association name for context
    let associationName = ''
    if (ann.association_id) {
      const { data: assoc } = await supabase
        .from('associations')
        .select('name')
        .eq('id', ann.association_id)
        .single()
      associationName = assoc?.name || ''
    }

    const postedAt = formatEST(ann.created_at)
    const expiresAt = formatEST(ann.expires_at)

    let sent = 0
    let failed = 0
    for (const r of uniqueRecipients) {
      try {
        const { error: emailError } = await supabase.functions.invoke('send-transactional-email', {
          body: {
            templateName: 'announcement-broadcast',
            recipientEmail: r.email,
            idempotencyKey: `announcement-${ann.id}-${r.id}`,
            templateData: {
              recipientName: r.name || '',
              title: ann.title,
              contentHtml: ann.content || '',
              postedAt,
              expiresAt,
              associationName,
            },
          },
        })
        if (emailError) {
          failed++
          console.error(`Email to ${r.email} failed:`, emailError)
        } else {
          sent++
        }
      } catch (e) {
        failed++
        console.error(`Email exception for ${r.email}:`, e)
      }
    }

    return new Response(
      JSON.stringify({ ok: true, recipients: uniqueRecipients.length, sent, failed }),
      { headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
    )
  } catch (err: any) {
    console.error('notify-announcement error:', err)
    return new Response(JSON.stringify({ error: err.message || String(err) }), {
      status: 500,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    })
  }
})
