"use client";

import { useState, useRef } from "react";
import type { FormEvent } from "react";
import { Turnstile } from "@marsidev/react-turnstile";
import { Button } from "@/components/site";

const SITE_KEY = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY ?? "";

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

interface ContactFormProps {
  submitLabel: string;
  successMessage: string;
}

interface FieldErrors {
  name?: string;
  email?: string;
  message?: string;
}

export function ContactForm({ submitLabel, successMessage }: ContactFormProps) {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [message, setMessage] = useState("");
  const [errors, setErrors] = useState<FieldErrors>({});
  const [apiError, setApiError] = useState<string | null>(null);
  const [submitted, setSubmitted] = useState(false);
  const [loading, setLoading] = useState(false);
  const turnstileToken = useRef<string | null>(null);

  function validate(): FieldErrors {
    const e: FieldErrors = {};
    if (!name.trim()) e.name = "Name is required.";
    if (!email.trim()) {
      e.email = "Email is required.";
    } else if (!EMAIL_RE.test(email)) {
      e.email = "Enter a valid email address.";
    }
    if (!message.trim()) e.message = "Message is required.";
    return e;
  }

  async function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setApiError(null);

    const fieldErrors = validate();
    if (Object.keys(fieldErrors).length > 0) {
      setErrors(fieldErrors);
      return;
    }
    setErrors({});
    setLoading(true);

    try {
      const res = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: name.trim(),
          email: email.trim(),
          message: message.trim(),
          ...(turnstileToken.current ? { turnstileToken: turnstileToken.current } : {}),
        }),
      });

      const data = (await res.json()) as { ok: boolean; error?: string };

      if (!res.ok || !data.ok) {
        setApiError(data.error ?? "Submission failed. Please try again.");
      } else {
        setSubmitted(true);
      }
    } catch {
      setApiError("Network error. Please check your connection and try again.");
    } finally {
      setLoading(false);
    }
  }

  if (submitted) {
    return (
      <div className="rounded-md border border-tertiary/20 bg-surface-container-low px-6 py-8 text-center">
        <span className="h-2 w-2 inline-block rounded-full bg-tertiary shadow-[0_0_10px_rgba(142,255,113,0.5)] mb-4" />
        <p className="body-lg text-on-surface">{successMessage}</p>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} noValidate className="flex flex-col gap-6">
      {/* Name */}
      <div className="flex flex-col gap-1.5">
        <label className="label-sm uppercase tracking-widest text-on-surface-variant">
          Full Name
        </label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="WALTER O'BRIEN"
          className="w-full border-0 border-b border-outline-variant/50 bg-surface-container-low px-0 py-3 font-headline uppercase tracking-tighter text-on-surface placeholder:text-outline transition-colors focus:border-primary focus:ring-0 focus:outline-none"
          aria-invalid={Boolean(errors.name)}
          aria-describedby={errors.name ? "err-name" : undefined}
        />
        {errors.name && (
          <span id="err-name" className="label-sm text-error">
            {errors.name}
          </span>
        )}
      </div>

      {/* Email */}
      <div className="flex flex-col gap-1.5">
        <label className="label-sm uppercase tracking-widest text-on-surface-variant">
          Email Address
        </label>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="W.OBRIEN@CENTRAL.COM"
          className="w-full border-0 border-b border-outline-variant/50 bg-surface-container-low px-0 py-3 font-headline uppercase tracking-tighter text-on-surface placeholder:text-outline transition-colors focus:border-primary focus:ring-0 focus:outline-none"
          aria-invalid={Boolean(errors.email)}
          aria-describedby={errors.email ? "err-email" : undefined}
        />
        {errors.email && (
          <span id="err-email" className="label-sm text-error">
            {errors.email}
          </span>
        )}
      </div>

      {/* Message */}
      <div className="flex flex-col gap-1.5">
        <label className="label-sm uppercase tracking-widest text-on-surface-variant">
          Message
        </label>
        <textarea
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          placeholder="DESCRIBE THE SYSTEM ARCHITECTURE OR PROBLEM SET..."
          rows={4}
          className="w-full resize-none border-0 border-b border-outline-variant/50 bg-surface-container-low px-0 py-3 font-headline uppercase tracking-tighter text-on-surface placeholder:text-outline transition-colors focus:border-primary focus:ring-0 focus:outline-none"
          aria-invalid={Boolean(errors.message)}
          aria-describedby={errors.message ? "err-message" : undefined}
        />
        {errors.message && (
          <span id="err-message" className="label-sm text-error">
            {errors.message}
          </span>
        )}
      </div>

      {/* Turnstile */}
      {SITE_KEY ? (
        <Turnstile
          siteKey={SITE_KEY}
          onSuccess={(token: string) => {
            turnstileToken.current = token;
          }}
        />
      ) : (
        <span className="label-sm text-on-surface-variant">
          Spam protection disabled (dev)
        </span>
      )}

      {/* API error */}
      {apiError && (
        <div
          role="alert"
          className="rounded-sm border border-error/20 bg-error-container/20 px-4 py-3"
        >
          <span className="label-sm text-error">{apiError}</span>
        </div>
      )}

      <Button
        type="submit"
        variant="primary"
        disabled={loading}
        className="mt-2 w-full justify-center disabled:opacity-50"
      >
        {loading ? "SENDING..." : submitLabel}
      </Button>
    </form>
  );
}
