"use client";

import { ChevronDown, KeyRound, Loader2, LogOut } from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import { putPlayerPassword } from "@/api/player-auth";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { validatePlayerLoginPassword } from "@/lib/player-input-validation";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import { LotteryApiBizError } from "@/types/api/errors";

type AccountView = "profile" | "password";

function ProfileRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="grid grid-cols-[7.5rem_minmax(0,1fr)] items-start gap-3 py-2.5 text-sm">
      <dt className="text-muted-foreground">{label}</dt>
      <dd className="min-w-0 break-words text-right font-medium text-foreground">{value}</dd>
    </div>
  );
}

function accountInitial(value: string): string {
  const trimmed = value.trim();
  return trimmed === "" ? "P" : trimmed.slice(0, 1).toUpperCase();
}

export function PlayerAccountDialog() {
  const { t } = useTranslation("player");
  const router = useRouter();
  const profile = usePlayerSessionStore((state) => state.profile);
  const clearBearerToken = usePlayerSessionStore((state) => state.clearBearerToken);
  const [open, setOpen] = useState(false);
  const [view, setView] = useState<AccountView>("profile");
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [saving, setSaving] = useState(false);

  const displayName =
    profile?.nickname?.trim() ||
    profile?.username?.trim() ||
    (profile?.id != null ? t("player.fallback", { id: profile.id }) : t("account.loading"));
  const isNative = profile?.auth_source === "lottery_native";

  function resetPasswordForm() {
    setCurrentPassword("");
    setNewPassword("");
    setConfirmPassword("");
  }

  function handleOpenChange(nextOpen: boolean) {
    setOpen(nextOpen);
    if (!nextOpen) {
      setView("profile");
      resetPasswordForm();
    }
  }

  function handleLogout() {
    handleOpenChange(false);
    clearBearerToken();
    router.replace("/login");
  }

  async function handlePasswordSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    if (currentPassword === "" || newPassword === "" || confirmPassword === "") {
      toast.error(t("account.password.required"));
      return;
    }
    if (validatePlayerLoginPassword(newPassword) === "too_short") {
      toast.error(t("account.password.tooShort"));
      return;
    }
    if (newPassword !== confirmPassword) {
      toast.error(t("account.password.mismatch"));
      return;
    }
    if (newPassword === currentPassword) {
      toast.error(t("account.password.mustDiffer"));
      return;
    }

    setSaving(true);
    try {
      await putPlayerPassword({
        current_password: currentPassword,
        password: newPassword,
        password_confirmation: confirmPassword,
      });
      handleOpenChange(false);
      clearBearerToken();
      router.replace("/login?password=changed");
    } catch (error) {
      toast.error(
        error instanceof LotteryApiBizError ? error.message : t("account.password.failed"),
      );
    } finally {
      setSaving(false);
    }
  }

  return (
    <>
      <Button
        type="button"
        variant="outline"
        size="sm"
        disabled={profile === null}
        aria-label={t("account.open")}
        onClick={() => setOpen(true)}
        className="max-w-[8.5rem] justify-start rounded-full bg-muted/40 px-1.5 sm:max-w-[11rem]"
      >
        <Avatar size="sm">
          <AvatarFallback>{accountInitial(displayName)}</AvatarFallback>
        </Avatar>
        <span className="min-w-0 flex-1 truncate text-left">{displayName}</span>
        <ChevronDown data-icon="inline-end" className="hidden sm:block" />
      </Button>

      <Dialog open={open} onOpenChange={handleOpenChange}>
        <DialogContent className="sm:max-w-md">
          {view === "profile" ? (
            <>
              <DialogHeader>
                <DialogTitle>{t("account.title")}</DialogTitle>
                <DialogDescription>{t("account.description")}</DialogDescription>
              </DialogHeader>

              <Card>
                <CardHeader>
                  <div className="flex items-center gap-3">
                    <Avatar size="lg">
                      <AvatarFallback>{accountInitial(displayName)}</AvatarFallback>
                    </Avatar>
                    <div className="min-w-0 flex-1">
                      <CardTitle className="truncate">{displayName}</CardTitle>
                      <CardDescription className="truncate">
                        {profile?.username || profile?.site_player_id || "—"}
                      </CardDescription>
                    </div>
                  </div>
                  <div className="flex flex-wrap gap-2 pt-1">
                    <Badge variant="secondary">
                      {isNative ? t("account.auth.native") : t("account.auth.sso")}
                    </Badge>
                    <Badge variant="outline">
                      {profile?.funding_mode === "credit"
                        ? t("account.funding.credit")
                        : t("account.funding.wallet")}
                    </Badge>
                  </div>
                </CardHeader>
                <CardContent>
                  <dl>
                    <ProfileRow label={t("account.fields.username")} value={profile?.username || "—"} />
                    <Separator />
                    <ProfileRow label={t("account.fields.site")} value={profile?.site_code || "—"} />
                    <Separator />
                    <ProfileRow
                      label={t("account.fields.playerId")}
                      value={profile?.site_player_id || "—"}
                    />
                    <Separator />
                    <ProfileRow
                      label={t("account.fields.currency")}
                      value={profile?.default_currency || "—"}
                    />
                  </dl>
                </CardContent>
              </Card>

              {!isNative ? (
                <p className="text-sm leading-relaxed text-muted-foreground">
                  {t("account.ssoManaged")}
                </p>
              ) : null}

              {isNative ? (
                <DialogFooter>
                  <Button type="button" variant="destructive" onClick={handleLogout}>
                    <LogOut data-icon="inline-start" />
                    {t("account.logout")}
                  </Button>
                  <Button type="button" variant="outline" onClick={() => setView("password")}>
                    <KeyRound data-icon="inline-start" />
                    {t("account.password.action")}
                  </Button>
                </DialogFooter>
              ) : null}
            </>
          ) : (
            <form onSubmit={handlePasswordSubmit}>
              <div className="flex flex-col gap-4">
                <DialogHeader>
                  <DialogTitle>{t("account.password.title")}</DialogTitle>
                  <DialogDescription>{t("account.password.description")}</DialogDescription>
                </DialogHeader>
                <FieldGroup>
                  <Field>
                    <FieldLabel htmlFor="player-current-password">
                      {t("account.password.current")}
                    </FieldLabel>
                    <Input
                      id="player-current-password"
                      type="password"
                      autoComplete="current-password"
                      value={currentPassword}
                      onChange={(event) => setCurrentPassword(event.target.value)}
                    />
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="player-new-password">
                      {t("account.password.new")}
                    </FieldLabel>
                    <Input
                      id="player-new-password"
                      type="password"
                      autoComplete="new-password"
                      value={newPassword}
                      onChange={(event) => setNewPassword(event.target.value)}
                    />
                    <FieldDescription>{t("account.password.hint")}</FieldDescription>
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="player-confirm-password">
                      {t("account.password.confirm")}
                    </FieldLabel>
                    <Input
                      id="player-confirm-password"
                      type="password"
                      autoComplete="new-password"
                      value={confirmPassword}
                      onChange={(event) => setConfirmPassword(event.target.value)}
                    />
                  </Field>
                </FieldGroup>
                <DialogFooter>
                  <Button type="submit" disabled={saving}>
                    {saving ? <Loader2 data-icon="inline-start" className="animate-spin" /> : null}
                    {saving ? t("account.password.saving") : t("account.password.submit")}
                  </Button>
                  <Button type="button" variant="outline" disabled={saving} onClick={() => setView("profile")}>
                    {t("actions.cancel")}
                  </Button>
                </DialogFooter>
              </div>
            </form>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
