"use client";

import { useState, type CSSProperties, type FC, type ReactNode } from "react";
import { AuthCard, SignInForm, type SignInValues } from "@crema/auth-ui";
import {
  ArcadiaError,
  useArcadiaClient,
  type ArcadiaAuthTokens,
  type ArcadiaUser,
} from "@crema/arcadia-core-client";

export interface LoginResult {
  tokens: ArcadiaAuthTokens;
  user?: ArcadiaUser;
  /** True if the API responded with a 2FA challenge instead of tokens. */
  twoFactorRequired?: boolean;
  /** Opaque challenge token to pass to the 2FA step (when twoFactorRequired). */
  twoFactorChallenge?: string;
  /** Whether the user asked to be remembered (from the form's checkbox). */
  remember?: boolean;
}

export interface LoginFormProps {
  /** Where to POST. Defaults to "/api/v1/auth/login". */
  loginPath?: string;
  /** Called on successful auth (or 2FA challenge — check twoFactorRequired). */
  onSuccess: (result: LoginResult) => void | Promise<void>;
  /** "Forgot password?" link click. If omitted, the link is hidden. */
  onForgotPassword?: () => void;
  /** "Don't have an account?" link click. Rendered in the card footer. */
  onSignup?: () => void;
  /** Optional brand row above the form (logo, app name). */
  brand?: ReactNode;
  /** Heading text. Default: "Sign in". */
  heading?: string;
  /** Subhead under the heading. */
  subhead?: ReactNode;
  /** Pre-fill email (e.g. from query string after invitation accept). */
  defaultEmail?: string;
  /** Override styles on the outer card. */
  style?: CSSProperties;
}

export const LoginForm: FC<LoginFormProps> = ({
  loginPath = "/api/v1/auth/login",
  onSuccess,
  onForgotPassword,
  onSignup,
  brand,
  heading = "Sign in",
  subhead,
  defaultEmail,
  style,
}) => {
  const arcadia = useArcadiaClient();
  const [error, setError] = useState<string | null>(null);

  async function handleSubmit({ email, password, remember }: SignInValues) {
    setError(null);
    try {
      const res = await arcadia.POST<{
        data: ArcadiaAuthTokens & {
          user?: ArcadiaUser;
          two_factor_required?: boolean;
          two_factor_challenge?: string;
        };
      }>(loginPath, { body: { email, password } });
      const { user, two_factor_required, two_factor_challenge, ...tokens } = res.data;
      await onSuccess({
        tokens,
        user,
        twoFactorRequired: two_factor_required,
        twoFactorChallenge: two_factor_challenge,
        remember,
      });
    } catch (err) {
      // SignInForm catches and clears its own pending state when this throws.
      // We surface the message via local error state below the form.
      if (err instanceof ArcadiaError) setError(err.message);
      else setError("Something went wrong. Please try again.");
      throw err;
    }
  }

  return (
    <AuthCard
      logo={brand}
      title={heading}
      description={subhead}
      footer={
        onSignup ? (
          <span className="text-sm text-muted-foreground">
            Don&apos;t have an account?{" "}
            <button
              type="button"
              data-action="auth-login-signup"
              onClick={onSignup}
              className="text-primary underline underline-offset-2"
            >
              Sign up
            </button>
          </span>
        ) : undefined
      }
      className="auth-arcadia-login"
      // style is forwarded via wrapper; AuthCard takes className not style
    >
      <div data-action="auth-login" style={style}>
        <SignInForm
          onSubmit={handleSubmit}
          onForgot={onForgotPassword}
          defaultEmail={defaultEmail}
        />
        {error ? (
          <div
            role="alert"
            className="mt-3 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive"
            data-action="auth-login-error"
          >
            {error}
          </div>
        ) : null}
      </div>
    </AuthCard>
  );
};
