'use client';

import * as FieldIcons from './Icons';

import { PasswordInput } from './PasswordInput';

import Link from 'next/link';
import { useActionState } from 'react';
import { changeEmail, changePassword, deleteAccount, forgotPassword, login, register, resendVerification, resetPassword, verifyEmail, type FormState } from '@/app/account/actions';
import { AlertIcon, ArrowRightIcon, CheckCircleIcon, Spinner } from './Icons';

function Err({ m }: { m?: string }) {
  if (!m) 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" />
      {m}
    </p>
  );
}
function Ok({ children }: { children: React.ReactNode }) {
  return (
    <p role="status" className="flex items-start gap-2 rounded-lg border border-ledger/30 bg-ledger-tint 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, label, wide = true }: { pending: boolean; children: React.ReactNode; label: string; wide?: boolean }) {
  return (
    <button disabled={pending} className={`btn btn-primary ${wide ? 'w-full' : ''}`}>
      {pending ? (
        <>
          <Spinner /> {label}
        </>
      ) : (
        children
      )}
    </button>
  );
}
const Pw = ({ name = 'password', label = 'Password', auto = 'new-password' }: { name?: string; label?: string; auto?: string }) => (
  <label className="block">
    <span className="field-label"><FieldIcons.KeyIcon />{label}</span>
    <PasswordInput name={name}  required minLength={auto === 'new-password' ? 10 : 1} maxLength={200} autoComplete={auto} className="field" />
  </label>
);

export function LoginForm({ next }: { next: string }) {
  const [s, action, pending] = useActionState<FormState, FormData>(login, {});
  return (
    <form action={action} className="space-y-4">
      <input type="hidden" name="next" value={next} />
      {s.challengeToken ? (
        <>
          <input type="hidden" name="challengeToken" value={s.challengeToken} />
          <label className="block">
            <span className="field-label"><FieldIcons.ShieldCheckIcon />Code from your authenticator app (or a recovery code)</span>
            <input name="code" required autoFocus maxLength={20} autoComplete="one-time-code" className="field num text-center tracking-[0.3em]" />
          </label>
        </>
      ) : (
        <>
          <label className="block">
            <span className="field-label"><FieldIcons.MailIcon />Email</span>
            <input name="email" type="email" required autoFocus autoComplete="username" className="field" />
          </label>
          <Pw auto="current-password" />
        </>
      )}
      <Err m={s.error} />
      <Submit pending={pending} label="Signing in…">
        {s.challengeToken ? 'Verify' : 'Sign in'} <ArrowRightIcon className="h-4 w-4" />
      </Submit>
    </form>
  );
}

export function RegisterForm() {
  const [s, action, pending] = useActionState<FormState, FormData>(register, {});
  if (s.done)
    return (
      <div className="space-y-3">
        <Ok>{s.message}</Ok>
        <p className="text-sm text-muted">The link expires in 48 hours. Once confirmed, enquiries you sent from this email appear in your account.</p>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <label className="block">
        <span className="field-label"><FieldIcons.UserIcon />Your name</span>
        <input name="name" required minLength={2} maxLength={150} autoComplete="name" className="field" />
      </label>
      <label className="block">
        <span className="field-label"><FieldIcons.MailIcon />Email</span>
        <input name="email" type="email" required autoComplete="email" className="field" />
        <span className="mt-1 block text-xs text-muted">Use the address you sent enquiries from to see them in your account.</span>
      </label>
      <Pw />
      <Pw name="confirmPassword" label="Repeat password" />
      <label className="flex items-start gap-2.5 text-sm text-ink-2">
        <input type="checkbox" name="acceptTerms" required className="mt-1" />
        <span>
          I agree to the{' '}
          <Link href="/disclaimer/" className="link">
            terms
          </Link>{' '}
          and{' '}
          <Link href="/privacy/" className="link">
            privacy policy
          </Link>
          .
        </span>
      </label>
      <input name="website" tabIndex={-1} autoComplete="off" className="hidden" aria-hidden />
      <Err m={s.error} />
      <Submit pending={pending} label="Creating account…">
        <FieldIcons.UserIcon />Create free account
      </Submit>
    </form>
  );
}

export function ForgotForm() {
  const [s, action, pending] = useActionState<FormState, FormData>(forgotPassword, {});
  if (s.done) return <Ok>{s.message}</Ok>;
  return (
    <form action={action} className="space-y-4">
      <label className="block">
        <span className="field-label"><FieldIcons.MailIcon />Email</span>
        <input name="email" type="email" required autoFocus autoComplete="username" className="field" />
      </label>
      <Err m={s.error} />
      <Submit pending={pending} label="Sending…">
        <FieldIcons.MailIcon />Email me a reset link
      </Submit>
    </form>
  );
}

export function ResetForm({ token, otpRequired = false }: { token: string; otpRequired?: boolean }) {
  const [s, action, pending] = useActionState<FormState, FormData>(resetPassword, {});
  if (s.done)
    return (
      <div className="space-y-4">
        <Ok>Password changed. Every device was signed out.</Ok>
        <Link href="/account/login/" className="btn btn-primary w-full">
          <FieldIcons.UserIcon />Sign in
        </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"><FieldIcons.MailIcon />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>}

      <Pw label="New password" />
      <Pw name="confirmPassword" label="Repeat new password" />
      <Err m={s.error} />
      <Submit pending={pending} label="Saving…">
        <FieldIcons.KeyIcon />Set new password
      </Submit>
    </form>
  );
}

export function VerifyForm({ token }: { token: string }) {
  const [s, action, pending] = useActionState<FormState, FormData>(verifyEmail, {});
  if (s.done)
    return (
      <div className="space-y-4">
        <Ok>Your email is confirmed. Enquiries you sent from it now appear in your account.</Ok>
        <Link href="/account/" className="btn btn-primary w-full">
          <FieldIcons.UserIcon />Go to my account
        </Link>
      </div>
    );
  return (
    <form action={action} className="space-y-4">
      <input type="hidden" name="token" value={token} />
      <Err m={s.error} />
      <Submit pending={pending} label="Confirming…">
        <FieldIcons.BadgeCheckIcon />Confirm my email
      </Submit>
    </form>
  );
}

export function ResendVerification() {
  const [s, action, pending] = useActionState<FormState>(resendVerification, {});
  return (
    <form action={action} className="inline">
      {s.done ? <span className="text-sm text-ledger">{s.message}</span> : <button className="link text-sm" disabled={pending}>{pending ? 'Sending…' : 'Send the confirmation email again'}</button>}
      {s.error && <span className="ml-2 text-xs text-danger">{s.error}</span>}
    </form>
  );
}

export function ChangeEmailForm({ mfaEnabled }: { mfaEnabled: boolean }) {
  const [s, action, pending] = useActionState<FormState, FormData>(changeEmail, {});
  return <form action={action} className="max-w-sm space-y-4">
    <label className="block"><span className="field-label"><FieldIcons.MailIcon />New email</span><input name="email" type="email" required maxLength={255} autoComplete="email" className="field" /></label>
    <Pw name="currentPassword" label="Current password" auto="current-password" />
    {mfaEnabled && <label className="block"><span className="field-label"><FieldIcons.ShieldCheckIcon />Authenticator code</span><input name="code" required pattern="[0-9]{6}" maxLength={6} autoComplete="one-time-code" className="field" /></label>}
    <Err m={s.error} />{s.done && <Ok>{s.message}</Ok>}<Submit pending={pending} label="Sending..." wide={false}>Verify new email</Submit>
  </form>;
}

export function ChangePasswordForm({ mfaEnabled = false }: { mfaEnabled?: boolean }) {
  const [s, action, pending] = useActionState<FormState, FormData>(changePassword, {});
  return (
    <form action={action} className="max-w-sm space-y-4">
      <Pw name="currentPassword" label="Current password" auto="current-password" />
      <Pw name="newPassword" label="New password" />
      <Pw name="confirmPassword" label="Repeat new password" />
      {mfaEnabled && <label className="block"><span className="field-label"><FieldIcons.ShieldCheckIcon />Authenticator code</span><input name="code" required pattern="[0-9]{6}" maxLength={6} autoComplete="one-time-code" className="field" /></label>}
      <Err m={s.error} />
      {s.done && <Ok>{s.message}</Ok>}
      <Submit pending={pending} label="Saving…" wide={false}>
        <FieldIcons.KeyIcon />Change password
      </Submit>
    </form>
  );
}

export function DeleteAccountForm() {
  const [s, action, pending] = useActionState<FormState, FormData>(deleteAccount, {});
  return (
    <form action={action} className="max-w-sm space-y-4">
      <Pw label="Your password" auto="current-password" />
      <label className="block">
        <span className="field-label"><FieldIcons.TrashIcon />Type DELETE to confirm</span>
        <input name="confirm" required pattern="DELETE" className="field" />
      </label>
      <Err m={s.error} />
      <button disabled={pending} className="btn btn-sm border-danger text-danger hover:bg-danger-soft">
        {pending ? <Spinner /> : <FieldIcons.TrashIcon />} Delete my account
      </button>
    </form>
  );
}
