"use client";

import Link from "./site-link";
import { useMemo, useRef, useState, type FormEvent } from "react";
import { categories } from "../lib/catalog";
import { useQuote } from "./quote-provider";

type ContactData = {
  profile: string;
  name: string;
  whatsapp: string;
  email: string;
  city: string;
  state: string;
};

type NeedData = {
  projectType: string;
  deadline: string;
  fulfillment: string;
  requestedItems: string;
  message: string;
};

const fieldMessages: Record<string, string> = {
  profile: "Selecione o perfil de quem está solicitando.",
  "contact-name": "Informe o nome do solicitante.",
  "contact-whatsapp": "Informe um número de WhatsApp.",
  "contact-city": "Informe a cidade do atendimento.",
  "requested-items": "Descreva pelo menos um item para a cotação.",
  "project-type": "Selecione o tipo de projeto.",
  deadline: "Informe quando precisa do material.",
  fulfillment: "Selecione retirada ou entrega.",
  consent: "Confirme o uso dos dados para concluir a demonstração.",
};

export function QuoteForm() {
  const formRef = useRef<HTMLFormElement>(null);
  const errorSummaryRef = useRef<HTMLDivElement>(null);
  const { items, updateQuantity, updateNote, removeItem, clearItems } = useQuote();
  const [step, setStep] = useState(1);
  const [submitted, setSubmitted] = useState(false);
  const [fileName, setFileName] = useState("");
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [contact, setContact] = useState<ContactData>({
    profile: "",
    name: "",
    whatsapp: "",
    email: "",
    city: "",
    state: "GO",
  });
  const [need, setNeed] = useState<NeedData>({
    projectType: "",
    deadline: "",
    fulfillment: "",
    requestedItems: "",
    message: "",
  });

  const categoryNames = useMemo(
    () => new Map(categories.map((category) => [category.slug, category.name])),
    [],
  );

  function validateStep(currentStep: number) {
    const container = formRef.current?.querySelector<HTMLElement>(`[data-step="${currentStep}"]`);
    if (!container) return true;
    const required = Array.from(container.querySelectorAll<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>("[required]"));
    const invalid = required.filter((field) => !field.checkValidity());
    if (invalid.length) {
      const nextErrors = Object.fromEntries(
        invalid.map((field) => [field.id, fieldMessages[field.id] ?? field.validationMessage]),
      );
      setErrors(nextErrors);
      requestAnimationFrame(() => errorSummaryRef.current?.focus());
      return false;
    }
    setErrors({});
    return true;
  }

  function clearResolvedError(event: FormEvent<HTMLFormElement>) {
    const field = event.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
    if (!field.id || !errors[field.id] || !field.checkValidity()) return;
    setErrors((current) => {
      const next = { ...current };
      delete next[field.id];
      return next;
    });
  }

  function fieldError(id: string) {
    return errors[id] ? <small className="field-error" id={`${id}-error`}>{errors[id]}</small> : null;
  }

  function goNext() {
    if (!validateStep(step)) return;
    setStep((value) => Math.min(3, value + 1));
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!validateStep(3)) return;
    setSubmitted(true);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  const whatsappSummary = useMemo(() => {
    const itemLines = items.length
      ? items.map((item) => `- ${item.name} — ${item.quantity} ${item.unit}`).join("\n")
      : `- ${need.requestedItems || "Lista enviada em arquivo"}`;
    return encodeURIComponent(
      `Olá, concluí uma lista no protótipo local da Portal.\nPerfil: ${contact.profile || "a informar"}\nCidade: ${contact.city || "a informar"}/${contact.state}\n\nItens:\n${itemLines}\n\nPrazo desejado: ${need.deadline || "a combinar"}`,
    );
  }, [items, need.requestedItems, need.deadline, contact.profile, contact.city, contact.state]);

  if (submitted) {
    return (
      <section className="quote-success" aria-live="polite">
        <p className="eyebrow">Demonstração concluída</p>
        <h2>Sua solicitação ficou organizada.</h2>
        <p>
          Como este ambiente é 100% local, nenhum dado foi enviado. Em uma versão conectada, este seria o ponto de confirmação, protocolo e prazo real de retorno.
        </p>
        <div className="quote-success__summary">
          <strong>{items.length || 1} {items.length === 1 ? "item" : "itens"}</strong>
          <span>{contact.profile}</span>
          <span>{contact.city}/{contact.state}</span>
        </div>
        <div className="button-row">
          <a
            className="button button--whatsapp"
            href={`https://wa.me/556232907222?text=${whatsappSummary}`}
            target="_blank"
            rel="noopener noreferrer"
          >
            Continuar no WhatsApp
          </a>
          <Link className="button button--ghost" href="/produtos">Voltar aos produtos</Link>
        </div>
        <button className="text-button" type="button" onClick={() => { clearItems(); setSubmitted(false); setStep(1); }}>
          Encerrar demonstração e limpar lista
        </button>
      </section>
    );
  }

  return (
    <form ref={formRef} className="quote-workspace" onSubmit={handleSubmit} onInput={clearResolvedError} noValidate>
      <ol className="stepper" aria-label="Etapas do orçamento">
        {["Identificação", "Necessidade", "Revisão"].map((label, index) => {
          const number = index + 1;
          return (
            <li key={label} data-active={step === number} data-complete={step > number}>
              <span>{number}</span>{label}
            </li>
          );
        })}
      </ol>

      <div className="prototype-banner" role="note">
        <strong>Ambiente local.</strong> O formulário demonstra a jornada, mas não envia nem salva dados pessoais.
      </div>

      {Object.keys(errors).length > 0 && (
        <div className="form-error-summary" role="alert" tabIndex={-1} ref={errorSummaryRef} aria-labelledby="form-error-title">
          <h2 id="form-error-title">Revise os campos indicados</h2>
          <p>Há informações necessárias antes de avançar:</p>
          <ul>{Object.entries(errors).map(([id, message]) => <li key={id}><a href={`#${id}`}>{message}</a></li>)}</ul>
        </div>
      )}

      <section className="form-step" data-step="1" hidden={step !== 1}>
        <div className="form-step__heading">
          <p className="eyebrow">Etapa 1 de 3</p>
          <h2>Quem está solicitando?</h2>
          <p>Esses dados serviriam apenas para direcionar o atendimento. Neste protótipo, permanecem na página.</p>
        </div>
        <div className="form-grid">
          <label className="field field--wide">
            <span>Perfil *</span>
            <select id="profile" required aria-invalid={Boolean(errors.profile)} aria-describedby={errors.profile ? "profile-error" : undefined} value={contact.profile} onChange={(event) => setContact({ ...contact, profile: event.target.value })}>
              <option value="">Selecione</option>
              <option value="Pessoa física">Pessoa física</option>
              <option value="Eletricista">Eletricista</option>
              <option value="Construtora">Construtora</option>
              <option value="Indústria">Indústria</option>
              <option value="Revenda / atacado">Revenda / atacado</option>
            </select>
            {fieldError("profile")}
          </label>
          <label className="field">
            <span>Nome *</span>
            <input id="contact-name" required aria-invalid={Boolean(errors["contact-name"])} aria-describedby={errors["contact-name"] ? "contact-name-error" : undefined} autoComplete="name" value={contact.name} onChange={(event) => setContact({ ...contact, name: event.target.value })} />
            {fieldError("contact-name")}
          </label>
          <label className="field">
            <span>WhatsApp *</span>
            <input id="contact-whatsapp" required aria-invalid={Boolean(errors["contact-whatsapp"])} aria-describedby={errors["contact-whatsapp"] ? "contact-whatsapp-error" : undefined} type="tel" inputMode="tel" autoComplete="tel" placeholder="(62) 99999-9999" value={contact.whatsapp} onChange={(event) => setContact({ ...contact, whatsapp: event.target.value })} />
            {fieldError("contact-whatsapp")}
          </label>
          <label className="field">
            <span>E-mail</span>
            <input type="email" autoComplete="email" value={contact.email} onChange={(event) => setContact({ ...contact, email: event.target.value })} />
          </label>
          <label className="field">
            <span>Cidade *</span>
            <input id="contact-city" required aria-invalid={Boolean(errors["contact-city"])} aria-describedby={errors["contact-city"] ? "contact-city-error" : undefined} autoComplete="address-level2" value={contact.city} onChange={(event) => setContact({ ...contact, city: event.target.value })} />
            {fieldError("contact-city")}
          </label>
          <label className="field field--small">
            <span>Estado *</span>
            <select required value={contact.state} onChange={(event) => setContact({ ...contact, state: event.target.value })}>
              <option value="GO">GO</option>
              <option value="TO">TO</option>
              <option value="MG">MG</option>
              <option value="DF">DF</option>
              <option value="Outro">Outro</option>
            </select>
          </label>
        </div>
      </section>

      <section className="form-step" data-step="2" hidden={step !== 2}>
        <div className="form-step__heading">
          <p className="eyebrow">Etapa 2 de 3</p>
          <h2>O que precisa entrar na cotação?</h2>
          <p>A lista abaixo fica salva somente neste navegador. Dados pessoais não entram no armazenamento local.</p>
        </div>

        {items.length ? (
          <div className="quote-items">
            {items.map((item) => (
              <article key={item.id} className="quote-item">
                <div>
                  <span>{categoryNames.get(item.category)}</span>
                  <h3>{item.name}</h3>
                </div>
                <label className="quantity-field">
                  <span>Quantidade</span>
                  <input type="number" min="1" max="999" value={item.quantity} onChange={(event) => updateQuantity(item.id, Number(event.target.value))} />
                  <small>{item.unit}</small>
                </label>
                <label className="field quote-item__note">
                  <span>Observação do item</span>
                  <input value={item.note} onChange={(event) => updateNote(item.id, event.target.value)} placeholder="Cor, marca, aplicação ou detalhe" />
                </label>
                <button className="text-button text-button--danger" type="button" onClick={() => removeItem(item.id)}>Remover</button>
              </article>
            ))}
          </div>
        ) : (
          <label className="field field--wide">
            <span>Descreva os itens *</span>
            <textarea id="requested-items" required aria-invalid={Boolean(errors["requested-items"])} aria-describedby={errors["requested-items"] ? "requested-items-error" : undefined} rows={5} value={need.requestedItems} onChange={(event) => setNeed({ ...need, requestedItems: event.target.value })} placeholder="Ex.: 2 rolos de cabo 2,5 mm², 12 disjuntores 20 A..." />
            {fieldError("requested-items")}
          </label>
        )}

        <div className="form-grid form-grid--spaced">
          <label className="field">
            <span>Tipo de projeto *</span>
            <select id="project-type" required aria-invalid={Boolean(errors["project-type"])} aria-describedby={errors["project-type"] ? "project-type-error" : undefined} value={need.projectType} onChange={(event) => setNeed({ ...need, projectType: event.target.value })}>
              <option value="">Selecione</option>
              <option value="Residencial">Residencial</option>
              <option value="Comercial">Comercial</option>
              <option value="Obra">Obra</option>
              <option value="Industrial">Industrial</option>
              <option value="Revenda">Revenda</option>
            </select>
            {fieldError("project-type")}
          </label>
          <label className="field">
            <span>Quando precisa do material? *</span>
            <input id="deadline" required aria-invalid={Boolean(errors.deadline)} aria-describedby={errors.deadline ? "deadline-error" : undefined} type="date" value={need.deadline} onChange={(event) => setNeed({ ...need, deadline: event.target.value })} />
            {fieldError("deadline")}
          </label>
          <label className="field">
            <span>Retirada ou entrega? *</span>
            <select id="fulfillment" required aria-invalid={Boolean(errors.fulfillment)} aria-describedby={errors.fulfillment ? "fulfillment-error" : undefined} value={need.fulfillment} onChange={(event) => setNeed({ ...need, fulfillment: event.target.value })}>
              <option value="">Selecione</option>
              <option value="Retirada em Goiânia">Retirada em Goiânia</option>
              <option value="Consultar entrega">Consultar entrega</option>
            </select>
            {fieldError("fulfillment")}
          </label>
          <label className="field">
            <span>Anexar lista, foto ou planilha</span>
            <input type="file" accept=".pdf,.xlsx,.xls,.csv,.jpg,.jpeg,.png" onChange={(event) => setFileName(event.target.files?.[0]?.name ?? "")} />
            <small>{fileName ? `Arquivo selecionado: ${fileName}` : "Simulação local · até 10 MB na versão conectada"}</small>
          </label>
          <label className="field field--wide">
            <span>Observações gerais</span>
            <textarea rows={4} value={need.message} onChange={(event) => setNeed({ ...need, message: event.target.value })} placeholder="Etapa da obra, preferências, substituições permitidas..." />
          </label>
        </div>
      </section>

      <section className="form-step" data-step="3" hidden={step !== 3}>
        <div className="form-step__heading">
          <p className="eyebrow">Etapa 3 de 3</p>
          <h2>Revise antes de concluir.</h2>
          <p>Preço, disponibilidade, frete e prazo só devem ser confirmados pela equipe responsável.</p>
        </div>
        <div className="review-grid">
          <div className="review-card">
            <span>Solicitante</span>
            <strong>{contact.name}</strong>
            <p>{contact.profile}<br />{contact.city}/{contact.state}</p>
            <button type="button" onClick={() => setStep(1)}>Editar</button>
          </div>
          <div className="review-card">
            <span>Necessidade</span>
            <strong>{items.length || 1} {items.length === 1 ? "item" : "itens"}</strong>
            <p>{need.projectType}<br />{need.fulfillment}</p>
            <button type="button" onClick={() => setStep(2)}>Editar</button>
          </div>
          <div className="review-card">
            <span>Prazo desejado</span>
            <strong>{need.deadline || "A combinar"}</strong>
            <p>{fileName || "Sem arquivo anexado"}</p>
          </div>
        </div>
        <label className="consent-field">
          <input id="consent" required type="checkbox" aria-invalid={Boolean(errors.consent)} aria-describedby={errors.consent ? "consent-error" : undefined} />
          <span>Li e concordo com o uso dos dados para responder a esta solicitação. Neste protótipo local, nada será transmitido.</span>
          {fieldError("consent")}
        </label>
        <label className="consent-field">
          <input type="checkbox" />
          <span>Quero receber conteúdos e novidades. Consentimento opcional e separado.</span>
        </label>
      </section>

      <div className="form-actions">
        {step > 1 && <button className="button button--ghost" type="button" onClick={() => setStep((value) => value - 1)}>Voltar</button>}
        {step < 3 ? (
          <button className="button button--primary" type="button" onClick={goNext}>Continuar</button>
        ) : (
          <button className="button button--primary" type="submit">Concluir demonstração</button>
        )}
      </div>
    </form>
  );
}
