'use client';

import * as FieldIcons from './Icons';

import { useState } from 'react';
import { AlertIcon, CheckCircleIcon, Spinner, StarIcon } from './Icons';

const RATING_WORDS = ['', 'Poor', 'Fair', 'Good', 'Very good', 'Excellent'];

export function ReviewForm({ lawyerId, lawyerName }: { lawyerId: number; lawyerName: string }) {
  const [open, setOpen] = useState(false);
  const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);
  const [textLen, setTextLen] = useState(0);
  const [state, setState] = useState<'idle' | 'sending' | 'done' | 'error'>('idle');
  const [msg, setMsg] = useState('');

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const fd = new FormData(e.currentTarget);
    const text = String(fd.get('text') ?? '').trim();
    const name = String(fd.get('name') ?? '').trim();
    const email = String(fd.get('email') ?? '').trim();
    const problem = !rating
      ? 'Choose a rating from 1 to 5 stars.'
      : text.length < 20
        ? 'Describe your experience in at least 20 characters.'
        : name.length < 2
          ? 'Enter the name to show with your review.'
          : !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email)
            ? 'Enter a valid email address — it is never shown.'
            : fd.get('engaged') !== 'on'
              ? 'Only clients who worked with this lawyer may review.'
              : null;
    if (problem) {
      setState('error');
      setMsg(problem);
      return;
    }
    setState('sending');
    const res = await fetch(`/api/v1/lawyers/${lawyerId}/reviews/`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ rating, text, authorName: name, authorEmail: email, engagedLawyer: true, website: fd.get('website') || undefined }),
    }).catch(() => null);
    const data = await res?.json().catch(() => ({}));
    if (res?.ok) {
      setState('done');
      setMsg(data?.message ?? 'Thank you — your review will appear once it has been moderated.');
    } else {
      setState('error');
      setMsg(data?.issues?.[0]?.message ?? (res?.status === 429 ? 'Too many reviews from this connection. Try again later.' : res ? 'The review was not sent. Try again.' : 'The connection failed. Try again.'));
    }
  }

  if (!open)
    return (
      <button type="button" className="btn btn-quiet btn-sm" onClick={() => setOpen(true)}>
        <StarIcon className="h-4 w-4 text-brass" /> Review {lawyerName}
      </button>
    );
  if (state === 'done')
    return (
      <p role="status" className="fade-up flex w-full items-start gap-2 rounded-lg border border-ledger/30 bg-ledger-tint px-3 py-2.5 text-sm text-ledger">
        <CheckCircleIcon className="mt-0.5 h-4 w-4" />
        {msg}
      </p>
    );
  const shown = hover || rating;
  return (
    <form onSubmit={onSubmit} noValidate className="card fade-up w-full space-y-4 p-5">
      <fieldset>
        <legend className="field-label">Your rating</legend>
        <div className="flex items-center gap-3" onMouseLeave={() => setHover(0)}>
          <div role="radiogroup" aria-label="Rating" className="flex gap-1">
            {[1, 2, 3, 4, 5].map((n) => (
              <button
                key={n}
                type="button"
                role="radio"
                aria-checked={rating === n}
                aria-label={`${n} star${n > 1 ? 's' : ''} — ${RATING_WORDS[n]}`}
                tabIndex={rating ? (rating === n ? 0 : -1) : n === 1 ? 0 : -1}
                onMouseEnter={() => setHover(n)}
                onClick={() => setRating(n)}
                onKeyDown={(e) => {
                  if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
                    e.preventDefault();
                    setRating(Math.min(5, (rating || 0) + 1));
                  } else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
                    e.preventDefault();
                    setRating(Math.max(1, (rating || 2) - 1));
                  }
                }}
                className={`grid h-10 w-10 place-items-center rounded-lg border transition-all duration-100 hover:scale-110 active:scale-95 ${
                  n <= shown ? 'border-brass/50 bg-brass-soft text-brass' : 'border-rule text-rule-strong hover:text-brass'
                }`}
              >
                <StarIcon className={`h-5 w-5 ${n <= shown ? 'fill-current' : ''}`} />
              </button>
            ))}
          </div>
          <span className="text-sm font-medium text-ink-2">{RATING_WORDS[shown]}</span>
        </div>
      </fieldset>
      <label className="block">
        <span className="field-label"><FieldIcons.FileTextIcon />Your experience</span>
        <textarea name="text" rows={4} required minLength={20} maxLength={2000} className="field" onInput={(e) => setTextLen(e.currentTarget.value.trim().length)} />
        <span className="num mt-1 block text-right text-xs text-muted">{textLen < 20 ? `${20 - textLen} more characters needed` : `${textLen}/2000`}</span>
      </label>
      <div className="grid gap-4 sm:grid-cols-2">
        <label className="block">
          <span className="field-label"><FieldIcons.UserIcon />Name shown</span>
          <input name="name" required maxLength={120} autoComplete="name" className="field" />
        </label>
        <label className="block">
          <span className="field-label">
            Email <span className="font-normal text-muted">(never shown)</span>
          </span>
          <input name="email" type="email" required inputMode="email" autoComplete="email" className="field" />
        </label>
      </div>
      <label className="flex items-center gap-2.5 text-sm text-ink-2">
        <input name="engaged" type="checkbox" required /> I was a client of this lawyer
      </label>
      <input name="website" tabIndex={-1} autoComplete="off" className="hidden" aria-hidden />
      <p className="text-xs leading-relaxed text-muted">Reviews are moderated and shown as unverified until we confirm the engagement. They affect rankings only through the capped reputation score.</p>
      {state === 'error' && (
        <p role="alert" className="flex items-start gap-2 text-sm text-danger">
          <AlertIcon className="mt-0.5 h-4 w-4" />
          {msg}
        </p>
      )}
      <div className="flex flex-wrap gap-2">
        <button className="btn btn-primary btn-sm" disabled={state === 'sending'}>
          {state === 'sending' ? (
            <>
              <Spinner /> Sending…
            </>
          ) : (
            'Submit review'
          )}
        </button>
        <button
          type="button"
          className="btn btn-quiet btn-sm"
          onClick={() => {
            setOpen(false);
            setState('idle');
          }}
        >
          Cancel
        </button>
      </div>
    </form>
  );
}
