"use client"

import { useRef, useState } from "react"
import { useQueryClient } from "@tanstack/react-query"
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Info, Smartphone } from "lucide-react"
import { parseContactFile, type ContactImportInput } from "@/lib/contacts/import-parsers"
import { bulkImportContacts, importInputToBulk } from "@/lib/api/contacts-bulk-import"
import { deviceContactsAvailable, fetchDeviceContacts } from "@/lib/native/contacts"
import { invalidateContactListCache } from "@/lib/api/contact-list-cache"
import { useContactsList } from "@/lib/contacts/use-contacts-list"
import {
  CONTACTS_HEADING_TEXT,
  CONTACTS_MUTED_TEXT,
  CONTACTS_PAGE_LINK_BTN_CLASS,
  CONTACTS_PANEL_MUTED_ICON_CLASS,
  CONTACTS_PRIMARY_BTN_CLASS,
} from "@/lib/contacts-chrome-classes"
import { cn } from "@/lib/utils"

interface ImportDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
}

export function ImportDialog({ open, onOpenChange }: ImportDialogProps) {
  const fileRef = useRef<HTMLInputElement>(null)
  const queryClient = useQueryClient()
  const { bookId } = useContactsList()
  const [pendingFile, setPendingFile] = useState<File | null>(null)
  const [previewCount, setPreviewCount] = useState(0)
  const [error, setError] = useState<string | null>(null)
  const [importing, setImporting] = useState(false)
  const [result, setResult] = useState<string | null>(null)

  function resetState() {
    setPendingFile(null)
    setPreviewCount(0)
    setError(null)
    setImporting(false)
    setResult(null)
    if (fileRef.current) fileRef.current.value = ""
  }

  function handleOpenChange(next: boolean) {
    if (!next) resetState()
    onOpenChange(next)
  }

  function handleFileSelect() {
    fileRef.current?.click()
  }

  async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (!file) return

    setError(null)
    setPendingFile(file)

    try {
      const parsed = await parseContactFile(file)
      setPreviewCount(parsed.length)
      if (parsed.length === 0) {
        setError("Aucun contact trouvé dans ce fichier.")
      }
    } catch {
      setError("Impossible de lire ce fichier.")
      setPreviewCount(0)
    }
  }

  async function runImport(parsed: ContactImportInput[]) {
    if (parsed.length === 0) {
      setError("Aucun contact à importer.")
      return
    }
    setImporting(true)
    setError(null)
    setResult(null)
    try {
      const { created, failed } = await bulkImportContacts(
        bookId,
        parsed.map(importInputToBulk)
      )
      invalidateContactListCache(bookId)
      void queryClient.invalidateQueries({ queryKey: ["contacts", bookId] })
      if (failed.length > 0) {
        setResult(`${created} importé(s), ${failed.length} en échec.`)
      } else {
        handleOpenChange(false)
      }
    } catch {
      setError("L'import a échoué. Vérifiez le format du fichier.")
    } finally {
      setImporting(false)
    }
  }

  async function handleImport() {
    if (!pendingFile || previewCount === 0) return
    try {
      const parsed = await parseContactFile(pendingFile)
      await runImport(parsed)
    } catch {
      setError("L'import a échoué. Vérifiez le format du fichier.")
    }
  }

  async function handleDeviceImport() {
    setImporting(true)
    setError(null)
    try {
      const parsed = await fetchDeviceContacts()
      await runImport(parsed)
    } catch (err) {
      const msg = err instanceof Error ? err.message : "device_error"
      setError(
        msg === "contacts_unavailable" || msg.includes("denied")
          ? "Accès aux contacts du téléphone refusé."
          : "Impossible de lire les contacts du téléphone."
      )
      setImporting(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <div className="flex items-center justify-between">
            <DialogTitle>Importer des contacts</DialogTitle>
            <Info className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />
          </div>
        </DialogHeader>
        <div className="space-y-4 py-2">
          <p className={cn("text-sm", CONTACTS_HEADING_TEXT)}>
            Pour commencer, sélectionnez un fichier.
            <br />
            Utilisez le format CSV ou vCard (.vcf).
          </p>

          <Button type="button" onClick={handleFileSelect} className={CONTACTS_PRIMARY_BTN_CLASS}>
            Sélectionner un fichier
          </Button>

          {deviceContactsAvailable() && (
            <Button
              type="button"
              variant="outline"
              onClick={() => void handleDeviceImport()}
              disabled={importing}
              className="w-full gap-2"
            >
              <Smartphone className="h-4 w-4" />
              Importer depuis le téléphone
            </Button>
          )}

          <input
            ref={fileRef}
            type="file"
            accept=".csv,.vcf,.vcard,text/vcard,text/csv"
            className="hidden"
            onChange={handleFileChange}
          />

          {pendingFile && previewCount > 0 && (
            <p className={cn("text-sm", CONTACTS_HEADING_TEXT)}>
              {previewCount} contact{previewCount > 1 ? "s" : ""} prêt
              {previewCount > 1 ? "s" : ""} à importer depuis{" "}
              <span className="font-medium">{pendingFile.name}</span>
            </p>
          )}

          {result && <p className="text-sm text-amber-600">{result}</p>}
          {error && <p className="text-sm text-red-600">{error}</p>}

          <p className={cn("text-xs", CONTACTS_MUTED_TEXT)}>
            Vous essayez de sauvegarder les contacts de votre mobile ?
            <br />
            <span className="cursor-pointer text-primary">Voici comment les synchroniser.</span>
          </p>
        </div>
        <div className="flex justify-end gap-3">
          <Button
            type="button"
            variant="ghost"
            onClick={() => handleOpenChange(false)}
            className={CONTACTS_PAGE_LINK_BTN_CLASS}
          >
            Non, ne rien faire
          </Button>
          <Button
            type="button"
            onClick={handleImport}
            disabled={!pendingFile || previewCount === 0 || importing}
            className="text-sm font-medium"
          >
            {importing ? "Importation…" : "Importer"}
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  )
}
