'use client';

import { useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { captureCaught } from '@/lib/observability/capture';
import { getCsrfToken } from '@/lib/csrf';
import { Input } from '@/components/ui/primitives/Input/Input';
import { Button } from '@/components/ui/primitives/Button/Button';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice/InlineNotice';
import { type PromoFunder } from '@/lib/enums/promo-funder';
import { formatAgorotShekels } from '@/lib/money.js';

// ─── Types ────────────────────────────────────────────────────────────────────

export type PromoApplied = {
  code: string;
  totalDiscountAgorot: number;
  perVendor: {
    vendorId: string;
    dealIds: string[];
    discountAgorot: number;
    funder: PromoFunder;
  }[];
};

interface Props {
  applied: PromoApplied | null;
  onApplied: (p: PromoApplied | null) => void;
}

// defineApi spreads result.data into the top-level body:
// POST /api/checkout/promo/apply returns { ok: true, totalDiscountAgorot, perVendor, kind } — no 'data' wrapper.
type ApplyResponse = {
  ok: boolean;
  code?: string;
  reason?: string;
  totalDiscountAgorot?: number;
  perVendor?: PromoApplied['perVendor'];
};

// ─── Component ────────────────────────────────────────────────────────────────

export function PromoCodeInput({ applied, onApplied }: Props) {
  const t = useT('promo_codes');
  const errorsMap = t('errors') as unknown as Record<string, string>;

  const [code, setCode] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  function getErrorMessage(key: string): string {
    return errorsMap[key] ?? errorsMap['NOT_FOUND'] ?? key;
  }

  async function submit() {
    const trimmed = code.trim();
    if (!trimmed) return;
    setBusy(true);
    setError(null);
    try {
      const res = await fetch('/api/checkout/promo/apply', {
        method: 'POST',
        headers: { 'content-type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify({ code: trimmed }),
      });
      const json = (await res.json()) as ApplyResponse;
      if (!res.ok || !json.ok) {
        setError(getErrorMessage(json.code ?? json.reason ?? 'NOT_FOUND'));
        return;
      }
      if (!json.totalDiscountAgorot || !json.perVendor) {
        setError(getErrorMessage(json.reason ?? 'NOT_FOUND'));
        return;
      }
      onApplied({
        code: trimmed,
        totalDiscountAgorot: json.totalDiscountAgorot,
        perVendor: json.perVendor,
      });
    } catch (e) {
      captureCaught(e, { scope: 'features.checkout.PromoCodeInput.apply', severity: 'warning' });
      setError(getErrorMessage('NOT_FOUND'));
    } finally {
      setBusy(false);
    }
  }

  function remove() {
    onApplied(null);
    setCode('');
    setError(null);
  }

  function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter') {
      void submit();
    }
  }

  // ── Applied state ─────────────────────────────────────────────────────────

  if (applied) {
    const summaryTemplate = t('applied_summary');
    const summaryText = String(summaryTemplate).replace(
      '{{amount}}',
      formatAgorotShekels(applied.totalDiscountAgorot),
    );
    return (
      <div className="flex items-center justify-between gap-2 py-2 ps-2 pe-2">
        <span className="text-success-700 text-sm font-medium">{summaryText}</span>
        <Button variant="ghost" size="sm" onClick={remove}>
          {String(t('remove_button'))}
        </Button>
      </div>
    );
  }

  // ── Input state ───────────────────────────────────────────────────────────

  return (
    <div className="flex flex-col gap-2 py-2 ps-2 pe-2">
      <label htmlFor="promo-code-input" className="text-text-secondary text-sm">
        {String(t('input_label'))}
      </label>
      <div className="flex gap-2">
        <Input
          id="promo-code-input"
          value={code}
          onChange={(e) => setCode(e.target.value)}
          onKeyDown={handleKeyDown}
          placeholder={String(t('input_placeholder'))}
          aria-label={String(t('input_label'))}
          disabled={busy}
          autoComplete="off"
          autoCapitalize="characters"
        />
        <Button
          variant="secondary"
          size="md"
          onClick={() => void submit()}
          disabled={busy || !code.trim()}
        >
          {busy ? String(t('loading')) : String(t('apply_button'))}
        </Button>
      </div>
      {error && <InlineNotice tone="danger" description={error} />}
    </div>
  );
}
