"use client";

import { useEffect, useState } from "react";
import { KeyRound, Mail, MailCheck, PencilLine, UserRound } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { FieldGroup } from "@/components/ui/field";
import { Spinner } from "@/components/ui/spinner";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { FormErrorAlert, TextField } from "@/components/app/form-fields";
import { SectionCard } from "@/components/app/page";
import { useAuth } from "../auth/auth-context";
import { IconField, PasswordField } from "../auth/auth-ui";
import { useChangeEmailForm, useEmailVerification } from "../auth/useAccountRecovery";
import { humanize } from "../lib/format";
import { roleLabel } from "../team/useTeam";
import { ReadOnlyField, SettingsLayout, UnsavedHint } from "./settings-layout";
import { usePasswordForm, useProfileForm } from "./useSettings";

// Kept for screens that import the settings frame from here.
export { SettingsFrame, SettingsLayout, SettingsShell } from "./settings-layout";

function ChangeEmailDialog({ open, onOpenChange, currentEmail, verified }) {
  const { form, submit } = useChangeEmailForm(() => onOpenChange(false));
  const { isSubmitting } = form.formState;

  // Start clean each time the dialog opens.
  useEffect(() => {
    if (open) form.reset();
  }, [form, open]);

  return <Dialog open={open} onOpenChange={(next) => !isSubmitting && onOpenChange(next)}>
    <DialogContent className="sm:max-w-md">
      <form onSubmit={submit} noValidate className="grid gap-5">
        <DialogHeader>
          <DialogTitle>Change sign-in email</DialogTitle>
          <DialogDescription>{verified
            ? `We send a link to the new address. You keep signing in with ${currentEmail} until you open it.`
            : "Your current address is not verified yet, so the new address replaces it right away and gets a fresh link."}</DialogDescription>
        </DialogHeader>
        <FormErrorAlert form={form} />
        <FieldGroup className="gap-4">
          <IconField control={form.control} name="email" id="change-email" label="New work email" icon={Mail} type="email" autoComplete="email" placeholder="name@company.com" inputProps={{ inputMode: "email", autoCapitalize: "none", spellCheck: false }} />
          <PasswordField control={form.control} name="current_password" id="change-email-password" label="Current password" description="Confirms it is you making this change." />
        </FieldGroup>
        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>Cancel</Button>
          <Button type="submit" disabled={isSubmitting}>{isSubmitting && <Spinner />} Send verification link</Button>
        </DialogFooter>
      </form>
    </DialogContent>
  </Dialog>;
}

// Sign-in email with its verification state; a new address only takes over once it is verified.
function EmailSection() {
  const { user } = useAuth();
  const { resend, cancelChange, cooldown, isResending, isCancelling } = useEmailVerification();
  const [open, setOpen] = useState(false);
  const verified = user?.emailVerified !== false;
  const supportSession = Boolean(user?.impersonation);

  const changeButton = <Button variant="outline" size="sm" onClick={() => setOpen(true)} disabled={supportSession}><PencilLine /> Change email</Button>;

  return <SectionCard id="email" title="Sign-in email" icon={MailCheck} description="The address you sign in with, and where password resets and security notices go."
    actions={supportSession ? <Tooltip><TooltipTrigger asChild><span tabIndex={0}>{changeButton}</span></TooltipTrigger><TooltipContent>Platform support sessions cannot change the email.</TooltipContent></Tooltip> : changeButton}>
    <div className="grid gap-4">
      <div className="flex flex-wrap items-center gap-x-3 gap-y-2">
        <span className="[overflow-wrap:anywhere] text-sm font-medium">{user?.email}</span>
        {verified
          ? <Badge variant="secondary" className="bg-success/10 text-success">Verified</Badge>
          : <Badge variant="secondary" className="bg-warning/10 text-warning">Not verified</Badge>}
      </div>

      {!verified && <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-muted/40 p-3">
        <p className="min-w-0 flex-1 basis-64 text-sm text-muted-foreground">Open the link we emailed you. Until then you cannot invite teammates, connect mailboxes, send email or open portal access.</p>
        <Button variant="outline" size="sm" onClick={resend} disabled={cooldown > 0 || isResending}>{isResending && <Spinner />} {cooldown > 0 ? `Resend in ${cooldown}s` : "Resend link"}</Button>
      </div>}

      {user?.pendingEmail && <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-muted/40 p-3">
        <p className="min-w-0 flex-1 basis-64 text-sm text-muted-foreground">Waiting for you to open the link sent to <span className="[overflow-wrap:anywhere] font-medium text-foreground">{user.pendingEmail}</span>. Your sign-in email changes when you do.</p>
        <div className="flex flex-wrap gap-2">
          <Button variant="outline" size="sm" onClick={resend} disabled={cooldown > 0 || isResending}>{isResending && <Spinner />} {cooldown > 0 ? `Resend in ${cooldown}s` : "Resend link"}</Button>
          <Button variant="ghost" size="sm" onClick={cancelChange} disabled={isCancelling}>{isCancelling && <Spinner />} Cancel change</Button>
        </div>
      </div>}
    </div>
    <ChangeEmailDialog open={open} onOpenChange={setOpen} currentEmail={user?.email} verified={verified} />
  </SectionCard>;
}

export function ProfileSettingsPage() {
  const { user, roles } = useAuth();
  const profile = useProfileForm();
  const password = usePasswordForm();
  const profileState = profile.form.formState;
  const passwordState = password.form.formState;

  // Deep links: /settings#password ("Set your own password" on the role checklist) and /settings#email.
  useEffect(() => {
    const target = window.location.hash.slice(1);
    if (!["password", "email"].includes(target)) return;
    window.requestAnimationFrame(() => {
      document.getElementById(target)?.scrollIntoView({ behavior: "smooth", block: "start" });
      if (target === "password") document.getElementById("profile-current-password")?.focus({ preventScroll: true });
    });
  }, []);

  return <SettingsLayout title="My profile" description="How you appear to your team, and how you sign in.">
    <form onSubmit={profile.submit} noValidate>
      <SectionCard title="Profile" icon={UserRound} description="Your name shows on records you create, assignments, and activity history.">
        <div className="grid gap-5">
          <FormErrorAlert form={profile.form} />
          <FieldGroup className="grid gap-5 sm:grid-cols-2">
            <TextField control={profile.form.control} name="name" label="Full name" inputProps={{ autoComplete: "name" }} />
            <ReadOnlyField id="profile-role" label="Role" value={(roles || []).map((role) => roleLabel(role)).join(", ") || "No role"} description="Roles decide which modules and actions you can use." />
            <ReadOnlyField id="profile-department" label="Department" value={humanize(user?.department)} />
          </FieldGroup>
          <div className="flex flex-wrap items-center justify-end gap-3 border-t pt-4">
            <UnsavedHint show={profileState.isDirty} />
            <Button type="submit" disabled={profileState.isSubmitting || !profileState.isDirty}>{profileState.isSubmitting && <Spinner />} Save profile</Button>
          </div>
        </div>
      </SectionCard>
    </form>

    <EmailSection />

    <form onSubmit={password.submit} noValidate>
      <SectionCard id="password" title="Password" icon={KeyRound} description="Changing it signs you out on your other devices. You stay signed in here.">
        <div className="grid gap-5">
          <FormErrorAlert form={password.form} />
          <FieldGroup className="grid items-start gap-5 lg:grid-cols-2">
            <PasswordField control={password.form.control} name="current_password" id="profile-current-password" label="Current password" className="lg:col-span-2 lg:max-w-[calc(50%-0.625rem)]" />
            <PasswordField control={password.form.control} name="password" id="profile-new-password" label="New password" autoComplete="new-password" rules />
            <PasswordField control={password.form.control} name="password_confirmation" id="profile-new-password-confirmation" label="Repeat new password" autoComplete="new-password" />
          </FieldGroup>
          <div className="flex justify-end border-t pt-4">
            <Button type="submit" disabled={passwordState.isSubmitting}>{passwordState.isSubmitting && <Spinner />} Update password</Button>
          </div>
        </div>
      </SectionCard>
    </form>
  </SettingsLayout>;
}
