"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import { MoreHorizontal, Pencil, Trash2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { AddMailAccountForm } from "@/components/gmail/settings/add-mail-account-form"
import { EditMailAccountForm } from "@/components/gmail/settings/edit-mail-account-form"
import { HostedMailSetupCard } from "@/components/gmail/settings/hosted-mail-setup-card"
import { SignatureLibraryCard } from "@/components/gmail/settings/signature-library-card"
import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries"
import {
  useCreateMailAccount,
  useDeleteMailAccount,
  useResanitizeBodies,
  useSyncMailAccount,
} from "@/lib/api/hooks/use-mail-account-mutations"
import { useIdentities } from "@/lib/api/hooks/use-folder-label-queries"
import {
  useCreateIdentity,
  useUpdateIdentity,
  useDeleteIdentity,
} from "@/lib/api/hooks/use-identity-mutations"
import { useMailSignatures } from "@/lib/api/hooks/use-mail-signatures"
import { SettingsSectionHeader } from "@/components/gmail/settings/settings-section-header"
import { SettingsSyncBanner } from "@/components/gmail/settings/settings-sync-banner"
import { useAuthReady } from "@/lib/api/use-auth-ready"
import type { ApiMailAccount, ApiMailSignature } from "@/lib/api/types"

const NONE_SIGNATURE = "__none__"

export function AccountsSettingsSection() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const oauthStatus = searchParams.get("oauth")
  const { ready, authenticated } = useAuthReady()
  const { data: accounts = [], isFetching, isError, refetch, isPending } = useMailAccounts()
  const {
    data: signatures = [],
    isFetching: signaturesFetching,
    isError: signaturesError,
    refetch: refetchSignatures,
    isPending: signaturesPending,
  } = useMailSignatures()
  const createAccount = useCreateMailAccount()
  const showInitialLoad = ready && authenticated && isPending && accounts.length === 0
  const showSignaturesInitialLoad =
    ready && authenticated && signaturesPending && signatures.length === 0

  useEffect(() => {
    if (oauthStatus === "success") {
      void refetch()
      router.replace("/mail/settings/accounts")
    }
  }, [oauthStatus, refetch, router])

  const syncFetching = isFetching || signaturesFetching
  const syncError = isError || signaturesError

  function handleRetry() {
    void refetch()
    void refetchSignatures()
  }

  return (
    <>
      <SettingsSectionHeader
        title="Comptes mail"
        description="Connexions IMAP/SMTP, identités d'envoi et signatures."
      />
      {oauthStatus === "success" ? (
        <p className="text-sm text-green-600 dark:text-green-500">
          Compte mail connecté via OAuth.
        </p>
      ) : null}
      {oauthStatus === "error" ? (
        <p className="text-sm text-destructive">
          Échec de la connexion OAuth
          {searchParams.get("code") ? ` (${searchParams.get("code")})` : ""}.
        </p>
      ) : null}
      <SettingsSyncBanner
        isFetching={syncFetching}
        isError={syncError}
        onRetry={handleRetry}
      />

      <div className="space-y-6">
        <HostedMailSetupCard />

        <AddMailAccountForm
          pending={createAccount.isPending}
          onSubmit={(payload) => createAccount.mutate(payload)}
        />

        {!ready || showInitialLoad ? null : accounts.length === 0 ? (
          <p className="text-sm text-muted-foreground">
            Aucun compte mail configuré. Ajoutez votre adresse e-mail ci-dessus pour commencer.
          </p>
        ) : (
          accounts.map((account) => (
            <AccountCard key={account.id} account={account} signatures={signatures} />
          ))
        )}

        <SignatureLibraryCard
          signatures={signatures}
          showInitialLoad={showSignaturesInitialLoad}
        />
      </div>
    </>
  )
}

function AccountCard({
  account,
  signatures,
}: {
  account: ApiMailAccount
  signatures: ApiMailSignature[]
}) {
  const deleteAccount = useDeleteMailAccount()
  const resanitizeBodies = useResanitizeBodies(account.id)
  const syncAccount = useSyncMailAccount(account.id)
  const { data: identities = [] } = useIdentities(account.id)
  const [editing, setEditing] = useState(false)
  const [maintenanceMessage, setMaintenanceMessage] = useState<string | null>(null)

  async function runResanitize() {
    setMaintenanceMessage(null)
    try {
      const result = await resanitizeBodies.mutateAsync()
      setMaintenanceMessage(
        `Corps réimportés depuis IMAP : ${result.updated} message(s) mis à jour sur ${result.scanned} analysé(s).`
      )
    } catch {
      setMaintenanceMessage("Échec de la réimportation des corps depuis IMAP.")
    }
  }

  async function runSync(force = false) {
    setMaintenanceMessage(null)
    try {
      await syncAccount.mutateAsync({ force })
      setMaintenanceMessage(
        force
          ? "Re-synchronisation complète IMAP terminée."
          : "Synchronisation IMAP terminée."
      )
    } catch {
      setMaintenanceMessage("Échec de la synchronisation IMAP.")
    }
  }

  const maintenancePending = resanitizeBodies.isPending || syncAccount.isPending

  return (
    <Card>
      <CardHeader className="flex flex-row items-start justify-between gap-3 space-y-0">
        <div>
          <CardTitle className="text-base">{account.name}</CardTitle>
          <CardDescription>{account.email}</CardDescription>
          <p className="mt-1 text-xs text-muted-foreground">
            IMAP {account.imap_host} · SMTP {account.smtp_host}
            {account.last_sync_at
              ? ` · Dernière sync : ${new Date(account.last_sync_at).toLocaleString("fr-FR")}`
              : null}
          </p>
        </div>
        <div className="flex shrink-0 gap-1">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button
                type="button"
                variant="ghost"
                size="icon"
                aria-label="Actions avancées du compte"
                disabled={maintenancePending}
              >
                <MoreHorizontal className="size-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem
                disabled={maintenancePending}
                onClick={() => void runResanitize()}
              >
                {resanitizeBodies.isPending
                  ? "Réimportation IMAP…"
                  : "Réimporter les corps depuis IMAP"}
              </DropdownMenuItem>
              <DropdownMenuItem
                disabled={maintenancePending}
                onClick={() => void runSync()}
              >
                {syncAccount.isPending ? "Synchronisation…" : "Synchroniser IMAP"}
              </DropdownMenuItem>
              <DropdownMenuItem
                disabled={maintenancePending}
                onClick={() => void runSync(true)}
              >
                Forcer re-sync complet
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            aria-label="Modifier le compte"
            aria-pressed={editing}
            onClick={() => setEditing((v) => !v)}
          >
            <Pencil className="size-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            aria-label="Supprimer le compte"
            onClick={() => deleteAccount.mutate(account.id)}
          >
            <Trash2 className="size-4" />
          </Button>
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        {maintenanceMessage ? (
          <p className="text-sm text-muted-foreground">{maintenanceMessage}</p>
        ) : null}
        {editing ? (
          <EditMailAccountForm account={account} onCancel={() => setEditing(false)} />
        ) : null}
        <IdentitiesBlock
          accountId={account.id}
          accountEmail={account.email}
          identities={identities}
          signatures={signatures}
        />
      </CardContent>
    </Card>
  )
}

function IdentitiesBlock({
  accountId,
  accountEmail,
  identities,
  signatures,
}: {
  accountId: string
  accountEmail: string
  identities: Array<{
    id: string
    email: string
    name: string
    is_default: boolean
    signature_html?: string
    default_signature_id?: string
    reply_to_addrs?: string[]
  }>
  signatures: ApiMailSignature[]
}) {
  const createIdentity = useCreateIdentity(accountId)
  const updateIdentity = useUpdateIdentity(accountId)
  const deleteIdentity = useDeleteIdentity(accountId)
  const [showAddForm, setShowAddForm] = useState(false)
  const [newIdentity, setNewIdentity] = useState({ email: accountEmail, name: "" })

  const signatureOptions = useMemo(
    () => [
      { value: NONE_SIGNATURE, label: "Aucune" },
      ...signatures.map((s) => ({ value: s.id, label: s.name })),
    ],
    [signatures]
  )

  useEffect(() => {
    if (!showAddForm) {
      setNewIdentity({ email: accountEmail, name: "" })
    }
  }, [accountEmail, showAddForm])

  function identityPayload(
    identity: (typeof identities)[number],
    patch: Partial<{
      email: string
      name: string
      is_default: boolean
      default_signature_id: string
    }> = {}
  ) {
    return {
      identityId: identity.id,
      email: patch.email ?? identity.email,
      name: patch.name ?? identity.name,
      is_default: patch.is_default ?? identity.is_default,
      signature_html: identity.signature_html ?? "",
      default_signature_id: patch.default_signature_id ?? identity.default_signature_id ?? "",
      reply_to_addrs: identity.reply_to_addrs,
    }
  }

  function handleCreateIdentity() {
    const email = newIdentity.email.trim()
    const name = newIdentity.name.trim()
    if (!email) return
    createIdentity.mutate(
      {
        email,
        name: name || email.split("@")[0] || "Identité",
        is_default: identities.length === 0,
      },
      {
        onSuccess: () => {
          setShowAddForm(false)
          setNewIdentity({ email: accountEmail, name: "" })
        },
      }
    )
  }

  return (
    <div className="space-y-3">
      <h3 className="text-sm font-medium">Identités d&apos;envoi</h3>
      {identities.length === 0 ? (
        <p className="text-xs text-muted-foreground">Aucune identité configurée.</p>
      ) : (
        <ul className="space-y-3">
          {identities.map((identity) => {
            const currentSignature =
              identity.default_signature_id && identity.default_signature_id !== ""
                ? identity.default_signature_id
                : NONE_SIGNATURE

            return (
              <li key={identity.id} className="rounded-lg border border-border p-3 space-y-2">
                <div className="flex items-start justify-between gap-2">
                  <div className="grid flex-1 gap-2 sm:grid-cols-3">
                    <div className="space-y-1">
                      <Label className="text-xs">Nom affiché</Label>
                      <Input
                        defaultValue={identity.name}
                        onBlur={(e) => {
                          const next = e.target.value.trim()
                          if (!next || next === identity.name) return
                          updateIdentity.mutate(identityPayload(identity, { name: next }))
                        }}
                      />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-xs">Adresse d&apos;envoi</Label>
                      <Input
                        type="email"
                        defaultValue={identity.email}
                        onBlur={(e) => {
                          const next = e.target.value.trim()
                          if (!next || next === identity.email) return
                          updateIdentity.mutate(identityPayload(identity, { email: next }))
                        }}
                      />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-xs">Signature</Label>
                      <Select
                        value={currentSignature}
                        disabled={updateIdentity.isPending}
                        onValueChange={(value) =>
                          updateIdentity.mutate(
                            identityPayload(identity, {
                              default_signature_id: value === NONE_SIGNATURE ? "" : value,
                            })
                          )
                        }
                      >
                        <SelectTrigger className="w-full">
                          <SelectValue placeholder="Signature" />
                        </SelectTrigger>
                        <SelectContent>
                          {signatureOptions.map((opt) => (
                            <SelectItem key={opt.value} value={opt.value}>
                              {opt.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                    {identity.is_default ? (
                      <p className="text-xs text-muted-foreground sm:col-span-3">
                        Identité par défaut
                      </p>
                    ) : null}
                  </div>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    aria-label="Supprimer l'identité"
                    onClick={() => deleteIdentity.mutate(identity.id)}
                  >
                    <Trash2 className="size-3.5" />
                  </Button>
                </div>
              </li>
            )
          })}
        </ul>
      )}

      {showAddForm ? (
        <div className="rounded-lg border border-border p-3 space-y-3 max-w-lg">
          <div className="grid gap-2 sm:grid-cols-2">
            <div className="space-y-1">
              <Label className="text-xs">Nom affiché</Label>
              <Input
                value={newIdentity.name}
                placeholder="Nom visible"
                onChange={(e) => setNewIdentity({ ...newIdentity, name: e.target.value })}
              />
            </div>
            <div className="space-y-1">
              <Label className="text-xs">Adresse d&apos;envoi</Label>
              <Input
                type="email"
                value={newIdentity.email}
                onChange={(e) => setNewIdentity({ ...newIdentity, email: e.target.value })}
              />
            </div>
          </div>
          <div className="flex gap-2">
            <Button
              type="button"
              size="sm"
              disabled={createIdentity.isPending || !newIdentity.email.trim()}
              onClick={handleCreateIdentity}
            >
              Créer l&apos;identité
            </Button>
            <Button type="button" size="sm" variant="ghost" onClick={() => setShowAddForm(false)}>
              Annuler
            </Button>
          </div>
        </div>
      ) : (
        <Button
          type="button"
          variant="outline"
          size="sm"
          disabled={createIdentity.isPending}
          onClick={() => setShowAddForm(true)}
        >
          Ajouter une identité
        </Button>
      )}
    </div>
  )
}
