"use client";

import { useState } from "react";
import { useMutation } from "convex/react";
import { api } from "../../../../../convex/_generated/api";
import type { Key } from "react-aria";
import {
  Form,
  TextField,
  Label,
  Input,
  TextArea,
  FieldError,
  Button,
  Spinner,
  toast,
  Select,
  ListBox,
} from "@heroui/react";

const TOPIC_OPTIONS = [
  { key: "products", label: "Products" },
  { key: "orders", label: "Orders" },
  { key: "support", label: "Support" },
  { key: "other", label: "Other" },
] as const;

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const MAX_NAME = 200;
const MAX_EMAIL = 254;
const MAX_MESSAGE = 5000;

export function ContactForm() {
  const submitMessage = useMutation(api.messages.submit);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [topicKey, setTopicKey] = useState<Key | null>(null);
  const [topicError, setTopicError] = useState<string | null>(null);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setTopicError(null);

    const form = e.currentTarget;
    const formData = new FormData(form);
    const fullName = (formData.get("fullName") as string)?.trim() ?? "";
    const email = (formData.get("email") as string)?.trim() ?? "";
    const message = (formData.get("message") as string)?.trim() ?? "";

    // Client-side validation
    if (!fullName) {
      toast.danger("Please enter your full name.");
      return;
    }
    if (fullName.length > MAX_NAME) {
      toast.danger(`Full name must be at most ${MAX_NAME} characters.`);
      return;
    }
    if (!email) {
      toast.danger("Please enter your work email.");
      return;
    }
    if (!EMAIL_REGEX.test(email)) {
      toast.danger("Please enter a valid email address.");
      return;
    }
    if (email.length > MAX_EMAIL) {
      toast.danger("Email must be at most 254 characters.");
      return;
    }
    const topic = topicKey as string | null;
    if (!topic || !TOPIC_OPTIONS.some((o) => o.key === topic)) {
      setTopicError("Please select a topic.");
      toast.danger("Please select a topic.");
      return;
    }
    if (!message) {
      toast.danger("Please enter your message.");
      return;
    }
    if (message.length > MAX_MESSAGE) {
      toast.danger(`Message must be at most ${MAX_MESSAGE} characters.`);
      return;
    }

    setIsSubmitting(true);
    try {
      await submitMessage({
        fullName,
        email,
        topic: topic as "products" | "orders" | "support" | "other",
        message,
      });
      toast.success("Thank you! We've received your message and will get back to you soon.");
      form.reset();
      setTopicKey(null);
      setTopicError(null);
    } catch (err: unknown) {
      const messageErr = err instanceof Error ? err.message : "Something went wrong. Please try again.";
      toast.danger(messageErr);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <Form onSubmit={handleSubmit} className="flex flex-col gap-5 w-full">
      <TextField
        isRequired
        name="fullName"
        maxLength={MAX_NAME}
        className="flex flex-col gap-1"
        aria-required="true"
      >
        <Label className="text-sm font-medium text-[var(--foreground)]">
          Full name <span className="text-danger">*</span>
        </Label>
        <Input
          placeholder="First and last name"
          className="bg-[var(--surface)]"
          autoComplete="name"
          disabled={isSubmitting}
          aria-required="true"
        />
        <FieldError className="text-xs text-danger" />
      </TextField>

      <TextField
        isRequired
        name="email"
        type="email"
        maxLength={MAX_EMAIL}
        validate={(val: string) => {
          if (val && !EMAIL_REGEX.test(val)) return "Please enter a valid email address.";
        }}
        className="flex flex-col gap-1"
        aria-required="true"
      >
        <Label className="text-sm font-medium text-[var(--foreground)]">
          Work email address <span className="text-danger">*</span>
        </Label>
        <Input
          type="email"
          placeholder="me@company.com"
          className="bg-[var(--surface)]"
          autoComplete="email"
          disabled={isSubmitting}
          aria-required="true"
        />
        <FieldError className="text-xs text-danger" />
      </TextField>

      <div className="flex flex-col gap-1">
        <Label className="text-sm font-medium text-[var(--foreground)]">
          Topic <span className="text-danger">*</span>
        </Label>
        <Select
          aria-label="Select a topic"
          aria-required="true"
          placeholder="Select a topic"
          value={topicKey}
          onChange={(value) => {
            setTopicKey(value ?? null);
            setTopicError(null);
          }}
          isDisabled={isSubmitting}
          className="w-full"
        >
          <Select.Trigger>
            <Select.Value />
            <Select.Indicator />
          </Select.Trigger>
          <Select.Popover className="rounded-lg">
            <ListBox>
              {TOPIC_OPTIONS.map((opt) => (
                <ListBox.Item key={opt.key} id={opt.key} textValue={opt.label}>
                  {opt.label}
                  <ListBox.ItemIndicator />
                </ListBox.Item>
              ))}
            </ListBox>
          </Select.Popover>
        </Select>
        {topicError && (
          <p className="text-xs text-danger mt-1" role="alert">
            {topicError}
          </p>
        )}
      </div>

      <TextField
        isRequired
        name="message"
        maxLength={MAX_MESSAGE}
        className="flex flex-col gap-1"
        aria-required="true"
      >
        <Label className="text-sm font-medium text-[var(--foreground)]">
          Your message <span className="text-danger">*</span>
        </Label>
        <TextArea
          rows={5}
          placeholder="Write your message"
          className="bg-[var(--surface)]"
          disabled={isSubmitting}
          aria-required="true"
        />
        <FieldError className="text-xs text-danger" />
      </TextField>

      <Button
        type="submit"
        isDisabled={isSubmitting}
        isPending={isSubmitting}
        className="bg-[#f4a13a] text-[#1a2e2d] font-medium w-full md:w-auto md:self-start mt-1"
        aria-busy={isSubmitting}
      >
        {({ isPending }: { isPending: boolean }) =>
          isPending ? (
            <>
              <Spinner color="current" size="sm" />
              Submitting…
            </>
          ) : (
            "Submit"
          )
        }
      </Button>
    </Form>
  );
}
