"use client";

import { useState, type FormEvent } from "react";

import { api } from "./api-client";
import type { Principal } from "./app-types";
import { Icon } from "./icons";
import { StatusLabel } from "./ui-components";

type AuthView = "sign-in" | "request-reset" | "confirm-reset" | "accept-invitation";

export function AuthExperience({
  onSignedIn
}: {
  readonly onSignedIn: (principal: Principal) => void;
}) {
  const [view, setView] = useState<AuthView>("sign-in");
  const [notice, setNotice] = useState("");
  return (
    <main className="sign-in-page">
      <section className="sign-in-story">
        <div className="brand-lockup">
          <span className="brand-mark">MI</span>
          <span>
            <strong>Mi-Insite</strong>
            <small>Intelligence to accountable action</small>
          </span>
        </div>
        <div className="story-content">
          <StatusLabel label="South Africa-first workspace" tone="positive" />
          <h1>Know what changed. Decide what matters. Prove what happened.</h1>
          <p>
            One evidence-grounded command centre for listening, response, publishing, archiving and
            executive reporting.
          </p>
          <div className="story-signals" aria-label="Platform capabilities">
            <span>
              <Icon name="listen" /> Live intelligence
            </span>
            <span>
              <Icon name="inbox" /> Accountable response
            </span>
            <span>
              <Icon name="archive" /> Verified evidence
            </span>
          </div>
        </div>
        <footer>
          <span>Development environment</span>
          <span>Fictional demonstration data only</span>
        </footer>
      </section>
      <section className="sign-in-panel">
        <div className="mobile-brand">
          <span className="brand-mark">MI</span>
          <strong>Mi-Insite</strong>
        </div>
        <div className="auth-form-wrap">
          {view === "sign-in" && (
            <SignInForm
              onForgot={() => setView("request-reset")}
              onInvite={() => setView("accept-invitation")}
              onSignedIn={onSignedIn}
            />
          )}
          {view === "request-reset" && (
            <ResetRequestForm
              onBack={() => setView("sign-in")}
              onSent={() => {
                setNotice("If the account exists, reset instructions were created.");
                setView("confirm-reset");
              }}
            />
          )}
          {view === "confirm-reset" && (
            <ResetConfirmForm
              notice={notice}
              onBack={() => setView("sign-in")}
              onComplete={() => {
                setNotice("");
                setView("sign-in");
              }}
            />
          )}
          {view === "accept-invitation" && <InvitationForm onBack={() => setView("sign-in")} />}
        </div>
        <p className="auth-security-note">
          <Icon name="check" size={15} /> Secure session · 30-minute inactivity timeout
        </p>
      </section>
    </main>
  );
}

function SignInForm({
  onForgot,
  onInvite,
  onSignedIn
}: {
  readonly onForgot: () => void;
  readonly onInvite: () => void;
  readonly onSignedIn: (principal: Principal) => void;
}) {
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);
  const submit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setBusy(true);
    setError("");
    const values = new FormData(event.currentTarget);
    const response = await api("/api/v1/auth/sign-in", {
      method: "POST",
      body: JSON.stringify({
        email: values.get("email"),
        password: values.get("password")
      })
    });
    setBusy(false);
    if (!response.ok) {
      setError("The email or password is incorrect, or the account is temporarily locked.");
      return;
    }
    const payload = (await response.json()) as { data: Principal };
    onSignedIn(payload.data);
  };
  return (
    <>
      <span className="auth-eyebrow">Welcome back</span>
      <h1>Sign in to your workspace</h1>
      <p>Use the account issued by your organisation administrator.</p>
      <form onSubmit={(event) => void submit(event)}>
        <label>
          Email address
          <input name="email" type="email" autoComplete="username" required />
        </label>
        <label>
          <span className="label-row">
            Password
            <button className="inline-link" type="button" onClick={onForgot}>
              Forgot password?
            </button>
          </span>
          <input name="password" type="password" autoComplete="current-password" required />
        </label>
        {error && (
          <p className="form-error" role="alert">
            <Icon name="warning" size={17} /> {error}
          </p>
        )}
        <button className="button-full" type="submit" disabled={busy}>
          {busy ? "Signing in…" : "Sign in securely"}
          {!busy && <Icon name="chevron" size={17} />}
        </button>
      </form>
      <div className="auth-divider">
        <span>or</span>
      </div>
      <button className="button-secondary button-full" type="button" onClick={onInvite}>
        Accept an invitation
      </button>
      <p className="auth-help">Need help? Contact your organisation administrator.</p>
    </>
  );
}

function ResetRequestForm({
  onBack,
  onSent
}: {
  readonly onBack: () => void;
  readonly onSent: () => void;
}) {
  const submit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const values = new FormData(event.currentTarget);
    await api("/api/v1/auth/password-reset/request", {
      method: "POST",
      body: JSON.stringify({ email: values.get("email") })
    });
    onSent();
  };
  return (
    <>
      <button className="back-link" type="button" onClick={onBack}>
        <Icon name="chevron" size={16} className="icon-back" /> Back to sign in
      </button>
      <span className="auth-eyebrow">Account recovery</span>
      <h1>Reset your password</h1>
      <p>Enter your account email. The response will not reveal whether an account exists.</p>
      <form onSubmit={(event) => void submit(event)}>
        <label>
          Email address
          <input name="email" type="email" autoComplete="email" required />
        </label>
        <button className="button-full" type="submit">
          Create reset instructions
        </button>
      </form>
    </>
  );
}

function ResetConfirmForm({
  notice,
  onBack,
  onComplete
}: {
  readonly notice: string;
  readonly onBack: () => void;
  readonly onComplete: () => void;
}) {
  const [error, setError] = useState("");
  const submit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const values = new FormData(event.currentTarget);
    const response = await api("/api/v1/auth/password-reset/confirm", {
      method: "POST",
      body: JSON.stringify({
        token: values.get("token"),
        password: values.get("password")
      })
    });
    if (response.ok) onComplete();
    else setError("The token is invalid, expired, or the password does not meet policy.");
  };
  return (
    <>
      <button className="back-link" type="button" onClick={onBack}>
        <Icon name="chevron" size={16} className="icon-back" /> Back to sign in
      </button>
      <span className="auth-eyebrow">Secure reset</span>
      <h1>Choose a new password</h1>
      {notice && <p className="form-notice">{notice}</p>}
      <form onSubmit={(event) => void submit(event)}>
        <label>
          Reset token
          <input name="token" autoComplete="one-time-code" required />
        </label>
        <label>
          New password
          <input name="password" type="password" autoComplete="new-password" required />
        </label>
        <small>Use at least 12 characters with upper, lower, number and symbol.</small>
        {error && (
          <p className="form-error" role="alert">
            {error}
          </p>
        )}
        <button className="button-full" type="submit">
          Reset password
        </button>
      </form>
    </>
  );
}

function InvitationForm({ onBack }: { readonly onBack: () => void }) {
  const [message, setMessage] = useState("");
  const submit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const values = new FormData(event.currentTarget);
    const response = await api("/api/v1/invitations/accept", {
      method: "POST",
      body: JSON.stringify({
        token: values.get("token"),
        displayName: values.get("displayName"),
        password: values.get("password")
      })
    });
    setMessage(
      response.ok
        ? "Invitation accepted. You can now sign in."
        : "The invitation is invalid, expired, or already used."
    );
  };
  return (
    <>
      <button className="back-link" type="button" onClick={onBack}>
        <Icon name="chevron" size={16} className="icon-back" /> Back to sign in
      </button>
      <span className="auth-eyebrow">Join a workspace</span>
      <h1>Accept your invitation</h1>
      <p>Invitation tokens are single-use and expire after seven days.</p>
      <form onSubmit={(event) => void submit(event)}>
        <label>
          Invitation token
          <input name="token" autoComplete="one-time-code" required />
        </label>
        <label>
          Display name
          <input name="displayName" autoComplete="name" required />
        </label>
        <label>
          Create password
          <input name="password" type="password" autoComplete="new-password" required />
        </label>
        {message && <p className="form-notice">{message}</p>}
        <button className="button-full" type="submit">
          Accept invitation
        </button>
      </form>
    </>
  );
}
