'use client';

import { useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import { X } from 'lucide-react';
import type { ProductType, ServiceSummary, AddBookingItemPayload } from '@/types/api';

type FieldsByType =
  | {
      productType: 'rental';
      data: { startsAt: string; endsAt: string; quantity: number; notes?: string };
    }
  | {
      productType: 'sale';
      data: { quantity: number; customizations?: string };
    }
  | {
      productType: 'digital';
      data: { quantity: number; recipientName?: string; recipientPhone?: string; deliverAt?: string };
    };

export type AddToEventSubmission = AddBookingItemPayload;

type VendorAddToEventPanelProps = {
  open: boolean;
  service: Pick<ServiceSummary, 'public_id' | 'name' | 'product_type'>;
  defaultStartsAt?: string | null;
  defaultEndsAt?: string | null;
  defaultRecipientName?: string | null;
  defaultRecipientPhone?: string | null;
  onClose: () => void;
  onSubmit: (payload: AddToEventSubmission) => Promise<void>;
};

export function VendorAddToEventPanel({
  open,
  service,
  defaultStartsAt,
  defaultEndsAt,
  defaultRecipientName,
  defaultRecipientPhone,
  onClose,
  onSubmit,
}: VendorAddToEventPanelProps) {
  const t = useTranslations('vendor.add_to_event');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Per-type state — discriminated by product_type so we never share fields.
  const [rental, setRental] = useState({
    startsAt: defaultStartsAt ?? '',
    endsAt: defaultEndsAt ?? '',
    quantity: 1,
    notes: '',
  });
  const [sale, setSale] = useState({ quantity: 1, customizations: '' });
  const [digital, setDigital] = useState({
    quantity: 1,
    recipientName: defaultRecipientName ?? '',
    recipientPhone: defaultRecipientPhone ?? '',
    deliverAt: '',
  });

  useEffect(() => {
    if (open) setError(null);
  }, [open]);

  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  if (!open) return null;

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError(null);
    setSubmitting(true);
    try {
      const payload = buildPayload(service.public_id, service.product_type, { rental, sale, digital });
      await onSubmit(payload);
    } catch (err) {
      setError(err instanceof Error ? err.message : t('error_generic'));
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-labelledby="add-to-event-title"
      className="fixed inset-0 z-50 flex items-end justify-center md:items-center"
    >
      <button
        type="button"
        aria-label={t('close')}
        className="absolute inset-0 bg-neutral-900/40"
        onClick={onClose}
      />
      <div className="relative w-full max-w-md rounded-t-2xl bg-white p-5 shadow-xl md:rounded-2xl">
        <div className="mb-3 flex items-start justify-between gap-3">
          <div>
            <p className="text-xs uppercase tracking-wide text-neutral-500">
              {t(`panel.title.${service.product_type}` as const)}
            </p>
            <h2 id="add-to-event-title" className="font-heading text-lg font-semibold text-neutral-900">
              {service.name}
            </h2>
          </div>
          <button
            type="button"
            onClick={onClose}
            aria-label={t('close')}
            className="rounded-md p-1 text-neutral-500 hover:bg-neutral-100"
          >
            <X className="h-5 w-5" aria-hidden />
          </button>
        </div>

        <form onSubmit={handleSubmit} className="space-y-4">
          {service.product_type === 'rental' ? (
            <RentalFields
              value={rental}
              onChange={setRental}
              labels={{
                starts: t('fields.event_starts_at'),
                ends: t('fields.event_ends_at'),
                quantity: t('fields.quantity'),
                notes: t('fields.notes_optional'),
              }}
            />
          ) : null}

          {service.product_type === 'sale' ? (
            <SaleFields
              value={sale}
              onChange={setSale}
              labels={{
                quantity: t('fields.quantity'),
                customizations: t('fields.customizations_optional'),
              }}
            />
          ) : null}

          {service.product_type === 'digital' ? (
            <DigitalFields
              value={digital}
              onChange={setDigital}
              labels={{
                quantity: t('fields.quantity'),
                recipientName: t('fields.recipient_name_optional'),
                recipientPhone: t('fields.recipient_phone_optional'),
                deliverAt: t('fields.deliver_at_optional'),
              }}
            />
          ) : null}

          {error ? (
            <p role="alert" className="rounded-md bg-danger/10 p-2 text-xs text-danger">
              {error}
            </p>
          ) : null}

          <button
            type="submit"
            disabled={submitting}
            className="btn-primary w-full"
            data-testid="vendor-add-to-event-submit"
          >
            {submitting ? t('submitting') : t('added_to_cart_cta')}
          </button>
        </form>
      </div>
    </div>
  );
}

function buildPayload(
  servicePublicId: string,
  productType: ProductType,
  state: {
    rental: { startsAt: string; endsAt: string; quantity: number; notes: string };
    sale: { quantity: number; customizations: string };
    digital: { quantity: number; recipientName: string; recipientPhone: string; deliverAt: string };
  },
): AddBookingItemPayload {
  switch (productType) {
    case 'rental':
      return {
        service_id: servicePublicId,
        quantity: state.rental.quantity,
        effective_starts_at: state.rental.startsAt || undefined,
        effective_ends_at: state.rental.endsAt || undefined,
        customization_data: state.rental.notes ? { notes: state.rental.notes } : undefined,
      };
    case 'sale':
      return {
        service_id: servicePublicId,
        quantity: state.sale.quantity,
        customization_data: state.sale.customizations ? { notes: state.sale.customizations } : undefined,
      };
    case 'digital':
      return {
        service_id: servicePublicId,
        quantity: state.digital.quantity,
        effective_starts_at: state.digital.deliverAt || undefined,
        customization_data: {
          ...(state.digital.recipientName ? { recipient_name: state.digital.recipientName } : {}),
          ...(state.digital.recipientPhone ? { recipient_phone_e164: state.digital.recipientPhone } : {}),
        },
      };
  }
}

type RentalLocalState = { startsAt: string; endsAt: string; quantity: number; notes: string };
type SaleLocalState = { quantity: number; customizations: string };
type DigitalLocalState = { quantity: number; recipientName: string; recipientPhone: string; deliverAt: string };

function RentalFields({
  value,
  onChange,
  labels,
}: {
  value: RentalLocalState;
  onChange: (v: RentalLocalState) => void;
  labels: { starts: string; ends: string; quantity: string; notes: string };
}) {
  return (
    <>
      <DateTimeRow label={labels.starts} value={value.startsAt} onChange={(v) => onChange({ ...value, startsAt: v })} />
      <DateTimeRow label={labels.ends} value={value.endsAt} onChange={(v) => onChange({ ...value, endsAt: v })} />
      <NumberRow label={labels.quantity} value={value.quantity} onChange={(v) => onChange({ ...value, quantity: v })} />
      <TextRow label={labels.notes} value={value.notes} onChange={(v) => onChange({ ...value, notes: v })} />
    </>
  );
}

function SaleFields({
  value,
  onChange,
  labels,
}: {
  value: SaleLocalState;
  onChange: (v: SaleLocalState) => void;
  labels: { quantity: string; customizations: string };
}) {
  return (
    <>
      <NumberRow label={labels.quantity} value={value.quantity} onChange={(v) => onChange({ ...value, quantity: v })} />
      <TextRow
        label={labels.customizations}
        value={value.customizations}
        onChange={(v) => onChange({ ...value, customizations: v })}
      />
    </>
  );
}

function DigitalFields({
  value,
  onChange,
  labels,
}: {
  value: DigitalLocalState;
  onChange: (v: DigitalLocalState) => void;
  labels: { quantity: string; recipientName: string; recipientPhone: string; deliverAt: string };
}) {
  return (
    <>
      <NumberRow label={labels.quantity} value={value.quantity} onChange={(v) => onChange({ ...value, quantity: v })} />
      <TextRow
        label={labels.recipientName}
        value={value.recipientName}
        onChange={(v) => onChange({ ...value, recipientName: v })}
      />
      <TextRow
        label={labels.recipientPhone}
        value={value.recipientPhone}
        onChange={(v) => onChange({ ...value, recipientPhone: v })}
        inputProps={{ dir: 'ltr', type: 'tel', inputMode: 'tel' }}
      />
      <DateTimeRow
        label={labels.deliverAt}
        value={value.deliverAt}
        onChange={(v) => onChange({ ...value, deliverAt: v })}
      />
    </>
  );
}

function NumberRow({ label, value, onChange }: { label: string; value: number; onChange: (v: number) => void }) {
  return (
    <label className="flex flex-col gap-1 text-sm">
      <span className="font-medium text-neutral-700">{label}</span>
      <input
        type="number"
        min={1}
        max={999}
        value={value}
        onChange={(e) => onChange(Math.max(1, Number(e.target.value) || 1))}
        className="rounded-md border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-primary-600 focus:ring-2 focus:ring-primary-100"
      />
    </label>
  );
}

function TextRow({
  label,
  value,
  onChange,
  inputProps,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
}) {
  return (
    <label className="flex flex-col gap-1 text-sm">
      <span className="font-medium text-neutral-700">{label}</span>
      <input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="rounded-md border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-primary-600 focus:ring-2 focus:ring-primary-100"
        {...inputProps}
      />
    </label>
  );
}

function DateTimeRow({ label, value, onChange }: { label: string; value: string; onChange: (v: string) => void }) {
  return (
    <label className="flex flex-col gap-1 text-sm">
      <span className="font-medium text-neutral-700">{label}</span>
      <input
        type="datetime-local"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="rounded-md border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-primary-600 focus:ring-2 focus:ring-primary-100"
      />
    </label>
  );
}
