'use client';

/**
 * PersonalDealActions
 *
 * Inline island rendered per-row on /vendor/personal-deals.
 * Provides:
 *  - Reject: confirm dialog → POST /api/vendor/personal-deals/[id]/reject
 *  - Accept: inline mini-form → POST /api/vendor/personal-deals/[id]/accept
 *    with newDealInput seeded from the source deal.
 */

import { useState } from 'react';
import { Button } from '@/components/ui/primitives/Button/Button';
import { Input } from '@/components/ui/primitives/Input/Input';
import { Label } from '@/components/ui/primitives/Label/Label';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from '@/components/ui/overlays/Dialog';
import { useT } from '@/lib/i18n/react';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { shekelFloatToDecimalString } from '@/lib/money';

export interface PersonalDealSeed {
  /** Source deal title */
  title: string;
  /** Stringified decimal e.g. "149.00" */
  originalPrice: string;
  discountPercent: number;
  discountedPrice: string;
  quantityTotal: number;
  /** ISO datetime string or undefined */
  windowEnd?: string;
  dealType: string;
  description?: string;
  categoryId?: string;
}

interface PersonalDealActionsProps {
  requestId: string;
  seed: PersonalDealSeed;
  disabled?: boolean;
}

function computeDiscountedPrice(orig: string, disc: string): string | null {
  const origNum = parseFloat(orig);
  const discNum = parseInt(disc, 10);
  if (isNaN(origNum) || isNaN(discNum)) return null;
  const raw = origNum * (1 - discNum / 100);
  const value = Math.max(3, Math.round(raw * 100) / 100);
  return shekelFloatToDecimalString(value);
}

function mapApiError(
  message: string,
  t: (key: 'error_min_price' | 'error_request_expired' | 'error_generic') => string,
): string {
  if (message === 'Deal price after discount must be at least ₪3') {
    return t('error_min_price');
  }
  if (message === 'Response deadline has passed') {
    return t('error_request_expired');
  }
  if (message.startsWith('HTTP')) {
    return t('error_generic');
  }
  return t('error_generic');
}

export function PersonalDealActions({
  requestId,
  seed,
  disabled = false,
}: PersonalDealActionsProps) {
  const t = useT('vendor_personal_deals');

  // ── Accept state ─────────────────────────────────────────────────────────
  const [showAccept, setShowAccept] = useState(false);
  const [title, setTitle] = useState(seed.title);
  const [originalPrice, setOriginalPrice] = useState(seed.originalPrice);
  const [discountPercent, setDiscountPercent] = useState(String(seed.discountPercent));
  const [discountedPrice, setDiscountedPrice] = useState(
    () =>
      computeDiscountedPrice(seed.originalPrice, String(seed.discountPercent)) ??
      seed.discountedPrice,
  );
  const [quantityTotal, setQuantityTotal] = useState('1');
  const [windowEnd, setWindowEnd] = useState(seed.windowEnd ? seed.windowEnd.slice(0, 16) : '');
  const [acceptBusy, setAcceptBusy] = useState(false);
  const [acceptError, setAcceptError] = useState<string | null>(null);
  const [acceptSuccess, setAcceptSuccess] = useState(false);

  // ── Reject state ─────────────────────────────────────────────────────────
  const [showReject, setShowReject] = useState(false);
  const [rejectBusy, setRejectBusy] = useState(false);
  const [rejectError, setRejectError] = useState<string | null>(null);
  const [rejectSuccess, setRejectSuccess] = useState(false);
  const actionDisabled = disabled || acceptBusy || rejectBusy;

  // ── Helpers ───────────────────────────────────────────────────────────────
  function buildHeaders(): Record<string, string> {
    const headers: Record<string, string> = { 'content-type': 'application/json' };
    const csrf = getCsrfToken();
    if (csrf) headers['x-csrf-token'] = csrf;
    return headers;
  }

  async function handleAccept() {
    setAcceptBusy(true);
    setAcceptError(null);
    try {
      const origNum = parseFloat(originalPrice);
      const discNum = parseInt(discountPercent, 10);
      const discountedNum = parseFloat(discountedPrice);
      const qtyNum = parseInt(quantityTotal, 10);

      // Guard against NaN from empty or non-numeric inputs before reaching fetch.
      if (isNaN(origNum) || isNaN(discNum) || isNaN(discountedNum) || isNaN(qtyNum)) {
        setAcceptError(t('error_generic'));
        return;
      }

      let windowEndIso: string | undefined;
      if (windowEnd) {
        const d = new Date(windowEnd);
        if (!isNaN(d.getTime())) windowEndIso = d.toISOString();
      }

      // Personal deals are always DELIVERY-only.
      // COUPON deals require pickupStart/pickupEnd when delivery is not DELIVERY,
      // and this form does not expose pickup hours. Force DELIVERY to satisfy
      // createDealBodySchema's superRefine constraint.
      //
      // The following fields are intentionally locked for personal deals and
      // not exposed in this form: tagIds (always []), isVoucher (always false),
      // delivery (always DELIVERY), description and categoryId (seeded from
      // source deal and not editable).
      const newDealInput = {
        dealType: seed.dealType,
        title: title.trim(),
        description: seed.description ?? '',
        categoryId: seed.categoryId,
        tagIds: [] as string[],
        isVoucher: false,
        originalPrice: shekelFloatToDecimalString(origNum),
        discountPercent: discNum,
        discountedPrice: shekelFloatToDecimalString(discountedNum),
        quantityTotal: qtyNum,
        windowEnd: windowEndIso,
        delivery: 'DELIVERY' as const,
      };

      const res = await fetch(`/api/vendor/personal-deals/${requestId}/accept`, {
        method: 'POST',
        headers: buildHeaders(),
        body: JSON.stringify({ newDealInput }),
        credentials: 'same-origin',
      });
      if (!res.ok) {
        const j = await res.json().catch((err) => {
          captureCaught(err, {
            scope: 'features.vendor-personal-deals.PersonalDealActions.accept',
          });
          return {};
        });
        throw new Error((j as { error?: string }).error ?? `HTTP ${res.status}`);
      }
      setAcceptSuccess(true);
      setTimeout(() => {
        location.reload();
      }, 1200);
    } catch (e) {
      setAcceptError(e instanceof Error ? mapApiError(e.message, t) : t('error_generic'));
    } finally {
      setAcceptBusy(false);
    }
  }

  async function handleReject() {
    setRejectBusy(true);
    setRejectError(null);
    try {
      const res = await fetch(`/api/vendor/personal-deals/${requestId}/reject`, {
        method: 'POST',
        headers: buildHeaders(),
        body: JSON.stringify({}),
        credentials: 'same-origin',
      });
      if (!res.ok) {
        const j = await res.json().catch((err) => {
          captureCaught(err, {
            scope: 'features.vendor-personal-deals.PersonalDealActions.reject',
          });
          return {};
        });
        throw new Error((j as { error?: string }).error ?? `HTTP ${res.status}`);
      }
      setRejectSuccess(true);
      setTimeout(() => {
        location.reload();
      }, 1200);
    } catch (e) {
      setRejectError(e instanceof Error ? mapApiError(e.message, t) : t('error_generic'));
    } finally {
      setRejectBusy(false);
    }
  }

  return (
    <div className="flex flex-wrap items-center gap-2">
      {/* ── Accept ── */}
      <Button
        size="sm"
        variant="primary"
        aria-label={`${t('accept_btn_aria_prefix')} ${requestId.slice(0, 8)}`}
        onClick={() => {
          const computed = computeDiscountedPrice(originalPrice, discountPercent);
          if (computed !== null) setDiscountedPrice(computed);
          setAcceptError(null);
          setAcceptSuccess(false);
          setShowAccept(true);
        }}
        disabled={actionDisabled}
      >
        {t('accept_btn')}
      </Button>

      <Dialog
        open={showAccept}
        onOpenChange={(open) => {
          if (!acceptBusy) setShowAccept(open);
        }}
      >
        <DialogContent aria-labelledby="accept-dialog-title" aria-describedby={undefined}>
          <DialogHeader>
            <DialogTitle id="accept-dialog-title">{t('accept_dialog_title')}</DialogTitle>
            <DialogDescription>{t('accept_dialog_intro')}</DialogDescription>
          </DialogHeader>

          <p className="text-text-muted text-sm">{t('delivery_notice')}</p>
          <p className="text-text-muted text-sm">{t('seeded_content_notice')}</p>

          <form
            className="space-y-4 py-2"
            aria-labelledby="accept-dialog-title"
            onSubmit={(e) => {
              e.preventDefault();
              void handleAccept();
            }}
          >
            <div className="space-y-1">
              <Label htmlFor="pd-title" className="text-text-secondary">
                {t('accept_form_title_label')}
              </Label>
              <Input
                id="pd-title"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                required
                maxLength={120}
              />
            </div>

            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1">
                <Label htmlFor="pd-orig-price" className="text-text-secondary">
                  {t('accept_form_price_label')}
                </Label>
                <Input
                  id="pd-orig-price"
                  type="number"
                  min="1"
                  step="0.01"
                  value={originalPrice}
                  onChange={(e) => {
                    const next = e.target.value;
                    setOriginalPrice(next);
                    const computed = computeDiscountedPrice(next, discountPercent);
                    if (computed !== null) setDiscountedPrice(computed);
                  }}
                  required
                />
              </div>

              <div className="space-y-1">
                <Label htmlFor="pd-discount" className="text-text-secondary">
                  {t('accept_form_discount_label')}
                </Label>
                <Input
                  id="pd-discount"
                  type="number"
                  min="50"
                  max="99"
                  step="1"
                  value={discountPercent}
                  onChange={(e) => {
                    const next = e.target.value;
                    setDiscountPercent(next);
                    const computed = computeDiscountedPrice(originalPrice, next);
                    if (computed !== null) setDiscountedPrice(computed);
                  }}
                  required
                />
                <p className="text-text-muted text-xs">{t('accept_form_discount_hint')}</p>
              </div>
            </div>

            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1">
                <Label htmlFor="pd-discounted-price" className="text-text-secondary">
                  {t('accept_form_discounted_label')}
                </Label>
                <Input
                  id="pd-discounted-price"
                  type="number"
                  min="3"
                  step="0.01"
                  value={discountedPrice}
                  readOnly
                  aria-readonly="true"
                  className="bg-surface-inset text-text-muted"
                  required
                />
              </div>

              <div className="space-y-1">
                <Label htmlFor="pd-qty" className="text-text-secondary">
                  {t('accept_form_qty_label')}
                </Label>
                <Input
                  id="pd-qty"
                  type="number"
                  min="1"
                  max="10000"
                  step="1"
                  value={quantityTotal}
                  onChange={(e) => setQuantityTotal(e.target.value)}
                  required
                />
                <p className="text-text-muted text-xs">{t('accept_form_qty_hint')}</p>
              </div>
            </div>

            <div className="space-y-1">
              <Label
                htmlFor="pd-window-end"
                className="text-text-secondary"
                title={t('accept_form_window_end_tooltip')}
              >
                {t('accept_form_window_end_label')}
              </Label>
              <Input
                id="pd-window-end"
                type="datetime-local"
                value={windowEnd}
                onChange={(e) => setWindowEnd(e.target.value)}
                aria-describedby="pd-window-end-hint"
              />
              <p id="pd-window-end-hint" className="text-text-muted text-xs">
                {t('accept_form_window_end_hint')}
              </p>
            </div>

            {acceptError && (
              <p role="alert" className="text-feedback-error text-sm">
                {acceptError}
              </p>
            )}

            {acceptSuccess && (
              <p role="status" className="text-feedback-success text-sm font-medium">
                {t('success_accepted')}
              </p>
            )}

            <DialogFooter>
              <Button
                type="button"
                variant="ghost"
                onClick={() => setShowAccept(false)}
                disabled={acceptBusy}
              >
                {t('reject_cancel')}
              </Button>
              <Button type="submit" variant="primary" disabled={acceptBusy}>
                {acceptBusy ? t('accept_submitting') : t('accept_submit_btn')}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      {/* ── Reject ── */}
      <Button
        size="sm"
        variant="secondary"
        aria-label={`${t('reject_btn_aria_prefix')} ${requestId.slice(0, 8)}`}
        onClick={() => {
          setRejectError(null);
          setRejectSuccess(false);
          setShowReject(true);
        }}
        disabled={actionDisabled}
      >
        {t('reject_btn')}
      </Button>

      <Dialog
        open={showReject}
        onOpenChange={(open) => {
          if (!rejectBusy) setShowReject(open);
        }}
      >
        <DialogContent
          role="alertdialog"
          aria-labelledby="reject-dialog-title"
          aria-describedby="reject-dialog-desc"
        >
          <DialogHeader>
            <DialogTitle id="reject-dialog-title">{t('reject_confirm')}</DialogTitle>
          </DialogHeader>
          <DialogDescription id="reject-dialog-desc" className="py-2">
            {t('reject_confirm_desc')}
          </DialogDescription>

          {rejectError && (
            <p role="alert" className="text-feedback-error text-sm">
              {rejectError}
            </p>
          )}

          {rejectSuccess && (
            <p role="status" className="text-feedback-success text-sm font-medium">
              {t('success_rejected')}
            </p>
          )}

          <DialogFooter>
            <Button
              type="button"
              variant="ghost"
              onClick={() => setShowReject(false)}
              disabled={rejectBusy}
            >
              {t('reject_cancel')}
            </Button>
            <Button
              type="button"
              variant="danger"
              onClick={() => void handleReject()}
              disabled={rejectBusy}
            >
              {rejectBusy ? t('rejecting') : t('reject_confirm_btn')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
