import { Button } from "@code/ui/components/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@code/ui/components/card";
import {
  Field,
  FieldDescription,
  FieldError,
  FieldGroup,
  FieldLabel,
} from "@code/ui/components/field";
import { Input } from "@code/ui/components/input";
import { cn } from "@code/ui/lib/utils";
import type { ComponentProps } from "react";

import { getErrorMessage } from "../shared/forms";
import { useSignInForm } from "./hooks";

type LoginFormProps = ComponentProps<"div"> & {
  readonly onSuccess?: () => void;
  readonly signUpHref?: string;
};

export const LoginForm = ({
  className,
  onSuccess,
  signUpHref = "/signup",
  ...props
}: LoginFormProps) => {
  const form = useSignInForm({ onSuccess });

  return (
    <div className={cn("flex flex-col gap-6", className)} {...props}>
      <Card>
        <CardHeader>
          <CardTitle>Welcome back</CardTitle>
          <CardDescription>Enter your email and password to continue.</CardDescription>
        </CardHeader>
        <CardContent>
          <form
            onSubmit={(event) => {
              event.preventDefault();
              event.stopPropagation();
              void form.handleSubmit();
            }}
          >
            <FieldGroup>
              <form.Field name="email">
                {(field) => (
                  <Field data-invalid={!field.state.meta.isValid}>
                    <FieldLabel htmlFor={field.name}>Email</FieldLabel>
                    <Input
                      autoComplete="email"
                      id={field.name}
                      name={field.name}
                      onBlur={field.handleBlur}
                      onChange={(event) => field.handleChange(event.target.value)}
                      placeholder="you@example.com"
                      type="email"
                      value={field.state.value}
                    />
                    <FieldError errors={field.state.meta.errors} />
                  </Field>
                )}
              </form.Field>

              <form.Field name="password">
                {(field) => (
                  <Field data-invalid={!field.state.meta.isValid}>
                    <FieldLabel htmlFor={field.name}>Password</FieldLabel>
                    <Input
                      autoComplete="current-password"
                      id={field.name}
                      name={field.name}
                      onBlur={field.handleBlur}
                      onChange={(event) => field.handleChange(event.target.value)}
                      type="password"
                      value={field.state.value}
                    />
                    <FieldError errors={field.state.meta.errors} />
                  </Field>
                )}
              </form.Field>

              <form.Subscribe
                selector={(state) => ({
                  canSubmit: state.canSubmit,
                  isSubmitting: state.isSubmitting,
                  submitError: getErrorMessage(state.errorMap.onSubmit),
                })}
              >
                {({ canSubmit, isSubmitting, submitError }) => (
                  <Field>
                    <FieldError>{submitError}</FieldError>
                    <Button disabled={!canSubmit || isSubmitting} type="submit">
                      {isSubmitting ? "Signing in…" : "Sign in"}
                    </Button>
                    <FieldDescription className="text-center">
                      Don&apos;t have an account? <a href={signUpHref}>Sign up</a>
                    </FieldDescription>
                  </Field>
                )}
              </form.Subscribe>
            </FieldGroup>
          </form>
        </CardContent>
      </Card>
    </div>
  );
};
