"use client"

import { useMemo, useState } from "react"
import { Check, Loader2, X } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  useAcceptEnrichmentSuggestion,
  useRejectEnrichmentSuggestion,
  useVisibleEnrichmentSuggestions,
} from "@/lib/api/hooks/use-contact-discovery"
import { useContactsList } from "@/lib/contacts/use-contacts-list"
import { useUpdateContact } from "@/lib/api/hooks/use-contact-mutations"
import {
  FIELD_LABELS,
  profileDisplayName,
} from "@/lib/contacts/discovery-utils"
import type { ApiEnrichmentSuggestion } from "@/lib/contacts/discovery-types"
import type { ApiContact } from "@/lib/api/types"
import { contactApiPath } from "@/lib/contacts/contact-api-path"
import type { FullContact } from "@/lib/contacts/types"
import {
  CONTACTS_HEADING_TEXT,
  CONTACTS_MUTED_TEXT,
  CONTACTS_DISCOVERY_FIELD_ROW_CLASS,
  CONTACTS_PAGE_CARD_CLASS,
  CONTACTS_PAGE_SECTION_TITLE_CLASS,
  CONTACTS_PRIMARY_BTN_CLASS,
} from "@/lib/contacts-chrome-classes"
import {
  DiscoveryCardsMasonry,
  DiscoveryCardsMasonryItem,
} from "@/components/gmail/contacts-page/discovery-cards-masonry"
import {
  DiscoveryFieldChips,
  type ChipFieldItem,
} from "@/components/gmail/contacts-page/discovery-field-chips"
import { cn } from "@/lib/utils"

const ACTION_BTN_CLASS = "h-9 rounded-full px-4 text-xs sm:text-sm"

export function AddCoordinatesView() {
  const { suggestions, isLoading } = useVisibleEnrichmentSuggestions()
  const acceptSuggestion = useAcceptEnrichmentSuggestion()
  const rejectSuggestion = useRejectEnrichmentSuggestion()
  const { contacts } = useContactsList()
  const updateContact = useUpdateContact()
  const [acceptingGroupKey, setAcceptingGroupKey] = useState<string | null>(null)

  const grouped = useMemo(() => {
    const map = new Map<string, ApiEnrichmentSuggestion[]>()
    for (const s of suggestions) {
      const key = s.target_contact_uid ?? s.profile_id ?? s.id
      const list = map.get(key) ?? []
      list.push(s)
      map.set(key, list)
    }
    return [...map.entries()]
  }, [suggestions])

  async function handleAccept(suggestion: ApiEnrichmentSuggestion) {
    if (suggestion.suggestion_type === "enrich_contact" && suggestion.target_contact_uid) {
      const contact = contacts.find((c) => c.id === suggestion.target_contact_uid)
      if (contact) {
        const patch = buildContactPatch(contact, suggestion)
        await updateContact.mutateAsync({
          path: contactApiPath(contact),
          etag: contact.etag,
          contact: patch,
        })
      }
    }
    await acceptSuggestion.mutateAsync(suggestion.id)
  }

  async function handleAcceptAll(groupKey: string, group: ApiEnrichmentSuggestion[]) {
    setAcceptingGroupKey(groupKey)
    try {
      const first = group[0]
      if (first.suggestion_type === "enrich_contact" && first.target_contact_uid) {
        const contact = contacts.find((c) => c.id === first.target_contact_uid)
        if (contact) {
          const patch = buildMergedContactPatch(contact, group)
          await updateContact.mutateAsync({
            path: contactApiPath(contact),
            etag: contact.etag,
            contact: patch,
          })
        }
      }
      for (const s of group) {
        await acceptSuggestion.mutateAsync(s.id)
      }
    } finally {
      setAcceptingGroupKey(null)
    }
  }

  const busy = acceptSuggestion.isPending || updateContact.isPending

  return (
    <div>
      <div className="mb-4 flex items-center justify-between">
        <h3 className={CONTACTS_PAGE_SECTION_TITLE_CLASS}>
          Ajouter des coordonnées ({suggestions.length})
        </h3>
      </div>

      {isLoading && (
        <p className={cn("py-8 text-center text-sm", CONTACTS_MUTED_TEXT)}>Chargement…</p>
      )}

      {!isLoading && suggestions.length === 0 && (
        <p className={cn("py-8 text-center text-sm", CONTACTS_MUTED_TEXT)}>
          Aucune suggestion disponible. Analysez vos e-mails depuis « Autres contacts » pour détecter des coordonnées dans les signatures.
        </p>
      )}

      <DiscoveryCardsMasonry>
        {grouped.map(([key, group]) => (
          <DiscoveryCardsMasonryItem key={key}>
            <SuggestionGroup
              suggestions={group}
              contacts={contacts}
              onAccept={handleAccept}
              onAcceptAll={() => handleAcceptAll(key, group)}
              onReject={(id) => rejectSuggestion.mutate(id)}
              busy={busy}
              acceptingAll={acceptingGroupKey === key}
            />
          </DiscoveryCardsMasonryItem>
        ))}
      </DiscoveryCardsMasonry>
    </div>
  )
}

function SuggestionGroup({
  suggestions,
  contacts,
  onAccept,
  onAcceptAll,
  onReject,
  busy,
  acceptingAll,
}: {
  suggestions: ApiEnrichmentSuggestion[]
  contacts: FullContact[]
  onAccept: (s: ApiEnrichmentSuggestion) => void
  onAcceptAll: () => void
  onReject: (id: string) => void
  busy: boolean
  acceptingAll: boolean
}) {
  const first = suggestions[0]
  const profile = first.profile
  const existing = first.target_contact_uid
    ? contacts.find((c) => c.id === first.target_contact_uid)
    : null

  const title = existing
    ? `${existing.firstName} ${existing.lastName}`.trim() || existing.emails[0]?.value
    : profile
      ? profileDisplayName(profile)
      : "Contact suggéré"

  const chipItems: ChipFieldItem[] = suggestions.map((s) => ({
    id: s.id,
    fieldKey: s.field_path,
    value: s.suggested_value,
  }))

  return (
    <div className={CONTACTS_PAGE_CARD_CLASS}>
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div className="min-w-0 flex-1">
          <p className={cn("text-sm font-medium leading-tight", CONTACTS_HEADING_TEXT)}>{title}</p>
          {first.suggestion_type === "enrich_contact" && (
            <p className={cn("text-[11px]", CONTACTS_MUTED_TEXT)}>
              Enrichissement · {suggestions.length} champ{suggestions.length > 1 ? "s" : ""}
            </p>
          )}
        </div>
        <div className="flex shrink-0 items-center gap-2">
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={onAcceptAll}
            disabled={busy}
            className={ACTION_BTN_CLASS}
          >
            {acceptingAll ? (
              <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />
            ) : (
              <Check className="mr-1.5 h-3.5 w-3.5" />
            )}
            Tout ajouter
          </Button>
        </div>
      </div>

      <DiscoveryFieldChips
        items={chipItems}
        dismissible
        onRemove={(id) => onReject(id)}
      />

      <details className="mt-2">
        <summary className={cn("cursor-pointer text-[11px]", CONTACTS_MUTED_TEXT)}>
          Gérer champ par champ
        </summary>
        <ul className="mt-2 space-y-1">
          {suggestions.map((s) => (
            <li
              key={s.id}
              className={CONTACTS_DISCOVERY_FIELD_ROW_CLASS}
            >
              <span className={cn("min-w-0 truncate text-xs", CONTACTS_HEADING_TEXT)}>
                <span className={CONTACTS_MUTED_TEXT}>
                  {FIELD_LABELS[s.field_path] ?? s.field_path} :
                </span>{" "}
                {s.suggested_value}
              </span>
              <div className="flex shrink-0 items-center gap-1">
                <button
                  type="button"
                  onClick={() => onReject(s.id)}
                  className="rounded-full p-1 text-muted-foreground hover:bg-accent"
                  aria-label="Ignorer"
                >
                  <X className="h-3.5 w-3.5" />
                </button>
                <Button
                  size="sm"
                  onClick={() => onAccept(s)}
                  disabled={busy}
                  className="h-7 rounded-full px-2.5 text-[11px]"
                >
                  <Check className="mr-1 h-3 w-3" />
                  Accepter
                </Button>
              </div>
            </li>
          ))}
        </ul>
      </details>
    </div>
  )
}

function buildContactPatch(
  contact: FullContact,
  suggestion: ApiEnrichmentSuggestion,
): Partial<ApiContact> {
  const { field_path, suggested_value } = suggestion
  switch (field_path) {
    case "full_name":
      return { full_name: suggested_value }
    case "company":
      return { org: suggested_value }
    case "job_title":
      return { raw_vcard: appendVCardField(contact, "TITLE", suggested_value) }
    case "phones":
      return { phone: suggested_value }
    case "emails":
      return { email: suggested_value }
    case "social_profiles": {
      const type = (suggestion.suggested_label || "other").toLowerCase()
      return {
        raw_vcard: appendVCardSocialProfile(contact, type, suggested_value),
      }
    }
    default:
      return { raw_vcard: appendVCardField(contact, field_path.toUpperCase(), suggested_value) }
  }
}

function buildMergedContactPatch(
  contact: FullContact,
  suggestions: ApiEnrichmentSuggestion[],
): Partial<ApiContact> {
  const patch: Partial<ApiContact> = {}
  let vcardExtra = ""

  for (const s of suggestions) {
    const part = buildContactPatch(contact, s)
    if (part.full_name) patch.full_name = part.full_name
    if (part.org) patch.org = part.org
    if (part.phone) patch.phone = part.phone
    if (part.email) patch.email = part.email
    if (part.raw_vcard && part.raw_vcard !== patch.raw_vcard) {
      vcardExtra += part.raw_vcard.replace(/^BEGIN:VCARD[\s\S]*?VERSION:3\.0\n/, "").replace(/\nEND:VCARD$/, "\n")
    }
  }

  if (vcardExtra) {
    const base = `BEGIN:VCARD\nVERSION:3.0\nFN:${contact.firstName} ${contact.lastName}\n`
    patch.raw_vcard = `${base}${vcardExtra}END:VCARD`
  }

  return patch
}

function appendVCardField(contact: FullContact, prop: string, value: string): string {
  const base = `BEGIN:VCARD\nVERSION:3.0\nFN:${contact.firstName} ${contact.lastName}\n`
  return `${base}${prop}:${value}\nEND:VCARD`
}

function appendVCardSocialProfile(contact: FullContact, type: string, value: string): string {
  const base = `BEGIN:VCARD\nVERSION:3.0\nFN:${contact.firstName} ${contact.lastName}\n`
  const socialType = type === "x" ? "twitter" : type
  return `${base}X-SOCIALPROFILE;TYPE=${socialType}:${value}\nEND:VCARD`
}
