import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useNavigate, useSearchParams } from 'react-router';
import { ArrowPathIcon } from '@heroicons/react/24/outline';
import { api } from '../lib/api';
import { formatRial, formatNumber, toGregorianDate, todayIso } from '../lib/utils';
import type { ClaimPatientRow } from '../types';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import PageHeader from '../components/ui/PageHeader';
import DataTable, { type Column } from '../components/ui/DataTable';
import StatCard from '../components/ui/StatCard';
import StatusBadge from '../components/ui/StatusBadge';
import SearchableSelect from '../components/ui/SearchableSelect';
import PersianDatePicker from '../components/ui/PersianDatePicker';
import FeatureGate from '../components/ui/FeatureGate';
import Pagination from '../components/ui/Pagination';

const LIMIT = 20;

const STATUS_OPTIONS = [
  { value: '', label: 'همه وضعیت‌ها' },
  { value: 'pending', label: 'در انتظار ارسال' },
  { value: 'submitted', label: 'ارسال شده' },
  { value: 'approved', label: 'تأیید شده' },
  { value: 'rejected', label: 'رد شده' },
  { value: 'paid', label: 'پرداخت شده' },
];

const PAYMENT_OPTIONS = [
  { value: '', label: 'همه' },
  { value: 'paid', label: 'وصول‌شده' },
  { value: 'unpaid', label: 'وصول‌نشده' },
];

/** واژگان مطالبه `base` است، نه `basic` که در قرارداد بیمه به کار می‌رود. */
const KIND_OPTIONS = [
  { value: '', label: 'همه انواع' },
  { value: 'base', label: 'پایه' },
  { value: 'supplementary', label: 'تکمیلی' },
];

const KIND_LABEL: Record<string, string> = { base: 'پایه', supplementary: 'تکمیلی' };

const isoNDaysAgo = (days: number): string => {
  const d = new Date();
  d.setDate(d.getDate() - days);
  return toGregorianDate(d);
};

const toUnix = (iso: string): number | null => {
  if (!iso) return null;
  const t = new Date(iso + 'T00:00:00').getTime();
  return Number.isNaN(t) ? null : Math.floor(t / 1000);
};
const endOfDayUnix = (iso: string): number | null => {
  if (!iso) return null;
  const t = new Date(iso + 'T23:59:59').getTime();
  return Number.isNaN(t) ? null : Math.floor(t / 1000);
};

interface DebtRow {
  insurance_id: number;
  insurance_name: string | null;
  claimed: number;
  approved: number;
  paid: number;
  debt: number;
}

/**
 * داشبورد پرونده‌های بیمه — سطح اول: یک ردیف به‌ازای هر بیمار.
 * فیلترها در query string زندگی می‌کنند تا رفرش و اشتراک لینک، نما را حفظ کند.
 */
export default function ClaimsPage() {
  const navigate = useNavigate();
  const [params, setParams] = useSearchParams();

  const search = params.get('search') ?? '';
  const status = params.get('status') ?? '';
  const insuranceId = params.get('insurance_id') ?? '';
  const kind = params.get('kind') ?? '';
  const paymentStatus = params.get('payment_status') ?? '';
  const from = params.get('from') ?? '';
  const to = params.get('to') ?? '';
  const page = Math.max(1, Number(params.get('page') ?? 1));
  const sort = params.get('sort') ?? 'last_activity_at';
  const dir = (params.get('dir') ?? 'desc') as 'asc' | 'desc';

  const hasFilters = !!(search || status || insuranceId || kind || paymentStatus || from || to);

  /** تغییر فیلتر همیشه به صفحه‌ی اول برمی‌گردد؛ ماندن روی صفحه ۵ با نتیجه‌ی جدید بی‌معناست. */
  const setParam = (patch: Record<string, string>) => {
    const next = new URLSearchParams(params);
    Object.entries(patch).forEach(([k, v]) => (v ? next.set(k, v) : next.delete(k)));
    if (!('page' in patch)) next.delete('page');
    setParams(next, { replace: true });
  };

  const queryString = useMemo(() => {
    const qs = new URLSearchParams();
    qs.set('page', String(page));
    qs.set('limit', String(LIMIT));
    qs.set('sort', sort);
    qs.set('dir', dir);
    if (search) qs.set('search', search);
    if (status) qs.set('status', status);
    if (insuranceId) qs.set('insurance_id', insuranceId);
    if (kind) qs.set('kind', kind);
    if (paymentStatus) qs.set('payment_status', paymentStatus);
    const fromUnix = toUnix(from);
    const toUnixVal = endOfDayUnix(to);
    if (fromUnix) qs.set('from', String(fromUnix));
    if (toUnixVal) qs.set('to', String(toUnixVal));
    return qs.toString();
  }, [page, sort, dir, search, status, insuranceId, kind, paymentStatus, from, to]);

  const listQuery = useQuery<PaginatedResponse<ClaimPatientRow>>({
    queryKey: ['claims-by-patient', queryString],
    queryFn: () => api.get(`/api/v1/billing/claims/by-patient?${queryString}`),
  });

  // یک fetch برای هر دو مصرف: کارت‌های آمار و گزینه‌های فیلتر بیمه.
  const debtQuery = useQuery<ApiResponse<{ data: DebtRow[] }>>({
    queryKey: ['insurance-debt'],
    queryFn: () => api.get('/api/v1/billing/reports/insurance-debt'),
  });

  const rows = listQuery.data?.data ?? [];
  const total = listQuery.data?.meta?.totalRecords ?? 0;
  const debt: DebtRow[] = debtQuery.data?.data?.data ?? [];

  const totals = useMemo(
    () => debt.reduce(
      (acc, d) => ({
        claimed: acc.claimed + d.claimed,
        paid: acc.paid + d.paid,
        debt: acc.debt + d.debt,
      }),
      { claimed: 0, paid: 0, debt: 0 },
    ),
    [debt],
  );

  const insuranceOptions = useMemo(
    () => [
      { value: '', label: 'همه بیمه‌ها' },
      ...debt.map((d) => ({ value: String(d.insurance_id), label: d.insurance_name ?? `بیمه #${d.insurance_id}` })),
    ],
    [debt],
  );

  const columns: Column<ClaimPatientRow>[] = [
    { key: 'full_name', header: 'بیمار', sortable: true, render: (r) => r.full_name ?? '—' },
    { key: 'mobile', header: 'موبایل', render: (r) => r.mobile ?? '—' },
    { key: 'national_code', header: 'کد ملی', render: (r) => r.national_code ?? '—' },
    {
      key: 'insurances',
      header: 'بیمه',
      render: (r) => (
        (r.insurances ?? []).length === 0 ? '—' : (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
            {r.insurances.map((i) => (
              <span
                key={`${i.insurance_id}-${i.kind}`}
                className={`badge ${i.kind === 'supplementary' ? 'violet' : 'blue'}`}
                title={KIND_LABEL[i.kind ?? ''] ?? i.kind ?? ''}
              >
                {i.insurance_name ?? `بیمه #${i.insurance_id}`}
              </span>
            ))}
          </div>
        )
      ),
    },
    { key: 'claims_count', header: 'تعداد درخواست', sortable: true, render: (r) => formatNumber(r.claims_count) },
    { key: 'total_services_rials', header: 'مجموع خدمات', sortable: true, render: (r) => formatRial(r.total_services_rials) },
    { key: 'total_insurance_rials', header: 'سهم بیمه', sortable: true, render: (r) => formatRial(r.total_insurance_rials) },
    { key: 'total_patient_rials', header: 'سهم بیمار', render: (r) => formatRial(r.total_patient_rials) },
    { key: 'overall_status', header: 'وضعیت کلی', render: (r) => <StatusBadge type="claim" value={r.overall_status} /> },
  ];

  return (
    <FeatureGate feature="insurance">
      <PageHeader
        title="پرونده‌های بیمه"
        tourId="claims"
        description="پیگیری مطالبات بیمه به تفکیک بیمار"
        breadcrumbs={[{ label: 'داشبورد', to: '/admin' }, { label: 'پرونده‌های بیمه' }]}
      />

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 'var(--gap)', marginBottom: 'var(--gap)' }}>
        <StatCard tone="violet" label="مجموع ادعای بیمه" value={formatRial(totals.claimed)} />
        <StatCard tone="green" label="وصول‌شده" value={formatRial(totals.paid)} />
        <StatCard tone="pink" label="مانده وصول‌نشده" value={formatRial(totals.debt)} />
        <StatCard tone="amber" label="تعداد بیماران" value={formatNumber(total)} />
      </div>

      <div className="card" style={{ padding: 18 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'flex-end', marginBottom: 16 }}>
          <div style={{ minWidth: 150 }}>
            <label className="field-label">بیمه</label>
            <SearchableSelect
              options={insuranceOptions}
              value={insuranceId}
              onChange={(v) => setParam({ insurance_id: v ? String(v) : '' })}
              placeholder="همه بیمه‌ها"
              height={38}
            />
          </div>
          <div style={{ minWidth: 130 }}>
            <label className="field-label">نوع بیمه</label>
            <SearchableSelect
              options={KIND_OPTIONS}
              value={kind}
              onChange={(v) => setParam({ kind: v ? String(v) : '' })}
              placeholder="همه انواع"
              height={38}
            />
          </div>
          <div style={{ minWidth: 150 }}>
            <label className="field-label">وضعیت</label>
            <SearchableSelect
              options={STATUS_OPTIONS}
              value={status}
              onChange={(v) => setParam({ status: v ? String(v) : '' })}
              placeholder="همه وضعیت‌ها"
              height={38}
            />
          </div>
          <div style={{ minWidth: 130 }}>
            <label className="field-label">وضعیت پرداخت</label>
            <SearchableSelect
              options={PAYMENT_OPTIONS}
              value={paymentStatus}
              onChange={(v) => setParam({ payment_status: v ? String(v) : '' })}
              placeholder="همه"
              height={38}
            />
          </div>
          <div style={{ minWidth: 140 }}>
            <label className="field-label">از تاریخ</label>
            <PersianDatePicker value={from} onChange={(v) => setParam({ from: v })} height={38} />
          </div>
          <div style={{ minWidth: 140 }}>
            <label className="field-label">تا تاریخ</label>
            <PersianDatePicker value={to} onChange={(v) => setParam({ to: v })} height={38} />
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button className="btn ghost sm" onClick={() => setParam({ from: isoNDaysAgo(30), to: todayIso() })}>یک ماه اخیر</button>
            <button className="btn ghost sm" onClick={() => setParam({ from: isoNDaysAgo(365), to: todayIso() })}>یک سال اخیر</button>
            {hasFilters && (
              <button
                className="btn ghost sm"
                onClick={() => setParams(new URLSearchParams(), { replace: true })}
                style={{ display: 'flex', alignItems: 'center', gap: 4 }}
              >
                <ArrowPathIcon style={{ width: 13 }} /> پاک‌کردن فیلترها
              </button>
            )}
          </div>
        </div>

        <DataTable
          columns={columns}
          data={rows}
          loading={listQuery.isLoading}
          searchValue={search}
          onSearchChange={(v) => setParam({ search: v })}
          searchPlaceholder="نام، موبایل، کد ملی بیمار یا نام بیمه"
          emptyMessage="پرونده بیمه‌ای ثبت نشده است."
          sortKey={sort}
          sortDir={dir}
          onSort={(key) => setParam({ sort: key, dir: sort === key && dir === 'desc' ? 'asc' : 'desc' })}
          actions={(row) => (
            <button className="btn primary sm" onClick={() => navigate(`/admin/claims/${row.record_uuid}`)}>
              جزئیات
            </button>
          )}
        />

        {total > LIMIT && (
          <Pagination page={page} total={total} limit={LIMIT} onPageChange={(p) => setParam({ page: String(p) })} />
        )}
      </div>
    </FeatureGate>
  );
}
