import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ChevronDownIcon } from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../../lib/api';
import type { ApiResponse } from '../../lib/api';
import { PencilIcon, TrashIcon } from '@heroicons/react/24/outline';
import { formatRial, formatDateTime, tomanToRial, rialToToman, todayIso } from '../../lib/utils';
import type { DiscountSuggestion } from '../../types';
import type { SessionCardData } from '../SessionServiceCard';
import SearchableSelect from '../ui/SearchableSelect';
import PersianDateInput from '../ui/PersianDateInput';
import PriceInput from '../ui/PriceInput';
import Modal from '../ui/Modal';
import ConfirmDialog from '../ui/ConfirmDialog';
import { Step2PaymentCard, FilesServiceBalanceWallet, TrashRed } from '../icons/FilesServiceIcons';

/** روش‌های پرداخت — همان چهار گزینه‌ی آکاردئون tauri Step2Payment. */
const METHODS: { key: string; label: string }[] = [
  { key: 'wallet', label: 'پرداخت از طریق کیف پول' },
  { key: 'pos',    label: 'پرداخت از طریق کارت خوان' },
  { key: 'cash',   label: 'پرداخت نقدی' },
  { key: 'card',   label: 'کارت به کارت' },
];
export const METHOD_LABELS: Record<string, string> = {
  wallet: 'پرداخت از کیف پول', pos: 'پرداخت کارتخوان', cash: 'پرداخت نقدی', card: 'کارت به کارت',
};

const todayISO = todayIso;
/** YYYY-MM-DD → unix (ظهر همان روز تا با هر timezone یک روز بماند) */
const isoToUnix = (iso: string) => Math.floor(new Date(`${iso}T12:00:00`).getTime() / 1000);

const fieldLabel: React.CSSProperties = { fontSize: 14, color: 'var(--text-2)', marginBottom: 8, display: 'block' };
const primaryBtn: React.CSSProperties = { background: 'var(--primary)', color: 'var(--on-primary)', border: 'none', borderRadius: 4, height: 46, fontSize: 14, fontWeight: 500, cursor: 'pointer' };
const ghostBtn: React.CSSProperties = { background: 'transparent', color: 'var(--primary)', border: '1px solid var(--primary)', borderRadius: 4, height: 46, fontSize: 14, fontWeight: 500, cursor: 'pointer' };

interface Props {
  recordUuid: string;
  session: SessionCardData;
  walletBalance: number;
  onContinue: () => void;
  onCancel: () => void;
}

/**
 * گام «پرداخت» — پورت tauri Step2Payment با دیتای واقعی:
 * تخفیف تسویه (PATCH /session/{uuid}) + پرداخت چندتکه (POST /session/{uuid}/payments).
 * بین NewSessionPage (ویزارد سه‌گامه) و SessionPaymentPage (دوگامه) مشترک است.
 */
export default function PaymentStep({ recordUuid, session, walletBalance, onContinue, onCancel }: Props) {
  const qc = useQueryClient();
  const sessionUuid = session.uuid;

  const [discountType, setDiscountType] = useState('');
  const [discountValue, setDiscountValue] = useState(0);
  const [paymentDate, setPaymentDate] = useState(todayISO());
  const [expanded, setExpanded] = useState<string | null>(null);
  const [amount, setAmount] = useState(0);

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['patient-sessions', recordUuid] });
    qc.invalidateQueries({ queryKey: ['patient-wallet', recordUuid] });
    qc.invalidateQueries({ queryKey: ['discount-suggestions', sessionUuid] });
  };

  const discountMut = useMutation({
    mutationFn: (body: object) => api.patch(`/api/v1/session/${sessionUuid}`, body),
    onSuccess: () => { invalidate(); toast.success('تخفیف به‌روزرسانی شد'); },
    onError: (e: Error) => toast.error(e.message),
  });

  const payMut = useMutation({
    mutationFn: (body: object) => api.post(`/api/v1/session/${sessionUuid}/payments`, body),
    // بعد از ثبت، آکاردئون بسته می‌شود تا باز شدن بعدی مانده‌ی به‌روزشده را پیش‌فرض بگذارد.
    onSuccess: () => { invalidate(); setAmount(0); setExpanded(null); toast.success('پرداخت ثبت شد'); },
    onError: (e: Error) => toast.error(e.message),
  });

  // ویرایش/حذف پرداخت
  const [editPay, setEditPay] = useState<{ uuid: string; method: string; amountToman: number } | null>(null);
  const [delPayUuid, setDelPayUuid] = useState<string | null>(null);

  const editPayMut = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: object }) => api.patch(`/api/v1/session/${sessionUuid}/payments/${uuid}`, body),
    onSuccess: () => { invalidate(); setEditPay(null); toast.success('پرداخت ویرایش شد'); },
    onError: (e: Error) => toast.error(e.message),
  });
  const delPayMut = useMutation({
    mutationFn: (uuid: string) => api.delete(`/api/v1/session/${sessionUuid}/payments/${uuid}`),
    onSuccess: () => { invalidate(); setDelPayUuid(null); toast.success('پرداخت حذف شد'); },
    onError: (e: Error) => toast.error(e.message),
  });

  const suggestionsQ = useQuery({
    queryKey: ['discount-suggestions', sessionUuid],
    queryFn: () => api.get<ApiResponse<DiscountSuggestion[]>>(`/api/v1/session/${sessionUuid}/discount-suggestions`),
  });
  const suggestions: DiscountSuggestion[] = (suggestionsQ.data?.data as any)?.data ?? (suggestionsQ.data?.data as any) ?? [];

  const applyDiscount = () => {
    if (!discountType || discountValue <= 0) return;
    // percent درصد است (بدون تبدیل)؛ fixed مبلغ تومان است → ریال.
    const value = discountType === 'fixed' ? tomanToRial(discountValue) : discountValue;
    discountMut.mutate({ discount_type: discountType, discount_value: value });
  };
  const applyRule = (ruleUuid: string) => {
    discountMut.mutate({ discount_rule_uuid: ruleUuid });
  };
  const removeDiscount = () => {
    setDiscountType(''); setDiscountValue(0);
    discountMut.mutate({ discount_rule_uuid: null });
  };
  const submitPayment = (method: string) => {
    if (amount <= 0) return;
    payMut.mutate({ method, amount_rials: tomanToRial(amount), paid_at: isoToUnix(paymentDate) });
  };

  const finalPrice = session.final_price_rials ?? 0;
  const discountRials = session.discount_rials ?? 0;
  const payments = session.payments ?? [];
  const appliedRuleLabel = session.applied_discount_rule_label ?? null;
  // تفکیک بیمه و مانده را سرور می‌دهد؛ محاسبه‌ی محلی باعث واگرایی با فاکتور می‌شد.
  const grossTotal = session.gross_total_rials ?? finalPrice;
  const baseInsurance = session.base_insurance_rials ?? 0;
  const suppInsurance = session.supplementary_insurance_rials ?? 0;
  const hasInsurance = baseInsurance > 0 || suppInsurance > 0;
  // همان فرمول سرور (PatientSession::getPayableRials). بازسازی از روی
  // `remaining + paid` غلط بود: سرور remaining را در صفر کلمپ می‌کند، پس در
  // بیش‌پرداخت مبلغ نهایی تا اندازه‌ی پرداختی بالا می‌رفت و اضافه‌پرداخت پنهان می‌شد.
  const payable = Math.max(0, finalPrice - discountRials);
  const debt = session.remaining_rials ?? session.patient_debt_rials ?? 0;

  /**
   * مبلغ پیش‌فرض هنگام باز شدن هر روش پرداخت = مانده‌ی فعلی (تومان).
   * چون `debt` از `remaining_rials` سرور می‌آید، بعد از هر پرداخت جزئی خودش کم می‌شود؛
   * پس در پرداخت چندروشه، روش بعدی باقی‌مانده‌ی درست را پیش‌فرض می‌گیرد.
   * برای کیف پول سقفِ موجودی هم اعمال می‌شود.
   */
  const defaultAmountFor = (method: string) => {
    const cap = method === 'wallet' ? Math.min(debt, walletBalance) : debt;
    return rialToToman(Math.max(0, cap));
  };

  return (
    <>
      {/* هزینه سرویس */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '12px 0 16px' }}>
        <Step2PaymentCard />
        <span style={{ fontSize: 14, color: 'var(--accent)', fontWeight: 700 }}>هزینه سرویس:</span>
        <span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text)' }}>{formatRial(finalPrice)}</span>
      </div>

      {/* تخفیف‌های پیشنهادی (قوانین تخفیف) */}
      {suggestions.length > 0 && (
        <div style={{ border: '1px solid var(--primary-soft2)', background: 'var(--primary-soft)', borderRadius: 8, padding: 12, marginBottom: 16 }}>
          <span style={{ ...fieldLabel, marginBottom: 10, fontWeight: 600, color: 'var(--primary-700)' }}>تخفیف‌های قابل اعمال:</span>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {suggestions.map((s) => (
              <div key={s.rule_uuid} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
                <span style={{ fontSize: 13, color: 'var(--text)' }}>
                  {s.rule_name} — <span style={{ color: 'var(--danger)' }}>{formatRial(s.discount_rials)}</span>
                  {' '}<span style={{ color: 'var(--text-2)', fontSize: 12 }}>({s.discount_type === 'percent' ? `${s.value}٪` : 'مبلغ ثابت'})</span>
                </span>
                <button
                  type="button"
                  onClick={() => applyRule(s.rule_uuid)}
                  disabled={discountMut.isPending}
                  style={{ height: 32, minWidth: 64, border: 'none', borderRadius: 6, background: 'var(--primary)', color: 'var(--on-primary)', fontSize: 12.5, fontWeight: 600, cursor: 'pointer' }}
                >
                  اعمال
                </button>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* تخفیف — port of tauri DiscountInput (نوع + مقدار + ثبت) */}
      <span style={fieldLabel}>تخفیف:</span>
      <div style={{ display: 'flex', alignItems: 'stretch', gap: 8 }}>
        <div className="bg-[var(--surface)]" style={{ flex: 1, minWidth: 0, display: 'flex', alignItems: 'center', border: '1px solid var(--border-2)', borderRadius: 8, marginBottom: 16 }}>
          <div style={{ minWidth: 150, borderLeft: '1px solid var(--border-2)', padding: '0 4px' }}>
            <SearchableSelect
              options={[{ value: 'percent', label: 'درصدی' }, { value: 'fixed', label: 'مبلغ ثابت' }]}
              value={discountType}
              onChange={(v) => setDiscountType(v ? String(v) : '')}
              placeholder="مبلغ تخفیف"
            />
          </div>
          <PriceInput
            latin
            value={discountValue}
            onChange={setDiscountValue}
            placeholder="مقدار تخفیف را وارد نمایید"
            style={{ flex: 1, minWidth: 0, height: 40, padding: '0 12px', fontSize: 13, border: 'none', outline: 'none', background: 'transparent', color: 'inherit' }}
          />
          <button
            type="button"
            onClick={applyDiscount}
            disabled={discountMut.isPending || !discountType || discountValue <= 0}
            style={{ height: 40, minWidth: 72, border: 'none', borderRadius: '0 4px 4px 0', background: 'var(--primary-soft2)', color: 'var(--primary-700)', fontSize: 13, fontWeight: 600, cursor: 'pointer' }}
          >
            ثبت
          </button>
        </div>
        <div
          onClick={removeDiscount}
          style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0, cursor: 'pointer', marginBottom: 16, minWidth: 120, justifyContent: 'center' }}
        >
          <TrashRed color="var(--danger)" size={18} />
          <span style={{ fontSize: 13, color: 'var(--text-2)' }}>حذف تخفیف</span>
        </div>
      </div>

      {/* خلاصه‌ی مبلغ: قبل از تخفیف / تخفیف / نهایی / منبع */}
      <div style={{ border: '1px solid var(--border-2)', borderRadius: 8, padding: 12, marginBottom: 16, display: 'flex', flexDirection: 'column', gap: 6 }}>
        {hasInsurance && (
          <>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
              <span style={{ color: 'var(--text-2)' }}>هزینه کل خدمات:</span>
              <span style={{ color: 'var(--text)' }}>{formatRial(grossTotal)}</span>
            </div>
            {baseInsurance > 0 && (
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
                <span style={{ color: 'var(--text-2)' }}>سهم بیمه پایه:</span>
                <span style={{ color: 'var(--success)' }}>{formatRial(baseInsurance)}</span>
              </div>
            )}
            {suppInsurance > 0 && (
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
                <span style={{ color: 'var(--text-2)' }}>سهم بیمه تکمیلی:</span>
                <span style={{ color: 'var(--success)' }}>{formatRial(suppInsurance)}</span>
              </div>
            )}
          </>
        )}
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
          <span style={{ color: 'var(--text-2)' }}>{hasInsurance ? 'سهم بیمار:' : 'مبلغ قبل از تخفیف:'}</span>
          <span style={{ color: 'var(--text)' }}>{formatRial(finalPrice)}</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
          <span style={{ color: 'var(--text-2)' }}>مبلغ تخفیف{appliedRuleLabel ? ` (${appliedRuleLabel})` : ''}:</span>
          <span style={{ color: 'var(--danger)' }}>{formatRial(discountRials)}</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, fontWeight: 700, borderTop: '1px dashed var(--border-2)', paddingTop: 6 }}>
          <span style={{ color: 'var(--text)' }}>مبلغ نهایی قابل پرداخت:</span>
          <span style={{ color: 'var(--text)' }}>{formatRial(payable)}</span>
        </div>
      </div>

      {/* تاریخ پرداخت */}
      <span style={{ ...fieldLabel, color: 'var(--text)' }}>تاریخ پرداخت</span>
      <PersianDateInput value={paymentDate} onChange={setPaymentDate} />

      {/* روش‌های پرداخت */}
      <span style={{ ...fieldLabel, color: 'var(--text)', marginTop: 24 }}>انتخاب روش های پرداخت:</span>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ display: 'flex', gap: 4 }}>
            <FilesServiceBalanceWallet />
            <span style={{ fontSize: 14, color: 'var(--accent)', marginBottom: 8, fontWeight: 600 }}>موجودی کیف پول:</span>
          </div>
          <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)', marginBottom: 4 }}>{formatRial(walletBalance)}</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
          <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>مبلغ باقی‌مانده:</span>
          <span style={{ fontSize: 14, fontWeight: 700, color: 'var(--danger)' }}>{formatRial(debt)}</span>
        </div>
      </div>

      {/* آکاردئون چهار روش — باز شدن هر روش: مبلغ + ثبت پرداخت */}
      <div style={{ marginTop: 8 }}>
        {METHODS.map((m) => {
          const open = expanded === m.key;
          return (
            <div key={m.key} style={{ borderBottom: '1px solid var(--border-2)' }}>
              <button
                type="button"
                aria-expanded={open}
                onClick={() => { setExpanded(open ? null : m.key); setAmount(open ? 0 : defaultAmountFor(m.key)); }}
                style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%', padding: '14px 4px', background: 'transparent', border: 'none', cursor: 'pointer' }}
              >
                <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>{m.label}</span>
                <ChevronDownIcon style={{ width: 16, color: 'var(--text-2)', transform: open ? 'rotate(180deg)' : undefined, transition: 'transform .15s' }} />
              </button>
              {open && (
                <div style={{ display: 'flex', gap: 8, padding: '0 4px 14px' }}>
                  <PriceInput
                    latin
                    className="input"
                    placeholder="مبلغ (تومان)"
                    value={amount}
                    onChange={setAmount}
                    style={{ flex: 1, height: 40 }}
                  />
                  <button
                    type="button"
                    onClick={() => submitPayment(m.key)}
                    disabled={payMut.isPending || amount <= 0}
                    style={{ ...primaryBtn, height: 40, padding: '0 20px', borderRadius: 8 }}
                  >
                    ثبت پرداخت
                  </button>
                </div>
              )}
            </div>
          );
        })}
      </div>

      {/* پرداخت شده‌ها — باکس خط‌چین tauri */}
      <div style={{ border: '1px dashed var(--primary-soft2)', borderRadius: 8, padding: 16, marginTop: 16, background: 'var(--surface)' }}>
        <span style={{ fontSize: 16, fontWeight: 500, color: 'var(--primary)', display: 'block', marginBottom: 16 }}>پرداخت شده ها:</span>
        {payments.length === 0 ? (
          <span style={{ fontSize: 13, color: 'var(--text-2)' }}>پرداختی ثبت نشده است</span>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {payments.map((p) => (
              <div key={p.uuid} style={{ padding: '6px 0', borderBottom: '1px solid var(--border-2)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--primary)' }} />
                    <span style={{ fontSize: 14, color: 'var(--text)' }}>{METHOD_LABELS[p.method] ?? p.method}</span>
                  </span>
                  <span style={{ flex: 1, textAlign: 'left', fontSize: 14, color: 'var(--text)' }}>مبلغ : {formatRial(p.amount_rials)}</span>
                  {p.method !== 'wallet' && (
                    <span style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                      <button type="button" aria-label="ویرایش پرداخت" onClick={() => setEditPay({ uuid: p.uuid, method: p.method, amountToman: rialToToman(p.amount_rials) })}
                        style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: 'var(--primary)', display: 'flex' }}>
                        <PencilIcon style={{ width: 16 }} />
                      </button>
                      <button type="button" aria-label="حذف پرداخت" onClick={() => setDelPayUuid(p.uuid)}
                        style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: 'var(--danger)', display: 'flex' }}>
                        <TrashIcon style={{ width: 16 }} />
                      </button>
                    </span>
                  )}
                </div>
                <div style={{ display: 'flex', gap: 12, marginTop: 4, fontSize: 12, color: 'var(--text-3)', flexWrap: 'wrap' }}>
                  {(p.paid_at ?? p.created_at) && <span>{formatDateTime(p.paid_at ?? p.created_at!)}</span>}
                  {p.created_by_name && <span>ثبت: {p.created_by_name}</span>}
                </div>
              </div>
            ))}
          </div>
        )}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 8, marginTop: 16 }}>
          <span style={{ fontSize: 14, fontWeight: 500, color: 'var(--text)' }}>مبلغ باقی‌مانده :</span>
          <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--danger)' }}>{formatRial(debt)}</span>
        </div>
      </div>

      {/* ACTIONS */}
      <div style={{ display: 'flex', gap: 8, marginTop: 16, width: '100%', justifyContent: 'flex-end' }}>
        <div style={{ width: '50%', display: 'flex', gap: 4 }}>
          <button type="button" style={{ ...ghostBtn, flex: 1 }} onClick={onCancel}>انصراف</button>
          <button type="button" style={{ ...primaryBtn, flex: 1 }} onClick={onContinue}>ثبت و ادامه</button>
        </div>
      </div>

      {editPay && (
        <Modal open title="ویرایش پرداخت" size="sm" onClose={() => setEditPay(null)}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div>
              <label style={fieldLabel}>روش پرداخت</label>
              <SearchableSelect
                options={METHODS.filter((m) => m.key !== 'wallet').map((m) => ({ value: m.key, label: m.label }))}
                value={editPay.method}
                onChange={(v) => setEditPay((s) => s && { ...s, method: v ? String(v) : s.method })}
                height={40}
              />
            </div>
            <div>
              <label style={fieldLabel}>مبلغ (تومان)</label>
              <PriceInput latin className="cp-input" style={{ width: '100%' }} value={editPay.amountToman} onChange={(v) => setEditPay((s) => s && { ...s, amountToman: v })} />
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <button className="btn ghost sm" onClick={() => setEditPay(null)}>انصراف</button>
              <button className="btn primary sm" disabled={editPayMut.isPending || editPay.amountToman <= 0}
                onClick={() => editPay && editPayMut.mutate({ uuid: editPay.uuid, body: { method: editPay.method, amount_rials: tomanToRial(editPay.amountToman) } })}>
                {editPayMut.isPending ? 'در حال ذخیره...' : 'ذخیره'}
              </button>
            </div>
          </div>
        </Modal>
      )}

      <ConfirmDialog
        open={!!delPayUuid}
        title="حذف پرداخت"
        message="آیا از حذف این پرداخت مطمئن هستید؟ این عملیات در تاریخچه ثبت می‌شود."
        confirmLabel="حذف"
        danger
        loading={delPayMut.isPending}
        onConfirm={() => delPayUuid && delPayMut.mutate(delPayUuid)}
        onCancel={() => setDelPayUuid(null)}
      />
    </>
  );
}
