/**
 * Login page.
 *
 * A single password field and submit button.  On success the user is
 * redirected to the originally requested page (via the `?next=` query
 * parameter) or the dashboard.
 */

import { useState } from "react";
import {
  Button,
  Field,
  Input,
  makeStyles,
  MessageBar,
  MessageBarBody,
  Spinner,
  Text,
  tokens,
} from "@fluentui/react-components";
import { useNavigate, useSearchParams } from "react-router-dom";
import type { ChangeEvent, FormEvent } from "react";
import { ApiError } from "../api/client";
import { useAuth } from "../hooks/useAuth";

// ---------------------------------------------------------------------------
// Styles
// ---------------------------------------------------------------------------

const useStyles = makeStyles({
  root: {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    minHeight: "100vh",
    backgroundColor: tokens.colorNeutralBackground2,
    padding: tokens.spacingHorizontalM,
  },
  card: {
    width: "100%",
    maxWidth: "360px",
    backgroundColor: tokens.colorNeutralBackground1,
    borderRadius: tokens.borderRadiusXLarge,
    padding: tokens.spacingVerticalXXL,
    boxShadow: tokens.shadow8,
  },
  heading: {
    marginBottom: tokens.spacingVerticalXS,
    display: "block",
  },
  subtitle: {
    marginBottom: tokens.spacingVerticalXXL,
    color: tokens.colorNeutralForeground2,
    display: "block",
  },
  field: {
    marginBottom: tokens.spacingVerticalM,
  },
  submitRow: {
    marginTop: tokens.spacingVerticalL,
  },
  error: {
    marginBottom: tokens.spacingVerticalM,
  },
});

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

/**
 * Login page — single password input, no username.
 */
export function LoginPage(): React.JSX.Element {
  const styles = useStyles();
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const { login } = useAuth();

  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const nextPath = searchParams.get("next") ?? "/";

  function handlePasswordChange(ev: ChangeEvent<HTMLInputElement>): void {
    setPassword(ev.target.value);
    setError(null);
  }

  async function handleSubmit(ev: FormEvent<HTMLFormElement>): Promise<void> {
    ev.preventDefault();
    if (!password) {
      setError("Please enter a password.");
      return;
    }

    setSubmitting(true);
    setError(null);

    try {
      await login(password);
      navigate(nextPath, { replace: true });
    } catch (err) {
      if (err instanceof ApiError && err.status === 401) {
        setError("Incorrect password. Please try again.");
      } else {
        setError("An unexpected error occurred. Please try again.");
      }
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className={styles.root}>
      <div className={styles.card}>
        <Text as="h1" size={700} weight="semibold" className={styles.heading}>
          BanGUI
        </Text>
        <Text size={300} className={styles.subtitle}>
          Enter your master password to continue.
        </Text>

        {error !== null && (
          <MessageBar intent="error" className={styles.error}>
            <MessageBarBody>{error}</MessageBarBody>
          </MessageBar>
        )}

        <form onSubmit={(ev) => void handleSubmit(ev)}>
          {/* Hidden username field — required by accessibility guidelines for
              password managers to correctly identify the credential form. */}
          <input
            type="text"
            autoComplete="username"
            aria-hidden="true"
            tabIndex={-1}
            value="bangui"
            readOnly
            style={{ display: "none" }}
          />
          <div className={styles.field}>
            <Field label="Password" required>
              <Input
                type="password"
                value={password}
                onChange={handlePasswordChange}
                autoComplete="current-password"
                autoFocus
              />
            </Field>
          </div>

          <div className={styles.submitRow}>
            <Button
              type="submit"
              appearance="primary"
              disabled={submitting || !password}
              icon={submitting ? <Spinner size="tiny" /> : undefined}
            >
              {submitting ? "Signing in…" : "Sign in"}
            </Button>
          </div>
        </form>
      </div>
    </div>
  );
}
