'use client';

/**
 * NewTicket — customer form to open a support ticket.
 *
 * Composed entirely from @/components/ui/** per Hard Rule §1.
 * On success, navigates to the new ticket detail page.
 */

import { useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { interpolate } from '@/lib/i18n/interpolate';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { FormField } from '@/components/ui/primitives/FormField';
import { Input } from '@/components/ui/primitives/Input';
import { Textarea } from '@/components/ui/primitives/Textarea';
import { Button } from '@/components/ui/primitives/Button';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { CategoryPicker } from '@/components/ui/domain/support/CategoryPicker';
import type { TicketCategory } from '@/components/ui/domain/support/CategoryPicker';
import { ErrorBoundary } from '@/components/ui/feedback/ErrorBoundary';
import { captureCaught } from '@/lib/observability';

type Priority = 'low' | 'normal' | 'high' | 'urgent';

export interface NewTicketProps {
  /** Current locale — injected from Astro locals. */
  locale?: 'he' | 'en';
  /** CSRF token from Astro locals. */
  csrfToken?: string;
  /** Prefill a related purchase id (from purchase detail page CTA). */
  relatedPurchaseId?: string;
  /** Route to a specific support agent definition (from entry-point CTAs). */
  agentDefinitionSlug?: string;
}

function NewTicketInner({ csrfToken, relatedPurchaseId, agentDefinitionSlug }: NewTicketProps) {
  const t = useT('support');
  const tkt = t('ticket') as unknown as Record<string, string>;

  const [category, setCategory] = useState<TicketCategory | undefined>(undefined);
  const priority: Priority = 'normal';
  const [subject, setSubject] = useState('');
  const [body, setBody] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [showValidation, setShowValidation] = useState(false);

  const isValid =
    category !== undefined &&
    subject.trim().length >= 3 &&
    subject.trim().length <= 200 &&
    body.trim().length >= 10;

  const validationErrors: string[] = [];
  if (showValidation) {
    if (category === undefined) validationErrors.push(tkt.validation_category_required ?? '');
    if (subject.trim().length < 3) validationErrors.push(tkt.validation_subject_min ?? '');
    if (subject.trim().length > 200) validationErrors.push(tkt.validation_subject_max ?? '');
    if (body.trim().length < 10) validationErrors.push(tkt.validation_body_min ?? '');
  }

  async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    setShowValidation(true);
    if (!isValid || submitting) return;

    setSubmitting(true);
    setError(null);

    try {
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      if (csrfToken) headers['x-csrf-token'] = csrfToken;

      const res = await fetch('/api/support/tickets', {
        method: 'POST',
        headers,
        body: JSON.stringify({
          category,
          priority,
          subject: subject.trim(),
          body: body.trim(),
          ...(relatedPurchaseId ? { relatedPurchaseId } : {}),
          ...(agentDefinitionSlug ? { agentDefinitionSlug } : {}),
          attachmentIds: [],
        }),
      });

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

      if (!json.ok) {
        if (res.status === 429) {
          setError(tkt.error_rate_limited ?? '');
        } else {
          setError(tkt.error_generic ?? '');
        }
        return;
      }

      if (json.ticketId) {
        window.location.href = `/support/tickets/${json.ticketId}`;
      }
    } catch (err) {
      captureCaught(err, { scope: 'features.support-tickets.NewTicket', severity: 'warning' });
      setError(tkt.error_generic ?? '');
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <ErrorBoundary>
      <div className="flex flex-col gap-6 px-4 pb-8">
        <PageHeader title={tkt.new_title ?? ''} subtitle={tkt.new_subtitle} />

        {relatedPurchaseId && (
          <InlineNotice
            tone="info"
            description={interpolate(tkt.related_purchase_hint ?? '', {
              purchaseId: relatedPurchaseId.slice(0, 8),
            })}
          />
        )}

        <form onSubmit={handleSubmit} className="flex flex-col gap-5" noValidate>
          {error && <InlineNotice tone="danger" description={error} />}
          {validationErrors.length > 0 && (
            <div role="alert" className="flex flex-col gap-1">
              {validationErrors.map((msg) => (
                <InlineNotice key={msg} tone="danger" description={msg} />
              ))}
            </div>
          )}

          <FormField label={tkt.category_label ?? ''} required htmlFor="ticket-category">
            <CategoryPicker value={category} onChange={setCategory} disabled={submitting} />
          </FormField>

          <FormField label={tkt.subject_label ?? ''} required htmlFor="ticket-subject">
            <Input
              id="ticket-subject"
              type="text"
              placeholder={tkt.subject_placeholder ?? ''}
              value={subject}
              onChange={(e) => setSubject(e.target.value)}
              maxLength={200}
              disabled={submitting}
            />
            <p className="text-text-muted mt-1 text-end text-xs">
              {interpolate(tkt.subject_char_count ?? '{current} / {max}', {
                current: subject.length,
                max: 200,
              })}
            </p>
          </FormField>

          <FormField label={tkt.body_label ?? ''} required htmlFor="ticket-body">
            <Textarea
              id="ticket-body"
              placeholder={tkt.body_placeholder ?? ''}
              value={body}
              onChange={(e) => setBody(e.target.value)}
              rows={6}
              maxLength={5000}
              disabled={submitting}
            />
            <p className="text-text-muted mt-1 text-end text-xs">
              {interpolate(tkt.body_char_count ?? '{current} / {max}', {
                current: body.length,
                max: 5000,
              })}
            </p>
          </FormField>

          {tkt.attachments_hint && <InlineNotice tone="info" description={tkt.attachments_hint} />}

          {!isValid && !submitting && (
            <p className="text-text-secondary text-sm">{tkt.submit_disabled_hint ?? ''}</p>
          )}

          <div className="flex items-center justify-end gap-3">
            <Button
              type="button"
              variant="ghost"
              disabled={submitting}
              onClick={() => window.history.back()}
            >
              {tkt.cancel}
            </Button>
            <Button type="submit" variant="primary" loading={submitting} disabled={!isValid}>
              {submitting ? tkt.submit_pending : tkt.submit}
            </Button>
          </div>
        </form>
      </div>
    </ErrorBoundary>
  );
}

export function NewTicket({ locale, ...props }: NewTicketProps) {
  return (
    <HydratedIsland locale={locale}>
      <NewTicketInner {...props} />
    </HydratedIsland>
  );
}
