"use client"

import { useEffect, useState } from "react"
import { ChevronDown, ChevronUp, Loader2, Mail } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { ProtonBridgeWizard } from "@/components/gmail/settings/proton-bridge-wizard"
import { useDiscoverMailAccount } from "@/lib/api/hooks/use-mail-account-discover"
import { useTestMailAccount } from "@/lib/api/hooks/use-mail-account-test"
import { useStartMailOAuth } from "@/lib/api/hooks/use-mail-oauth"
import { useMailOAuthProviders } from "@/lib/api/hooks/use-mail-oauth-providers"
import type { CreateMailAccountPayload, MailAccountDiscoverResult } from "@/lib/api/types"
import { manualMailDiscoverResult } from "@/lib/mail-settings/manual-account-discover"

type Step = "email" | "proton" | "credentials"

function displayNameFromEmail(email: string): string {
  const local = email.split("@")[0] ?? email
  return local.replace(/[._-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
}

function usernameForHint(email: string, hint: string): string {
  if (hint === "local") {
    return email.split("@")[0] ?? email
  }
  return email
}

function shouldShowAdvanced(discover: MailAccountDiscoverResult | null): boolean {
  if (!discover) return true
  if (discover.confidence === "low") return true
  if (!discover.imap_host || !discover.smtp_host) return true
  if (discover.provider_id === "tutanota") return true
  return false
}

function oauthProviderForDiscover(
  discover: MailAccountDiscoverResult,
  enabled: string[]
): "google" | "microsoft" | null {
  if (!discover.auth_methods.includes("oauth2")) return null
  const id = discover.provider_id
  if ((id === "gmail" || id === "google_workspace") && enabled.includes("google")) {
    return "google"
  }
  if (
    (id === "outlook" || id === "microsoft365") &&
    enabled.includes("microsoft")
  ) {
    return "microsoft"
  }
  return null
}

export function AddMailAccountForm({
  pending,
  onSubmit,
}: {
  pending: boolean
  onSubmit: (payload: CreateMailAccountPayload) => void
}) {
  const [open, setOpen] = useState(false)
  const [step, setStep] = useState<Step>("email")
  const [showAdvanced, setShowAdvanced] = useState(false)
  const [discover, setDiscover] = useState<MailAccountDiscoverResult | null>(null)
  const [testOk, setTestOk] = useState<boolean | null>(null)
  const discoverMutation = useDiscoverMailAccount()
  const testMutation = useTestMailAccount()
  const oauthStart = useStartMailOAuth()
  const { data: oauthProviders } = useMailOAuthProviders()
  const enabledOAuth = oauthProviders?.providers ?? []

  const [email, setEmail] = useState("")
  const [form, setForm] = useState({
    name: "",
    imap_host: "127.0.0.1",
    imap_port: "1143",
    imap_tls: true,
    smtp_host: "127.0.0.1",
    smtp_port: "1025",
    smtp_tls: true,
    username: "",
    password: "",
  })

  useEffect(() => {
    if (!discover) return
    setForm((prev) => ({
      ...prev,
      imap_host: discover.imap_host || prev.imap_host,
      imap_port: String(discover.imap_port || 993),
      imap_tls: discover.imap_tls,
      smtp_host: discover.smtp_host || prev.smtp_host,
      smtp_port: String(discover.smtp_port || 587),
      smtp_tls: discover.smtp_tls,
      username: prev.username || usernameForHint(discover.email, discover.username_hint),
      name: prev.name || displayNameFromEmail(discover.email),
    }))
    setShowAdvanced(shouldShowAdvanced(discover))
    setTestOk(null)
  }, [discover])

  function resetForm() {
    setStep("email")
    setEmail("")
    setDiscover(null)
    setShowAdvanced(false)
    setTestOk(null)
    setForm({
      name: "",
      imap_host: "127.0.0.1",
      imap_port: "1143",
      imap_tls: true,
      smtp_host: "127.0.0.1",
      smtp_port: "1025",
      smtp_tls: true,
      username: "",
      password: "",
    })
    discoverMutation.reset()
    testMutation.reset()
    oauthStart.reset()
  }

  async function handleEmailContinue() {
    const trimmed = email.trim()
    if (!trimmed) return
    const result = await discoverMutation.mutateAsync(trimmed)
    goToCredentials(result)
  }

  function goToCredentials(result: MailAccountDiscoverResult) {
    setDiscover(result)
    if (result.provider_id === "proton" && result.source !== "manual") {
      setStep("proton")
    } else {
      setStep("credentials")
    }
  }

  function handleManualContinue() {
    const trimmed = email.trim()
    if (!trimmed || !trimmed.includes("@")) return
    goToCredentials(manualMailDiscoverResult(trimmed))
  }

  async function runConnectionTest() {
    const result = await testMutation.mutateAsync({
      imap_host: form.imap_host,
      imap_port: Number(form.imap_port) || 993,
      imap_tls: form.imap_tls,
      smtp_host: form.smtp_host,
      smtp_port: Number(form.smtp_port) || 587,
      smtp_tls: form.smtp_tls,
      username: form.username,
      password: form.password,
    })
    setTestOk(result.ok)
    return result
  }

  async function handleProtonContinue() {
    setForm((prev) => ({
      ...prev,
      imap_host: "127.0.0.1",
      smtp_host: "127.0.0.1",
      username: discover?.email ?? prev.username,
      password: prev.password,
    }))
    const result = await runConnectionTest()
    if (result.ok) {
      setStep("credentials")
    }
  }

  function handleSubmit() {
    if (!discover) return
    onSubmit({
      name: form.name.trim() || displayNameFromEmail(discover.email),
      email: discover.email,
      provider: discover.provider_id,
      imap_host: form.imap_host,
      imap_port: Number(form.imap_port) || 993,
      imap_tls: form.imap_tls,
      smtp_host: form.smtp_host,
      smtp_port: Number(form.smtp_port) || 587,
      smtp_tls: form.smtp_tls,
      username: form.username,
      password: form.password,
    })
    setOpen(false)
    resetForm()
  }

  async function handleOAuth(provider: "google" | "microsoft") {
    if (!discover) return
    const { authorization_url } = await oauthStart.mutateAsync({
      provider,
      email: discover.email,
      name: form.name.trim() || displayNameFromEmail(discover.email),
      provider_id: discover.provider_id,
      imap_host: form.imap_host,
      imap_port: Number(form.imap_port) || 993,
      imap_tls: form.imap_tls,
      smtp_host: form.smtp_host,
      smtp_port: Number(form.smtp_port) || 587,
      smtp_tls: form.smtp_tls,
    })
    window.location.href = authorization_url
  }

  const oauthProvider = discover ? oauthProviderForDiscover(discover, enabledOAuth) : null

  if (!open) {
    return (
      <Button type="button" variant="outline" onClick={() => setOpen(true)}>
        Ajouter un compte mail
      </Button>
    )
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Nouveau compte mail</CardTitle>
        <CardDescription>
          Saisissez votre adresse e-mail : nous détectons le fournisseur et préremplissons IMAP/SMTP.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {step === "email" ? (
          <div className="space-y-3 max-w-md">
            <Field
              label="Adresse e-mail"
              value={email}
              onChange={setEmail}
              type="email"
              autoComplete="email"
              placeholder="vous@exemple.com"
            />
            {discoverMutation.isError ? (
              <p className="text-sm text-destructive">
                Détection impossible. Utilisez « Configurer manuellement » ou réessayez.
              </p>
            ) : null}
            <div className="flex flex-wrap gap-2">
              <Button
                type="button"
                disabled={!email.trim() || discoverMutation.isPending}
                onClick={() => void handleEmailContinue()}
              >
                {discoverMutation.isPending ? (
                  <>
                    <Loader2 className="mr-2 size-4 animate-spin" />
                    Détection…
                  </>
                ) : (
                  "Détecter la configuration"
                )}
              </Button>
              <Button
                type="button"
                variant="secondary"
                disabled={!email.trim() || !email.includes("@")}
                onClick={handleManualContinue}
              >
                Configurer manuellement
              </Button>
              <Button
                type="button"
                variant="ghost"
                onClick={() => {
                  setOpen(false)
                  resetForm()
                }}
              >
                Annuler
              </Button>
            </div>
            <p className="text-xs text-muted-foreground">
              La détection préremplit IMAP/SMTP. Choisissez « Configurer manuellement » pour saisir
              vos paramètres sans appel réseau.
            </p>
          </div>
        ) : null}

        {step === "proton" && discover ? (
          <ProtonBridgeWizard
            email={discover.email}
            imapPort={form.imap_port}
            smtpPort={form.smtp_port}
            bridgePassword={form.password}
            onBridgePasswordChange={(v) => setForm({ ...form, password: v })}
            onImapPortChange={(v) => setForm({ ...form, imap_port: v })}
            onSmtpPortChange={(v) => setForm({ ...form, smtp_port: v })}
            onContinue={() => void handleProtonContinue()}
            onBack={() => setStep("email")}
          />
        ) : null}

        {step === "credentials" && discover ? (
          <>
            <ProviderBanner discover={discover} onBack={() => setStep("email")} />

            {discover.notes?.length ? (
              <ul className="rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground space-y-1">
                {discover.notes.map((note) => (
                  <li key={note}>{note}</li>
                ))}
              </ul>
            ) : null}

            {oauthProvider ? (
              <div className="space-y-2 max-w-md">
                <p className="text-sm text-muted-foreground">
                  Connexion recommandée sans mot de passe :
                </p>
                <Button
                  type="button"
                  variant="secondary"
                  disabled={oauthStart.isPending}
                  onClick={() => void handleOAuth(oauthProvider)}
                >
                  {oauthStart.isPending ? (
                    <Loader2 className="mr-2 size-4 animate-spin" />
                  ) : null}
                  {oauthProvider === "google"
                    ? "Continuer avec Google"
                    : "Continuer avec Microsoft"}
                </Button>
                <p className="text-xs text-muted-foreground">ou identifiant / mot de passe ci-dessous</p>
              </div>
            ) : null}

            <div className="grid gap-3 sm:grid-cols-2 max-w-2xl">
              <Field
                label="Nom affiché"
                value={form.name}
                onChange={(v) => setForm({ ...form, name: v })}
              />
              <Field
                label="Identifiant"
                value={form.username}
                onChange={(v) => setForm({ ...form, username: v })}
                autoComplete="username"
              />
              <Field
                label="Mot de passe"
                type="password"
                value={form.password}
                onChange={(v) => {
                  setTestOk(null)
                  setForm({ ...form, password: v })
                }}
                autoComplete="current-password"
              />
            </div>

            <div>
              <button
                type="button"
                className="flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
                onClick={() => setShowAdvanced((v) => !v)}
              >
                {showAdvanced ? (
                  <ChevronUp className="size-4" />
                ) : (
                  <ChevronDown className="size-4" />
                )}
                Paramètres serveur {showAdvanced ? "" : "(avancé)"}
              </button>
              {showAdvanced ? (
                <div className="mt-3 grid gap-3 sm:grid-cols-2 max-w-2xl">
                  <Field
                    label="IMAP hôte"
                    value={form.imap_host}
                    onChange={(v) => setForm({ ...form, imap_host: v })}
                  />
                  <Field
                    label="IMAP port"
                    value={form.imap_port}
                    onChange={(v) => setForm({ ...form, imap_port: v })}
                  />
                  <Field
                    label="SMTP hôte"
                    value={form.smtp_host}
                    onChange={(v) => setForm({ ...form, smtp_host: v })}
                  />
                  <Field
                    label="SMTP port"
                    value={form.smtp_port}
                    onChange={(v) => setForm({ ...form, smtp_port: v })}
                  />
                  <label className="flex items-center gap-2 text-sm sm:col-span-2">
                    <input
                      type="checkbox"
                      checked={form.imap_tls}
                      onChange={(e) => setForm({ ...form, imap_tls: e.target.checked })}
                    />
                    IMAP TLS
                  </label>
                  <label className="flex items-center gap-2 text-sm sm:col-span-2">
                    <input
                      type="checkbox"
                      checked={form.smtp_tls}
                      onChange={(e) => setForm({ ...form, smtp_tls: e.target.checked })}
                    />
                    SMTP TLS / STARTTLS
                  </label>
                </div>
              ) : (
                <p className="mt-1 text-xs text-muted-foreground">
                  Réception {form.imap_host}:{form.imap_port} · Envoi {form.smtp_host}:{form.smtp_port}
                </p>
              )}
            </div>

            <TestResultBanner
              testing={testMutation.isPending}
              result={testMutation.data}
              testOk={testOk}
              error={testMutation.isError}
            />

            <div className="flex flex-wrap gap-2">
              <Button
                type="button"
                variant="outline"
                disabled={
                  testMutation.isPending ||
                  !form.password ||
                  !form.username ||
                  !form.imap_host ||
                  !form.smtp_host
                }
                onClick={() => void runConnectionTest()}
              >
                {testMutation.isPending ? (
                  <>
                    <Loader2 className="mr-2 size-4 animate-spin" />
                    Test…
                  </>
                ) : (
                  "Tester la connexion"
                )}
              </Button>
              <Button
                type="button"
                disabled={
                  pending ||
                  !form.password ||
                  !form.username ||
                  !form.imap_host ||
                  !form.smtp_host ||
                  testOk === false
                }
                onClick={handleSubmit}
              >
                Enregistrer
              </Button>
              <Button
                type="button"
                variant="ghost"
                onClick={() => {
                  setOpen(false)
                  resetForm()
                }}
              >
                Annuler
              </Button>
            </div>
          </>
        ) : null}
      </CardContent>
    </Card>
  )
}

function TestResultBanner({
  testing,
  result,
  testOk,
  error,
}: {
  testing: boolean
  result?: { ok: boolean; imap_ok: boolean; imap_error?: string; smtp_ok: boolean; smtp_error?: string }
  testOk: boolean | null
  error: boolean
}) {
  if (testing || testOk === null) {
    if (error) {
      return <p className="text-sm text-destructive">Échec du test de connexion.</p>
    }
    return null
  }
  if (testOk && result?.ok) {
    return (
      <p className="text-sm text-green-600 dark:text-green-500">
        Connexion IMAP et SMTP validée.
      </p>
    )
  }
  return (
    <div className="text-sm text-destructive space-y-1">
      <p>Échec du test de connexion.</p>
      {result?.imap_error ? <p className="text-xs">IMAP : {result.imap_error}</p> : null}
      {result?.smtp_error ? <p className="text-xs">SMTP : {result.smtp_error}</p> : null}
    </div>
  )
}

function ProviderBanner({
  discover,
  onBack,
}: {
  discover: MailAccountDiscoverResult
  onBack: () => void
}) {
  return (
    <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border bg-muted/30 px-3 py-2">
      <div className="flex items-center gap-2 min-w-0">
        <Mail className="size-4 shrink-0 text-muted-foreground" />
        <div className="min-w-0">
          <p className="text-sm font-medium truncate">{discover.email}</p>
          <p className="text-xs text-muted-foreground">
            {discover.provider_name}
            {discover.confidence !== "high" ? ` · confiance ${discover.confidence}` : null}
          </p>
        </div>
      </div>
      <Button type="button" variant="ghost" size="sm" onClick={onBack}>
        Modifier l&apos;adresse
      </Button>
    </div>
  )
}

function Field({
  label,
  value,
  onChange,
  type = "text",
  autoComplete,
  placeholder,
}: {
  label: string
  value: string
  onChange: (value: string) => void
  type?: string
  autoComplete?: string
  placeholder?: string
}) {
  return (
    <div className="space-y-1.5">
      <Label className="text-xs">{label}</Label>
      <Input
        value={value}
        type={type}
        autoComplete={autoComplete}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
      />
    </div>
  )
}
