"use client";

import Link from "next/link";
import { useActionState, useEffect, useRef } from "react";

import { submitDemoRequest } from "@/app/actions";
import { initialFormState } from "@/lib/form-state";
import { LOCALE_NAME, LOCALES, type Locale } from "@/lib/locales";

import { Button } from "./Button";
import styles from "./Form.module.css";

export type DemoFormStrings = {
  name: string;
  company: string;
  sector: string;
  sectorPlaceholder: string;
  sectorOther: string;
  phone: string;
  language: string;
  message: string;
  optional: string;
  consent: string;
  privacyLabel: string;
  privacyHref: string;
  send: string;
  sending: string;
  successTitle: string;
  successBody: string;
  errorTitle: string;
  errorSummaryAria: string;
};

export type SectorOption = { value: string; label: string };

/**
 * The demo request — the site's one primary action (Blueprint 02).
 *
 * Five fields plus an optional message, validated on the server. The success
 * state replaces the form instantly with a green rule above it (motion #5);
 * there is no spinner and no page reload.
 */
export function DemoForm({
  locale,
  sectors,
  strings,
}: {
  locale: Locale;
  sectors: SectorOption[];
  strings: DemoFormStrings;
}) {
  const [state, action, pending] = useActionState(submitDemoRequest, initialFormState);
  const startedAtRef = useRef<HTMLInputElement | null>(null);
  const resultRef = useRef<HTMLDivElement | null>(null);

  /*
   * The fill-time reference is written straight into the input on mount. It
   * must not be part of the statically generated HTML: a build-time stamp
   * would make every submission look hours old and the check would never fire.
   */
  useEffect(() => {
    if (startedAtRef.current) {
      startedAtRef.current.value = String(Date.now());
    }
  }, []);

  useEffect(() => {
    if (state.status !== "idle") {
      resultRef.current?.focus();
    }
  }, [state.status]);

  if (state.status === "success") {
    return (
      <div className={styles.result} ref={resultRef} tabIndex={-1} role="status">
        <p className={styles.resultTitle}>{strings.successTitle}</p>
        <p className={styles.resultBody}>{strings.successBody}</p>
      </div>
    );
  }

  const errors = state.errors ?? {};
  const errorList = Object.values(errors);

  return (
    <form action={action} className={styles.form} noValidate>
      <input type="hidden" name="locale" value={locale} />
      <input type="hidden" name="startedAt" defaultValue="0" ref={startedAtRef} />

      {errorList.length > 0 ? (
        <div
          className={styles.summary}
          ref={resultRef}
          tabIndex={-1}
          role="alert"
          aria-label={strings.errorSummaryAria}
        >
          <p className={styles.resultTitle}>{strings.errorTitle}</p>
          <ul className={styles.summaryList}>
            {errorList.map((message) => (
              <li key={message}>{message}</li>
            ))}
          </ul>
        </div>
      ) : null}

      <div className={styles.fields}>
        <p className={styles.field}>
          <label className={styles.label} htmlFor="demo-name">
            {strings.name}
          </label>
          <input
            id="demo-name"
            name="name"
            type="text"
            autoComplete="name"
            required
            aria-invalid={errors.name ? true : undefined}
            aria-describedby={errors.name ? "demo-name-error" : undefined}
            className={[styles.input, errors.name ? styles.invalid : null]
              .filter(Boolean)
              .join(" ")}
          />
          {errors.name ? (
            <span id="demo-name-error" className={styles.error}>
              {errors.name}
            </span>
          ) : null}
        </p>

        <p className={styles.field}>
          <label className={styles.label} htmlFor="demo-company">
            {strings.company} <span className={styles.optional}>({strings.optional})</span>
          </label>
          <input
            id="demo-company"
            name="company"
            type="text"
            autoComplete="organization"
            className={styles.input}
          />
        </p>

        <p className={styles.field}>
          <label className={styles.label} htmlFor="demo-sector">
            {strings.sector}
          </label>
          <select
            id="demo-sector"
            name="sector"
            required
            defaultValue=""
            aria-invalid={errors.sector ? true : undefined}
            aria-describedby={errors.sector ? "demo-sector-error" : undefined}
            className={[styles.select, errors.sector ? styles.invalid : null]
              .filter(Boolean)
              .join(" ")}
          >
            <option value="" disabled>
              {strings.sectorPlaceholder}
            </option>
            {sectors.map((sector) => (
              <option key={sector.value} value={sector.value}>
                {sector.label}
              </option>
            ))}
            <option value="other">{strings.sectorOther}</option>
          </select>
          {errors.sector ? (
            <span id="demo-sector-error" className={styles.error}>
              {errors.sector}
            </span>
          ) : null}
        </p>

        <p className={styles.field}>
          <label className={styles.label} htmlFor="demo-phone">
            {strings.phone}
          </label>
          <input
            id="demo-phone"
            name="phone"
            type="tel"
            inputMode="tel"
            autoComplete="tel"
            required
            aria-invalid={errors.phone ? true : undefined}
            aria-describedby={errors.phone ? "demo-phone-error" : undefined}
            className={[styles.input, errors.phone ? styles.invalid : null]
              .filter(Boolean)
              .join(" ")}
          />
          {errors.phone ? (
            <span id="demo-phone-error" className={styles.error}>
              {errors.phone}
            </span>
          ) : null}
        </p>

        <p className={styles.field}>
          <label className={styles.label} htmlFor="demo-language">
            {strings.language}
          </label>
          <select
            id="demo-language"
            name="preferredLanguage"
            defaultValue={locale}
            className={styles.select}
          >
            {/*
              Each language names itself, in itself — a reader looking for
              their own language is looking for the word they would use for
              it, not for its name translated into the page they happen to be
              standing on.
            */}
            {LOCALES.map((option) => (
              <option key={option} value={option}>
                {LOCALE_NAME[option]}
              </option>
            ))}
          </select>
        </p>

        <p className={`${styles.field} ${styles.span2}`}>
          <label className={styles.label} htmlFor="demo-message">
            {strings.message} <span className={styles.optional}>({strings.optional})</span>
          </label>
          <textarea id="demo-message" name="message" rows={4} className={styles.textarea} />
        </p>
      </div>

      {/* Honeypot — a real visitor never sees or fills this. */}
      <p className={styles.honeypot} aria-hidden="true">
        <label htmlFor="demo-website">Website</label>
        <input id="demo-website" name="website" type="text" tabIndex={-1} autoComplete="off" />
      </p>

      <p className={styles.consent}>
        {strings.consent} <Link href={strings.privacyHref}>{strings.privacyLabel}</Link>
      </p>

      <div className={styles.actions}>
        <Button type="submit" disabled={pending} data-event="demo_submit">
          {pending ? strings.sending : strings.send}
        </Button>
      </div>
    </form>
  );
}
