import type { FormEvent, ReactNode } from "react";
import {
  Alert,
  AlertDescription,
  AlertIcon,
  Button,
  FormControl,
  FormLabel,
  Input,
  Spinner,
  Stack,
  Text
} from "@chakra-ui/react";
import type { PasswordResetMode, PasswordResetTokenState } from "./types";

type PasswordResetRequestTexts = {
  emailLabel: string;
  submitLabel: string;
  requestSentMessage: string;
};

type PasswordResetRequestFormProps = {
  texts: PasswordResetRequestTexts;
  helperText: ReactNode;
  loading?: boolean;
  requestSent?: boolean;
  onSubmit: (values: { email: string }) => void | Promise<void>;
  emailPlaceholder?: string;
};

type PasswordResetConfirmTexts = {
  loadingLabel: string;
  passwordLabel: string;
  passwordConfirmLabel: string;
  invalidLinkLabel: string;
  resetSubmitLabel: string;
  createSubmitLabel: string;
  resetSuccessLabel: string;
  createSuccessLabel: string;
};

type PasswordResetConfirmFormProps = {
  texts: PasswordResetConfirmTexts;
  tokenState: PasswordResetTokenState;
  loading?: boolean;
  completedMode?: PasswordResetMode | null;
  onSubmit: (values: { password: string; passwordConfirm: string }) => void | Promise<void>;
};

export function PasswordResetRequestForm({
  texts,
  helperText,
  loading = false,
  requestSent = false,
  onSubmit,
  emailPlaceholder = "you@example.com"
}: PasswordResetRequestFormProps) {
  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const form = new FormData(event.currentTarget);
    void onSubmit({
      email: String(form.get("email") ?? "")
    });
  }

  return (
    <Stack spacing={5}>
      {requestSent ? (
        <Alert status="success" borderRadius="md">
          <AlertIcon />
          <AlertDescription>{texts.requestSentMessage}</AlertDescription>
        </Alert>
      ) : null}

      <form onSubmit={handleSubmit}>
        <Stack spacing={4}>
          <FormControl isRequired>
            <FormLabel>{texts.emailLabel}</FormLabel>
            <Input name="email" type="email" placeholder={emailPlaceholder} />
          </FormControl>

          <Text fontSize="sm" color="gray.600">
            {helperText}
          </Text>

          <Button type="submit" isLoading={loading}>
            {texts.submitLabel}
          </Button>
        </Stack>
      </form>
    </Stack>
  );
}

export function PasswordResetConfirmForm({
  texts,
  tokenState,
  loading = false,
  completedMode = null,
  onSubmit
}: PasswordResetConfirmFormProps) {
  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const form = new FormData(event.currentTarget);
    void onSubmit({
      password: String(form.get("password") ?? ""),
      passwordConfirm: String(form.get("passwordConfirm") ?? "")
    });
  }

  if (tokenState.status === "loading") {
    return (
      <Stack align="center" py={6} spacing={3}>
        <Spinner />
        <Text color="gray.600">{texts.loadingLabel}</Text>
      </Stack>
    );
  }

  if (tokenState.status === "invalid") {
    return (
      <Alert status="error" borderRadius="md">
        <AlertIcon />
        <AlertDescription>{tokenState.error || texts.invalidLinkLabel}</AlertDescription>
      </Alert>
    );
  }

  if (completedMode !== null) {
    return (
      <Alert status="success" borderRadius="md">
        <AlertIcon />
        <AlertDescription>{completedMode === "create" ? texts.createSuccessLabel : texts.resetSuccessLabel}</AlertDescription>
      </Alert>
    );
  }

  return (
    <Stack spacing={4}>
      <Text fontSize="sm" color="gray.600">
        {tokenState.email}
      </Text>

      <form onSubmit={handleSubmit}>
        <Stack spacing={4}>
          <FormControl isRequired>
            <FormLabel>{texts.passwordLabel}</FormLabel>
            <Input name="password" type="password" minLength={8} />
          </FormControl>

          <FormControl isRequired>
            <FormLabel>{texts.passwordConfirmLabel}</FormLabel>
            <Input name="passwordConfirm" type="password" minLength={8} />
          </FormControl>

          <Button type="submit" isLoading={loading}>
            {tokenState.mode === "create" ? texts.createSubmitLabel : texts.resetSubmitLabel}
          </Button>
        </Stack>
      </form>
    </Stack>
  );
}
