"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { KeyRound, Pencil } from "lucide-react";
import { Button } from "@/components/ui/button";
import { FormField } from "@/components/shared/form-field";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { PageHeader } from "@/components/shared/page-header";
import { PasswordForm } from "@/features/auth/password-form";
import { parseUserProfile, type ProfileUpdateValues, type UserProfile } from "./contract";

function fullName(profile: UserProfile) {
  return [profile.firstName, profile.lastName].filter(Boolean).join(" ") || "User";
}

function initials(profile: UserProfile) {
  const value = `${profile.firstName.slice(0, 1)}${profile.lastName.slice(0, 1)}`.toUpperCase();
  return value || "U";
}

function display(value: string) {
  return value || "—";
}

function formatDate(value: string) {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "—";
  return new Intl.DateTimeFormat("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    timeZone: "UTC",
  }).format(date);
}

function DetailField({ label, value }: { label: string; value: string }) {
  return (
    <div className="min-w-0">
      <dt className="text-sm text-muted-foreground">{label}</dt>
      <dd className="mt-1 break-words text-sm font-medium">{display(value)}</dd>
    </div>
  );
}

export function ProfileSettings({ profile: initialProfile, roleLabel, tenantCode, loadError }: {
  profile: UserProfile | null;
  roleLabel?: string;
  tenantCode?: string;
  loadError?: string;
}) {
  const router = useRouter();
  const [profile, setProfile] = useState(initialProfile);
  const [draft, setDraft] = useState<ProfileUpdateValues | null>(null);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");
  const [notice, setNotice] = useState("");

  function openEditor() {
    if (!profile) return;
    setError("");
    setNotice("");
    setDraft({
      firstName: profile.firstName,
      lastName: profile.lastName,
      email: profile.email,
      phone: profile.phone,
      address: { ...profile.address },
      basicInformation: {
        dateOfBirth: profile.basicInformation.dateOfBirth.slice(0, 10),
        placeOfBirth: profile.basicInformation.placeOfBirth,
        gender: profile.basicInformation.gender,
      },
    });
  }

  function updateDraft<K extends keyof ProfileUpdateValues>(key: K, value: ProfileUpdateValues[K]) {
    setDraft((current) => current ? { ...current, [key]: value } : current);
  }

  function updateAddress(key: keyof ProfileUpdateValues["address"], value: string) {
    setDraft((current) => current ? { ...current, address: { ...current.address, [key]: value } } : current);
  }

  function updateBasicInformation(key: keyof ProfileUpdateValues["basicInformation"], value: string) {
    setDraft((current) => current
      ? { ...current, basicInformation: { ...current.basicInformation, [key]: value } }
      : current);
  }

  async function saveProfile(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!draft || saving) return;
    setSaving(true);
    setError("");
    setNotice("");
    try {
      const response = await fetch("/api/profile", {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(draft),
        cache: "no-store",
        credentials: "same-origin",
      });
      const payload: unknown = await response.json().catch(() => null);
      const body = typeof payload === "object" && payload !== null ? payload as Record<string, unknown> : null;
      const nextProfile = parseUserProfile({ ok: true, result: body?.profile });
      if (!response.ok || !nextProfile) {
        throw new Error(typeof body?.error === "string" ? body.error : "Unable to save your profile. Please try again.");
      }
      setProfile(nextProfile);
      setDraft(null);
      setNotice("Profile updated successfully.");
      router.refresh();
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "Unable to save your profile. Please try again.");
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="space-y-6">
      <PageHeader title="Profile Settings" currentPage="Profile Settings" />
      {loadError && (
        <p role="alert" className="rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive">
          {loadError}
        </p>
      )}
      {notice && <p role="status" className="rounded-lg border border-success/25 bg-success/5 p-4 text-sm">{notice}</p>}

      {profile && (
        <>
          <section className="panel p-5 sm:p-6">
            <div className="flex flex-wrap items-center justify-between gap-4">
              <div className="flex min-w-0 items-center gap-4 sm:gap-5">
                <span className="inline-flex size-16 shrink-0 items-center justify-center rounded-full border border-border bg-muted text-lg font-semibold text-foreground">
                  {initials(profile)}
                </span>
                <div className="min-w-0">
                  <h2 className="break-words text-xl font-semibold">{fullName(profile)}</h2>
                  <div className="mt-2 flex flex-wrap items-center gap-2">
                    <span className="rounded-full border border-border px-2.5 py-1 text-xs font-medium">
                      {roleLabel || profile.roles[0] || "—"}
                    </span>
                    <span className={`rounded-full border px-2.5 py-1 text-xs font-medium ${profile.active ? "border-success/30 text-success" : "border-border text-muted-foreground"}`}>
                      {profile.active ? "Active" : "Inactive"}
                    </span>
                    {(profile.organizationCode || tenantCode) && (
                      <span className="rounded-full border border-border px-2.5 py-1 text-xs font-medium text-muted-foreground">
                        {profile.organizationCode || tenantCode}
                      </span>
                    )}
                  </div>
                </div>
              </div>
              <Button type="button" variant="outline" onClick={openEditor}>
                <Pencil aria-hidden="true" /> Edit profile
              </Button>
            </div>
          </section>

          <section className="panel space-y-5 p-5 sm:p-6">
            <div>
              <h3 className="text-lg font-semibold">Profile</h3>
              <p className="mt-1 text-sm text-muted-foreground">Personal and address information for {fullName(profile)}.</p>
            </div>
            <div className="grid min-w-0 gap-4 xl:grid-cols-2">
              <section className="rounded-xl border border-border bg-background p-5 sm:p-6">
                <h4 className="mb-5 text-base font-semibold">Personal Information</h4>
                <dl className="grid gap-x-6 gap-y-5 sm:grid-cols-2">
                  <DetailField label="First name" value={profile.firstName} />
                  <DetailField label="Last name" value={profile.lastName} />
                  <DetailField label="Email address" value={profile.email} />
                  <DetailField label="Phone" value={profile.phone} />
                  <DetailField label="Date of birth" value={formatDate(profile.basicInformation.dateOfBirth)} />
                  <DetailField label="Place of birth" value={profile.basicInformation.placeOfBirth} />
                  <DetailField label="Gender" value={profile.basicInformation.gender} />
                </dl>
              </section>
              <section className="rounded-xl border border-border bg-background p-5 sm:p-6">
                <h4 className="mb-5 text-base font-semibold">Address Information</h4>
                <dl className="grid gap-x-6 gap-y-5 sm:grid-cols-2">
                  <div className="sm:col-span-2"><DetailField label="Street address" value={profile.address.streetAndNumber} /></div>
                  <DetailField label="City" value={profile.address.city} />
                  <DetailField label="State / province" value={profile.address.state} />
                  <DetailField label="Country" value={profile.address.country} />
                  <DetailField label="Postal code" value={profile.address.postalCode} />
                </dl>
              </section>
            </div>
          </section>

          <section className="panel p-5 sm:p-6">
            <div className="mb-5 flex items-start gap-3">
              <KeyRound className="mt-1 size-5 text-muted-foreground" aria-hidden="true" />
              <div>
                <h2 className="font-semibold">Change Password</h2>
                <p className="mt-1 text-sm text-muted-foreground">Enter your current password and choose a new one.</p>
              </div>
            </div>
            <PasswordForm mode="change" onComplete={() => setNotice("Password changed successfully.")} />
          </section>

          <Dialog open={!!draft} onOpenChange={(open) => { if (!open && !saving) setDraft(null); }}>
            <DialogContent className="flex max-h-[92dvh] flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl">
              <DialogHeader className="shrink-0 border-b px-6 py-5 pr-14">
                <DialogTitle>Edit profile</DialogTitle>
                <DialogDescription>Update your personal and address information.</DialogDescription>
              </DialogHeader>
              {draft && (
                <form onSubmit={saveProfile} className="flex min-h-0 flex-1 flex-col">
                  <div className="min-h-0 flex-1 space-y-6 overflow-y-auto px-6 py-5">
                    {error && <p role="alert" className="rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive">{error}</p>}
                    <fieldset disabled={saving} className="space-y-6 disabled:opacity-70">
                      <section className="space-y-4">
                        <h3 className="font-medium">Personal information</h3>
                        <div className="grid gap-4 sm:grid-cols-2">
                          <FormField name="firstName" label="First name" autoComplete="given-name" value={draft.firstName} onChange={(event) => updateDraft("firstName", event.target.value)} maxLength={100} required />
                          <FormField name="lastName" label="Last name" autoComplete="family-name" value={draft.lastName} onChange={(event) => updateDraft("lastName", event.target.value)} maxLength={100} required />
                          <FormField name="email" label="Email address" type="email" autoComplete="email" value={draft.email} onChange={(event) => updateDraft("email", event.target.value)} maxLength={254} required />
                          <FormField name="phone" label="Phone" type="tel" autoComplete="tel" value={draft.phone} onChange={(event) => updateDraft("phone", event.target.value)} maxLength={40} />
                          <FormField name="dateOfBirth" label="Date of birth" type="date" value={draft.basicInformation.dateOfBirth} onChange={(event) => updateBasicInformation("dateOfBirth", event.target.value)} />
                          <FormField name="placeOfBirth" label="Place of birth" value={draft.basicInformation.placeOfBirth} onChange={(event) => updateBasicInformation("placeOfBirth", event.target.value)} maxLength={256} />
                          <FormField name="gender" label="Gender" value={draft.basicInformation.gender} onChange={(event) => updateBasicInformation("gender", event.target.value)} maxLength={50} />
                        </div>
                      </section>
                      <section className="space-y-4">
                        <h3 className="font-medium">Address information</h3>
                        <div className="grid gap-4 sm:grid-cols-2">
                          <FormField className="sm:col-span-2" name="streetAndNumber" label="Street address" autoComplete="street-address" value={draft.address.streetAndNumber} onChange={(event) => updateAddress("streetAndNumber", event.target.value)} maxLength={256} />
                          <FormField name="city" label="City" autoComplete="address-level2" value={draft.address.city} onChange={(event) => updateAddress("city", event.target.value)} maxLength={256} />
                          <FormField name="state" label="State / province" autoComplete="address-level1" value={draft.address.state} onChange={(event) => updateAddress("state", event.target.value)} maxLength={256} />
                          <FormField name="country" label="Country" autoComplete="country-name" value={draft.address.country} onChange={(event) => updateAddress("country", event.target.value)} maxLength={256} />
                          <FormField name="postalCode" label="Postal code" autoComplete="postal-code" value={draft.address.postalCode} onChange={(event) => updateAddress("postalCode", event.target.value)} maxLength={32} />
                        </div>
                      </section>
                    </fieldset>
                  </div>
                  <DialogFooter className="mx-0 mb-0 shrink-0 rounded-b-xl border-t px-6 py-4">
                    <Button type="button" variant="outline" disabled={saving} onClick={() => setDraft(null)}>Cancel</Button>
                    <Button type="submit" disabled={saving}>{saving ? "Saving…" : "Save changes"}</Button>
                  </DialogFooter>
                </form>
              )}
            </DialogContent>
          </Dialog>
        </>
      )}
    </div>
  );
}
