'use client';

import { PasswordInput } from './PasswordInput';

import * as ActionIcons from './Icons';

import Link from 'next/link';
import { useActionState } from 'react';
import {
  acceptInvite,
  changePassword,
  enableMfa,
  forgotPassword,
  regenerateRecoveryCodes,
  resetPassword,
  uploadClaimDocument,
  verifyClaim,
  verifyEmail,
  type CodesState,
  type FormState,
} from '@/app/actions';
import { AlertIcon, ArrowRightIcon, CheckCircleIcon, Spinner } from './Icons';

const codeField = 'field num w-40 text-center text-base tracking-[0.4em]';

function ErrorNote({ message }: { message?: string }) {
  if (!message) return null;
  return (
    <p role="alert" className="flex items-start gap-2 rounded-lg border border-danger/30 bg-danger-soft px-3 py-2.5 text-sm text-danger">
      <AlertIcon className="mt-0.5 h-4 w-4 shrink-0" />
      {message}
    </p>
  );
}

function DoneNote({ children }: { children: React.ReactNode }) {
  return (
    <p role="status" className="flex items-start gap-2 rounded-lg bg-ledger-soft px-3 py-2.5 text-sm text-ledger">
      <CheckCircleIcon className="mt-0.5 h-4 w-4 shrink-0" />
      <span>{children}</span>
    </p>
  );
}

function Submit({ pending, children, pendingLabel, wide }: { pending: boolean; children: React.ReactNode; pendingLabel: string; wide?: boolean }) {
  return (
    <button disabled={pending} className={`btn btn-primary ${wide ? 'w-full !min-h-11' : 'btn-sm'}`}>
      {pending ? (
        <>
          <Spinner className="h-3.5 w-3.5" /> {pendingLabel}
        </>
      ) : (
        children
      )}
    </button>
  );
}

function NewPasswordFields({ autoFocus }: { autoFocus?: boolean }) {
  return (
    <>
      <label className="block">
        <span className="field-label"><ActionIcons.KeyIcon />New password</span>
        <PasswordInput name="password"  required minLength={10} maxLength={200} autoComplete="new-password" autoFocus={autoFocus} className="field" />
        <span className="mt-1 block text-xs text-muted">At least 10 characters. A short sentence is easy to remember and hard to guess.</span>
      </label>
      <label className="block">
        <span className="field-label"><ActionIcons.KeyIcon />Repeat new password</span>
        <PasswordInput name="confirmPassword"  required minLength={10} maxLength={200} autoComplete="new-password" className="field" />
      </label>
    </>
  );
}

/** Recovery codes are shown exactly once, straight from the action result */
export function RecoveryCodeList({ codes }: { codes: string[] }) {
  return (
    <div className="space-y-3 rounded-lg border border-brass/40 bg-brass-soft/40 p-4">
      <p className="text-sm font-semibold text-ink">Save these recovery codes now — they won’t be shown again.</p>
      <p className="text-xs text-ink-2">Each code works once, if you lose your authenticator. Store them in a password manager or print them.</p>
      <ul className="num grid grid-cols-2 gap-2 font-mono text-sm sm:grid-cols-5">
        {codes.map((c) => (
          <li key={c} className="select-all rounded bg-surface px-2 py-1 text-center">
            {c}
          </li>
        ))}
      </ul>
      <button type="button" className="btn btn-quiet btn-xs" onClick={() => navigator.clipboard?.writeText(codes.join('\n'))}>
        <ActionIcons.CopyIcon />Copy all
      </button>
    </div>
  );
}

// ─────────────────────────── Signed-in forms

export function ChangePasswordForm({ requireCode, back, currentPasswordOptional = false }: { requireCode: boolean; back?: string; currentPasswordOptional?: boolean }) {
  const [state, action, pending] = useActionState<FormState, FormData>(changePassword, {});
  return (
    <form action={action} className="grid max-w-md gap-4 text-sm">
      {back && <input type="hidden" name="back" value={back} />}
      <label className="block">
        <span className="field-label"><ActionIcons.KeyIcon />Current password{currentPasswordOptional ? ' (optional)' : ''}</span>
        <PasswordInput name="currentPassword"  required={!currentPasswordOptional} autoComplete="current-password" className="field" />
      </label>
      <label className="block">
        <span className="field-label"><ActionIcons.KeyIcon />New password</span>
        <PasswordInput name="newPassword"  required minLength={10} maxLength={200} autoComplete="new-password" className="field" />
        <span className="mt-1 block text-xs text-muted">At least 10 characters. Other devices are signed out when you change it.</span>
      </label>
      <label className="block">
        <span className="field-label"><ActionIcons.KeyIcon />Repeat new password</span>
        <PasswordInput name="confirmPassword"  required minLength={10} maxLength={200} autoComplete="new-password" className="field" />
      </label>
      {requireCode && (
        <label className="block">
          <span className="field-label"><ActionIcons.ShieldCheckIcon />Authenticator code</span>
          <input name="code" inputMode="numeric" pattern="\d{6}" maxLength={6} required autoComplete="one-time-code" placeholder="000000" className={codeField} />
        </label>
      )}
      <ErrorNote message={state.error} />
      {state.done && <DoneNote>{state.message}</DoneNote>}
      <div>
        <Submit pending={pending} pendingLabel="Saving…">
          <ActionIcons.KeyIcon />Change password
        </Submit>
      </div>
    </form>
  );
}

export function MfaEnableForm() {
  const [state, action, pending] = useActionState<CodesState, FormData>(enableMfa, {});
  if (state.codes)
    return (
      <div className="space-y-3">
        <DoneNote>Two-factor authentication is on.</DoneNote>
        <RecoveryCodeList codes={state.codes} />
        <Link href="?" className="btn btn-primary btn-sm">
          <ActionIcons.CheckCircleIcon />I’ve saved my codes
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-3">
      <div className="flex flex-wrap items-end gap-2">
        <label className="block">
          <span className="field-label"><ActionIcons.ShieldCheckIcon />Code from the app</span>
          <input name="code" inputMode="numeric" pattern="\d{6}" maxLength={6} required autoComplete="one-time-code" autoFocus placeholder="000000" className={codeField} />
        </label>
        <Submit pending={pending} pendingLabel="Checking…">
          <ActionIcons.ShieldCheckIcon />Turn on
        </Submit>
      </div>
      <ErrorNote message={state.error} />
    </form>
  );
}

export function RecoveryCodesForm({ remaining }: { remaining: number }) {
  const [state, action, pending] = useActionState<CodesState, FormData>(regenerateRecoveryCodes, {});
  if (state.codes) return <RecoveryCodeList codes={state.codes} />;
  return (
    <form action={action} className="space-y-3 text-sm">
      <p className={remaining <= 2 ? 'font-medium text-brass' : 'text-ink-2'}>
        {remaining} unused recovery {remaining === 1 ? 'code' : 'codes'} left. Generating new codes cancels the old ones.
      </p>
      <div className="flex flex-wrap items-end gap-2">
        <label className="block">
          <span className="field-label"><ActionIcons.ShieldCheckIcon />Authenticator code</span>
          <input name="code" inputMode="numeric" pattern="\d{6}" maxLength={6} required autoComplete="one-time-code" placeholder="000000" className={codeField} />
        </label>
        <Submit pending={pending} pendingLabel="Generating…">
          <ActionIcons.RefreshIcon />Generate new codes
        </Submit>
      </div>
      <ErrorNote message={state.error} />
    </form>
  );
}

// ─────────────────────────── Public forms (signed out)

export function ForgotPasswordForm() {
  const [state, action, pending] = useActionState<FormState, FormData>(forgotPassword, {});
  if (state.done)
    return (
      <div className="space-y-4">
        <DoneNote>{state.message}</DoneNote>
        <p className="text-sm text-muted">The link expires soon and works once. Check your spam folder if nothing arrives within a few minutes.</p>
        <Link href="/login" className="btn btn-quiet w-full">
          <ActionIcons.ArrowLeftIcon />Back to sign in
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <label className="block">
        <span className="field-label"><ActionIcons.MailIcon />Email</span>
        <input name="email" type="email" required autoFocus autoComplete="username" placeholder="you@firm.com" className="field" />
      </label>
      <ErrorNote message={state.error} />
      <Submit pending={pending} pendingLabel="Sending…" wide>
        Email me a reset link <ArrowRightIcon className="h-4 w-4" />
      </Submit>
    </form>
  );
}

export function ResetPasswordForm({ token, otpRequired = false }: { token: string; otpRequired?: boolean }) {
  const [state, action, pending] = useActionState<FormState, FormData>(resetPassword, {});
  if (state.done)
    return (
      <div className="space-y-4">
        <DoneNote>Your password has been changed and every device was signed out.</DoneNote>
        <Link href="/login" className="btn btn-primary w-full">
          <ActionIcons.LogOutIcon />Sign in with your new password
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <input type="hidden" name="token" value={token} />
      {otpRequired && <label className="block"><span className="field-label"><ActionIcons.BadgeCheckIcon />Email verification OTP</span><input name="otp" required inputMode="numeric" pattern="[0-9]{6}" maxLength={6} autoComplete="one-time-code" className="field" placeholder="Six-digit code from your email" /></label>}

      <NewPasswordFields autoFocus />
      <ErrorNote message={state.error} />
      <Submit pending={pending} pendingLabel="Saving…" wide>
        <ActionIcons.KeyIcon />Set new password
      </Submit>
    </form>
  );
}

export function AcceptInviteForm({ token, name }: { token: string; name: string | null }) {
  const [state, action, pending] = useActionState<FormState, FormData>(acceptInvite, {});
  if (state.done)
    return (
      <div className="space-y-4">
        <DoneNote>Your account is active.</DoneNote>
        <Link href="/login" className="btn btn-primary w-full">
          <ActionIcons.LogOutIcon />Sign in
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <input type="hidden" name="token" value={token} />
      <label className="block">
        <span className="field-label"><ActionIcons.UserIcon />Your name</span>
        <input name="name" required minLength={2} maxLength={150} defaultValue={name ?? ''} autoComplete="name" className="field" />
      </label>
      <NewPasswordFields />
      <ErrorNote message={state.error} />
      <Submit pending={pending} pendingLabel="Activating…" wide>
        <ActionIcons.CheckCircleIcon />Activate account
      </Submit>
    </form>
  );
}

export function ClaimConfirmForm({ token }: { token: string }) {
  const [state, action, pending] = useActionState<FormState, FormData>(verifyClaim, {});
  return (
    <form action={action} className="space-y-3">
      <input type="hidden" name="token" value={token} />
      <ErrorNote message={state.error} />
      <Submit pending={pending} pendingLabel="Confirming…" wide>
        <ActionIcons.MailIcon />Confirm my email and send the claim
      </Submit>
    </form>
  );
}

export function ClaimUploadForm({ token }: { token: string }) {
  const [state, action, pending] = useActionState<FormState, FormData>(uploadClaimDocument, {});
  return (
    <form action={action} className="space-y-3" encType="multipart/form-data">
      <input type="hidden" name="token" value={token} />
      <label className="block">
        <span className="field-label"><ActionIcons.UploadIcon />Proof of identity (PDF, JPG or PNG, up to 10 MB)</span>
        <input name="file" type="file" required accept="application/pdf,image/jpeg,image/png" className="field" />
        <span className="mt-1 block text-xs text-muted">For example your bar card, licence certificate or a letter on firm letterhead. Only our verification team can see it.</span>
      </label>
      <ErrorNote message={state.error} />
      {state.done && <DoneNote>{state.message}</DoneNote>}
      <Submit pending={pending} pendingLabel="Uploading…">
        <ActionIcons.UploadIcon />Upload document
      </Submit>
    </form>
  );
}

/** A button, not an automatic GET: mail scanners open links, and verification shouldn't happen by accident */
export function VerifyEmailForm({ token }: { token: string }) {
  const [state, action, pending] = useActionState<FormState, FormData>(verifyEmail, {});
  if (state.done)
    return (
      <div className="space-y-4">
        <DoneNote>Your email address is confirmed.</DoneNote>
        <Link href="/" className="btn btn-primary w-full">
          <ActionIcons.ArrowRightIcon />Continue
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <input type="hidden" name="token" value={token} />
      <ErrorNote message={state.error} />
      <Submit pending={pending} pendingLabel="Confirming…" wide>
        <ActionIcons.MailIcon />Confirm my email address
      </Submit>
    </form>
  );
}
