import React, { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { PlusIcon, PencilIcon, TrashIcon } from '@heroicons/react/24/outline';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { PaginatedResponse } from '../lib/api';
import type { SubscriptionPlan, SubscriptionPeriod } from '../types';
import { formatRial, formatNumber, formatDate, formatResourceLimit } from '../lib/utils';
import Modal from '../components/ui/Modal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import PageHeader from '../components/ui/PageHeader';
import PriceInput from '../components/ui/PriceInput';
import SearchableSelect from '../components/ui/SearchableSelect';
import Pagination from '../components/ui/Pagination';
import { numericField } from '../lib/forms';
import { useUrlState } from '../hooks/useUrlState';

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

interface ReportRow {
  uuid: string;
  entityType: string;
  entityId: number;
  entityName: string | null;
  isTrial: boolean;
  isGranted: boolean;
  grantedBy: string | null;
  startsAt: number;
  expiresAt: number | null;
  createdAt: number;
  plan_name: string;
  plan_level: number;
}

// ── Schemas ───────────────────────────────────────────────────────────────

const planSchema = z.object({
  name:            z.string().min(1, 'نام الزامی است'),
  level:           z.coerce.number().min(0),
  max_secretaries: z.coerce.number().min(1),
  // API نامحدود را با `-1` می‌فهمد، ولی فرم عددِ منفی نمی‌گیرد: `numericField` علامت را
  // پاک می‌کند و «۱-» هم چیزی نیست که ادمین حدس بزند. پس یک سوییچ، و نگاشت هنگام ارسال.
  resources_unlimited: z.boolean(),
  max_resources: z.coerce.number().int().min(1),
  features: z.record(z.string(), z.boolean()),
  active: z.boolean(),
});
type PlanForm = z.infer<typeof planSchema>;

/** بدنهٔ واقعی API: سوییچِ «نامحدود» به همان `-1` قراردادی برمی‌گردد. */
type PlanPayload = Omit<PlanForm, 'resources_unlimited'>;

const toPlanPayload = ({ resources_unlimited, max_resources, ...rest }: PlanForm): PlanPayload => ({
  ...rest,
  max_resources: resources_unlimited ? -1 : max_resources,
});

const periodSchema = z.object({
  plan_uuid:       z.string().min(1, 'پلن الزامی است'),
  label:           z.string().min(1, 'عنوان دوره الزامی است'),
  duration_months: z.coerce.number().min(1),
  price_rials:     z.coerce.number().min(0),
  is_trial:        z.boolean(),
  sort_order:      z.coerce.number().min(0),
  active:          z.boolean(),
});
type PeriodForm = z.infer<typeof periodSchema>;

// ── Feature labels ────────────────────────────────────────────────────────

const FEATURE_LABELS: Record<string, string> = {
  patient_records: 'پرونده بیمار',
  services:        'سرویس‌ها',
  sms_panel:       'پنل پیامک',
  insurance:       'بیمه و مطالبات',
};

const FEATURE_KEYS = Object.keys(FEATURE_LABELS);

const emptyFeatures = (): Record<string, boolean> =>
  Object.fromEntries(FEATURE_KEYS.map((k) => [k, false]));

const PLAN_DISPLAY: Record<string, string> = {
  free:         'رایگان',
  basic:        'پایه',
  professional: 'حرفه‌ای',
};

// ── Switch toggle ─────────────────────────────────────────────────────────

/**
 * نسخهٔ uncontrolled سوییچ برای `react-hook-form`.
 *
 * `components/ui/Switch` کنترل‌شده است (`checked` + `onChange`) و با اسپردِ
 * `register()` — که `ref` و `onChange` نیتیو می‌دهد — جور در نمی‌آید. ظاهر هر دو از
 * یک کلاس `.switch` می‌آید، پس تفاوت دیداری ندارند.
 */
const SwitchToggle = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
  function SwitchToggle(props, ref) {
    return (
      <span className="switch" onClick={(e) => e.stopPropagation()}>
        <input type="checkbox" ref={ref} {...props} />
        <span className="switch-track"><span className="switch-thumb" /></span>
      </span>
    );
  },
);

// ── Plans tab ─────────────────────────────────────────────────────────────

function PlansTab() {
  const qc = useQueryClient();
  const [planModal,   setPlanModal]   = useState<'create' | SubscriptionPlan | null>(null);
  const [periodModal, setPeriodModal] = useState<'create' | SubscriptionPeriod | null>(null);
  const [activePlan,  setActivePlan]  = useState<SubscriptionPlan | null>(null);
  const [deletePeriod, setDeletePeriod] = useState<SubscriptionPeriod | null>(null);

  const { data: plansData, isLoading } = useQuery({
    queryKey: ['admin-subscription-plans'],
    queryFn: () => api.get<PaginatedResponse<SubscriptionPlan>>('/api/v1/admin/subscription/plans'),
  });

  const plans: SubscriptionPlan[] = (plansData as any)?.data ?? [];

  const planForm = useForm<PlanForm>({
    resolver: zodResolver(planSchema),
    defaultValues: { features: emptyFeatures(), active: true },
  });

  const unlimitedResources = planForm.watch('resources_unlimited');

  const periodForm = useForm<PeriodForm>({
    resolver: zodResolver(periodSchema),
    defaultValues: { is_trial: false, sort_order: 0, active: true, price_rials: 0 },
  });

  const createPlanMut = useMutation({
    mutationFn: (body: PlanPayload) => api.post('/api/v1/admin/subscription/plan', body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-subscription-plans'] }); setPlanModal(null); planForm.reset(); toast.success('پلن ایجاد شد'); },
    onError: (e: any) => toast.error(e.message),
  });

  const updatePlanMut = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: PlanPayload }) => api.patch(`/api/v1/admin/subscription/plan/${uuid}`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-subscription-plans'] }); setPlanModal(null); toast.success('پلن بروزرسانی شد'); },
    onError: (e: any) => toast.error(e.message),
  });

  const createPeriodMut = useMutation({
    mutationFn: (body: PeriodForm) => api.post('/api/v1/admin/subscription/period', body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-subscription-plans'] }); setPeriodModal(null); periodForm.reset(); toast.success('دوره ایجاد شد'); },
    onError: (e: any) => toast.error(e.message),
  });

  const updatePeriodMut = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: PeriodForm }) => api.patch(`/api/v1/admin/subscription/period/${uuid}`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-subscription-plans'] }); setPeriodModal(null); toast.success('دوره بروزرسانی شد'); },
    onError: (e: any) => toast.error(e.message),
  });

  const deletePeriodMut = useMutation({
    mutationFn: (uuid: string) => api.delete(`/api/v1/admin/subscription/period/${uuid}`),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-subscription-plans'] }); setDeletePeriod(null); toast.success('دوره حذف شد'); },
    onError: (e: any) => toast.error(e.message),
  });

  const openEditPlan = (plan: SubscriptionPlan) => {
    planForm.reset({
      name:            plan.name,
      level:           plan.level,
      max_secretaries: plan.max_secretaries,
      // سقفِ نامحدود عددی برای نمایش ندارد؛ ۱ می‌نشیند تا خاموش‌کردن سوییچ یک مقدار
      // معتبر بدهد، نه یک فیلدِ خالی.
      resources_unlimited: plan.max_resources < 0,
      max_resources:   plan.max_resources < 0 ? 1 : plan.max_resources,
      features:        { ...emptyFeatures(), ...plan.features },
      active:          (plan as any).active ?? true,
    });
    setPlanModal(plan);
  };

  const openEditPeriod = (period: SubscriptionPeriod) => {
    periodForm.reset({
      plan_uuid:       (period as any).plan_uuid ?? '',
      label:           period.label,
      duration_months: period.duration_months,
      price_rials:     period.price_rials,
      is_trial:        period.is_trial,
      sort_order:      (period as any).sort_order ?? 0,
      active:          (period as any).active ?? true,
    });
    setPeriodModal(period);
  };

  const openCreatePeriod = (plan: SubscriptionPlan) => {
    setActivePlan(plan);
    periodForm.reset({ plan_uuid: plan.uuid, is_trial: false, sort_order: 0, active: true, price_rials: 0, label: '', duration_months: 1 });
    setPeriodModal('create');
  };

  return (
    <>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 16 }}>
        <button className="btn primary sm" onClick={() => { planForm.reset({ features: emptyFeatures(), active: true, level: 0, max_secretaries: 1, max_resources: 1, resources_unlimited: false }); setPlanModal('create'); }}>
          <PlusIcon style={{ width: 16 }} /> پلن جدید
        </button>
      </div>

      {isLoading ? (
        <div className="card card-pad" style={{ color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {plans.map((plan) => {
            const periods: SubscriptionPeriod[] = Array.isArray(plan.periods)
              ? plan.periods
              : Object.values(plan.periods ?? {});
            return (
            <div key={plan.uuid} className="card">
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px', borderBottom: '1px solid var(--border)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                  <b style={{ fontSize: 15 }}>{PLAN_DISPLAY[plan.name] ?? plan.name}</b>
                  <span className={`badge ${plan.active ? 'green' : 'gray'}`} style={{ fontSize: 11 }}>{plan.active ? 'فعال' : 'غیرفعال'}</span>
                  <span className="badge blue" style={{ fontSize: 11 }}>سطح {plan.level}</span>
                  <span className="muted" style={{ fontSize: 12 }}>حداکثر {plan.max_secretaries} منشی</span>
                  <span className="muted" style={{ fontSize: 12 }}>حداکثر {formatResourceLimit(plan.max_resources)} منبع</span>
                  <span style={{ fontSize: 12, display: 'flex', gap: 6 }}>
                    {Object.entries(plan.features).map(([k, v]) => (
                      <span key={k} className={`badge ${v ? 'green' : 'gray'}`} style={{ fontSize: 10 }}>{FEATURE_LABELS[k] ?? k}</span>
                    ))}
                  </span>
                </div>
                <div style={{ display: 'flex', gap: 6 }}>
                  <button className="btn sm" onClick={() => openCreatePeriod(plan)}>
                    <PlusIcon style={{ width: 13 }} /> دوره جدید
                  </button>
                  <button className="btn sm" onClick={() => openEditPlan(plan)}>
                    <PencilIcon style={{ width: 13 }} />
                  </button>
                </div>
              </div>

              {periods.length === 0 ? (
                <div style={{ padding: '20px 16px', color: 'var(--text-3)', fontSize: 13 }}>هنوز دوره‌ای تعریف نشده</div>
              ) : (
                <div className="table-wrap"><table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
                  <thead>
                    <tr style={{ borderBottom: '1px solid var(--border)' }}>
                      <th style={{ textAlign: 'right', padding: '8px 16px', color: 'var(--text-3)', fontWeight: 500 }}>دوره</th>
                      <th style={{ textAlign: 'right', padding: '8px 16px', color: 'var(--text-3)', fontWeight: 500 }}>مدت</th>
                      <th style={{ textAlign: 'right', padding: '8px 16px', color: 'var(--text-3)', fontWeight: 500 }}>قیمت</th>
                      <th style={{ textAlign: 'right', padding: '8px 16px', color: 'var(--text-3)', fontWeight: 500 }}>نوع</th>
                      <th style={{ textAlign: 'right', padding: '8px 16px', color: 'var(--text-3)', fontWeight: 500 }}>عملیات</th>
                    </tr>
                  </thead>
                  <tbody>
                    {periods.map((period, i) => (
                      <tr key={period.uuid} style={{ borderBottom: i < periods.length - 1 ? '1px solid var(--border)' : 'none' }}>
                        <td style={{ padding: '8px 16px' }}><b>{period.label}</b></td>
                        <td style={{ padding: '8px 16px' }}>{period.duration_months} ماه</td>
                        <td style={{ padding: '8px 16px' }}>{period.is_trial ? 'رایگان' : formatRial(period.price_rials)}</td>
                        <td style={{ padding: '8px 16px' }}>
                          {period.is_trial ? <span className="badge amber">تریال</span> : <span className="badge blue">پولی</span>}
                        </td>
                        <td style={{ padding: '8px 16px' }}>
                          <div style={{ display: 'flex', gap: 4 }}>
                            <button className="btn sm" onClick={() => openEditPeriod(period)}>
                              <PencilIcon style={{ width: 13 }} />
                            </button>
                            <button className="btn sm" onClick={() => setDeletePeriod(period)}>
                              <TrashIcon style={{ width: 13 }} />
                            </button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table></div>
              )}
            </div>
            );
          })}
        </div>
      )}

      {/* Modal پنل */}
      <Modal
        open={planModal !== null}
        onClose={() => setPlanModal(null)}
        title={planModal === 'create' ? 'پلن جدید' : 'ویرایش پلن'}
      >
        <form onSubmit={planForm.handleSubmit((d) => {
          const body = toPlanPayload(d);
          if (planModal === 'create') createPlanMut.mutate(body);
          else if (planModal !== null && typeof planModal === 'object') updatePlanMut.mutate({ uuid: planModal.uuid, body });
        })}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div className="field">
              <label>نام (slug) *</label>
              <input {...planForm.register('name')} placeholder="basic" dir="ltr" />
              {planForm.formState.errors.name && <span className="field-error">{planForm.formState.errors.name.message}</span>}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <div className="field">
                <label>سطح *</label>
                <input {...numericField(planForm.register('level'))} />
              </div>
              <div className="field">
                <label>حداکثر منشی *</label>
                <input {...numericField(planForm.register('max_secretaries'))} />
              </div>
            </div>
            <div className="field">
              <label htmlFor="plan-max-resources">حداکثر منبع *</label>
              <input
                id="plan-max-resources"
                {...numericField(planForm.register('max_resources'))}
                disabled={unlimitedResources}
                style={unlimitedResources ? { opacity: 0.5 } : undefined}
              />
              <label style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, fontSize: 13.5, cursor: 'pointer', marginTop: 8 }}>
                <span style={{ color: 'var(--text)' }}>منابع نامحدود</span>
                <SwitchToggle {...planForm.register('resources_unlimited')} />
              </label>
              <span className="field-hint">سقف اتاق و دستگاه و پرسنلِ هر محیط. منابعِ پزشک و پرسنل هم در این شمارش می‌آیند.</span>
              {planForm.formState.errors.max_resources && (
                <span className="field-error">{planForm.formState.errors.max_resources.message}</span>
              )}
            </div>
            <div>
              <span className="field-label">قابلیت‌های پلن</span>
              <div style={{ display: 'flex', flexDirection: 'column', border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', background: 'var(--surface)', overflow: 'hidden' }}>
                {FEATURE_KEYS.map((k, i) => (
                  <label key={k} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, fontSize: 13.5, cursor: 'pointer', padding: '11px 14px', borderTop: i ? '1px solid var(--border)' : 'none' }}>
                    <span style={{ color: 'var(--text)' }}>{FEATURE_LABELS[k]}</span>
                    <SwitchToggle {...planForm.register(`features.${k}` as any)} />
                  </label>
                ))}
              </div>
            </div>
            <label style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, fontSize: 13.5, cursor: 'pointer', padding: '11px 14px', border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', background: 'var(--surface)' }}>
              <span style={{ color: 'var(--text)', fontWeight: 600 }}>پلن فعال است</span>
              <SwitchToggle {...planForm.register('active')} />
            </label>
          </div>
          <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
            <button type="submit" className="btn primary" disabled={createPlanMut.isPending || updatePlanMut.isPending}>ذخیره</button>
            <button type="button" className="btn" onClick={() => setPlanModal(null)}>انصراف</button>
          </div>
        </form>
      </Modal>

      {/* Modal دوره */}
      <Modal
        open={periodModal !== null}
        onClose={() => setPeriodModal(null)}
        title={periodModal === 'create' ? `دوره جدید — ${PLAN_DISPLAY[activePlan?.name ?? ''] ?? activePlan?.name ?? ''}` : 'ویرایش دوره'}
      >
        <form onSubmit={periodForm.handleSubmit((d) => {
          if (periodModal === 'create') createPeriodMut.mutate(d);
          else if (periodModal !== null && typeof periodModal === 'object') updatePeriodMut.mutate({ uuid: periodModal.uuid, body: d });
        })}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div className="field">
              <label>عنوان دوره *</label>
              <input {...periodForm.register('label')} placeholder="مثلاً: یک ماهه" />
              {periodForm.formState.errors.label && <span className="field-error">{periodForm.formState.errors.label.message}</span>}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <div className="field">
                <label>مدت (ماه) *</label>
                <input {...numericField(periodForm.register('duration_months'))} />
              </div>
              <div className="field">
                <label>قیمت (ریال) *</label>
                <PriceInput
                  value={periodForm.watch('price_rials') ?? ''}
                  onChange={(v) => periodForm.setValue('price_rials', v)}
                  ariaLabel="قیمت دوره (ریال)"
                />
              </div>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <div className="field">
                <label>ترتیب نمایش</label>
                <input {...numericField(periodForm.register('sort_order'))} />
              </div>
            </div>
            <div style={{ display: 'flex', gap: 16 }}>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, cursor: 'pointer' }}>
                <input type="checkbox" {...periodForm.register('is_trial')} style={{ accentColor: 'var(--primary)' }} />
                تریال (رایگان)
              </label>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, cursor: 'pointer' }}>
                <input type="checkbox" {...periodForm.register('active')} style={{ accentColor: 'var(--primary)' }} />
                فعال
              </label>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
            <button type="submit" className="btn primary" disabled={createPeriodMut.isPending || updatePeriodMut.isPending}>ذخیره</button>
            <button type="button" className="btn" onClick={() => setPeriodModal(null)}>انصراف</button>
          </div>
        </form>
      </Modal>

      {/* Confirm حذف دوره */}
      <ConfirmDialog
        open={!!deletePeriod}
        title="حذف دوره"
        message={`آیا مطمئن هستید که می‌خواهید دوره «${deletePeriod?.label}» را حذف کنید؟`}
        confirmLabel="حذف"
        danger
        loading={deletePeriodMut.isPending}
        onConfirm={() => deletePeriod && deletePeriodMut.mutate(deletePeriod.uuid)}
        onCancel={() => setDeletePeriod(null)}
      />
    </>
  );
}

// ── Grant tab ─────────────────────────────────────────────────────────────

type EntityType = 'doctor' | 'clinic';

interface EntityRow { uuid: string; name: string; mobile?: string; owner_mobile?: string }

interface ActiveSubscriptionData {
  subscription: {
    plan: { name: string; level: number };
    period?: { label: string };
    expires_at: number | null;
    is_trial: boolean;
    is_granted: boolean;
  } | null;
}

function GrantTab() {
  const qc = useQueryClient();
  const [entityType, setEntityType] = useState<EntityType>('doctor');
  const [entityUuid, setEntityUuid] = useState<string | null>(null);
  const [periodUuid, setPeriodUuid] = useState<string | null>(null);
  const [searchInput, setSearchInput] = useState('');
  const [search, setSearch] = useState('');
  const [downgrade, setDowngrade] = useState<{ from: string; to: string } | null>(null);

  // جستجوی سمت سرور، چون فهرست پزشکان از سقف یک صفحهٔ endpoint بیشتر است.
  React.useEffect(() => {
    const t = setTimeout(() => setSearch(searchInput), 350);
    return () => clearTimeout(t);
  }, [searchInput]);

  const { data: entityData, isFetching: entitiesLoading } = useQuery({
    queryKey: ['admin-grant-entities', entityType, search],
    queryFn: () => api.get<PaginatedResponse<EntityRow>>(
      `/api/v1/admin/${entityType === 'doctor' ? 'doctors' : 'clinics'}?limit=25&search=${encodeURIComponent(search)}`,
    ),
  });

  const entityOptions = (entityData?.data ?? []).map((e) => ({
    value: e.uuid,
    label: e.mobile || e.owner_mobile ? `${e.name} — ${e.mobile ?? e.owner_mobile}` : e.name,
  }));

  const { data: plansData } = useQuery({
    queryKey: ['admin-subscription-plans'],
    queryFn: () => api.get<PaginatedResponse<SubscriptionPlan>>('/api/v1/admin/subscription/plans'),
  });

  const plans: SubscriptionPlan[] = (plansData as any)?.data ?? [];

  // فقط دوره‌های پولی: اعطای دورهٔ تریال، تریالِ نگرفتهٔ کاربر را می‌سوزاند.
  const periodOptions = plans.flatMap((plan) => {
    const periods: SubscriptionPeriod[] = Array.isArray(plan.periods) ? plan.periods : Object.values(plan.periods ?? {});
    return periods
      .filter((p) => !p.is_trial)
      .map((p) => ({
        value: p.uuid,
        label: `${PLAN_DISPLAY[plan.name] ?? plan.name} — ${p.label} (${formatRial(p.price_rials)})`,
        planName: plan.name,
        planLevel: plan.level,
      }));
  });

  const selectedPeriod = periodOptions.find((p) => p.value === periodUuid) ?? null;

  const { data: activeData, isFetching: activeLoading } = useQuery({
    queryKey: ['admin-grant-active', entityType, entityUuid],
    queryFn: () => api.get<{ data: ActiveSubscriptionData }>(`/api/v1/admin/subscription/active/${entityType}/${entityUuid}`),
    enabled: entityUuid !== null,
  });

  const activeSub = (activeData as any)?.data?.subscription ?? null;

  const grantMut = useMutation({
    mutationFn: (body: { entity_type: EntityType; entity_uuid: string; period_uuid: string }) =>
      api.post('/api/v1/admin/subscription/grant', body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin-subscription-report'] });
      qc.invalidateQueries({ queryKey: ['admin-grant-active'] });
      setDowngrade(null);
      setPeriodUuid(null);
      toast.success('اشتراک اعطا شد');
    },
    onError: (e: any) => { setDowngrade(null); toast.error(e.message); },
  });

  const submitGrant = () => {
    if (!entityUuid || !periodUuid) { return; }
    grantMut.mutate({ entity_type: entityType, entity_uuid: entityUuid, period_uuid: periodUuid });
  };

  const onSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!entityUuid || !periodUuid || selectedPeriod === null) { return; }

    // `findActive` آخرین رکورد را برمی‌دارد، نه بالاترین پلن را — پس اعطای پلن
    // پایین‌تر واقعاً downgrade می‌کند و باید صریح تأیید شود.
    if (activeSub !== null && selectedPeriod.planLevel < activeSub.plan.level) {
      setDowngrade({
        from: PLAN_DISPLAY[activeSub.plan.name] ?? activeSub.plan.name,
        to:   PLAN_DISPLAY[selectedPeriod.planName] ?? selectedPeriod.planName,
      });
      return;
    }

    submitGrant();
  };

  const changeEntityType = (type: EntityType) => {
    setEntityType(type);
    setEntityUuid(null);
    setSearchInput('');
    setSearch('');
  };

  return (
    <>
      <div className="card card-pad" style={{ maxWidth: 560 }}>
        <form onSubmit={onSubmit}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div className="field-block">
              <label>نوع مقصد</label>
              <div className="seg">
                <button type="button" className={entityType === 'doctor' ? 'on' : ''} onClick={() => changeEntityType('doctor')}>پزشک</button>
                <button type="button" className={entityType === 'clinic' ? 'on' : ''} onClick={() => changeEntityType('clinic')}>کلینیک</button>
              </div>
            </div>

            <div className="field-block">
              <label htmlFor="grant-entity">{entityType === 'doctor' ? 'پزشک' : 'کلینیک'} <span className="req">*</span></label>
              <SearchableSelect
                inputId="grant-entity"
                options={entityOptions}
                value={entityUuid}
                onChange={(v) => setEntityUuid(v === null ? null : String(v))}
                onInputChange={setSearchInput}
                isLoading={entitiesLoading}
                isClearable
                placeholder="نام یا شماره موبایل را بنویسید..."
                ariaLabelledBy="grant-entity-label"
              />
              <span className="field-hint">برای یافتن مقصد، بخشی از نام یا شمارهٔ موبایل را تایپ کنید.</span>
            </div>

            {entityUuid !== null && (
              <div style={{ background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', padding: '11px 14px', fontSize: 13 }}>
                {activeLoading ? (
                  <span style={{ color: 'var(--text-3)' }}>در حال بررسی اشتراک فعلی...</span>
                ) : activeSub === null ? (
                  <span style={{ color: 'var(--text-3)' }}>این مقصد اشتراک فعالی ندارد.</span>
                ) : (
                  <span style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <span style={{ color: 'var(--text-2)' }}>اشتراک فعلی:</span>
                    <b>{PLAN_DISPLAY[activeSub.plan.name] ?? activeSub.plan.name}</b>
                    {activeSub.is_trial && <span className="badge amber">تریال</span>}
                    {activeSub.is_granted && <span className="badge violet">اعطایی</span>}
                    <span style={{ color: 'var(--text-2)' }}>
                      انقضا: {activeSub.expires_at ? formatDate(activeSub.expires_at) : 'بی‌نهایت'}
                    </span>
                  </span>
                )}
              </div>
            )}

            <div className="field-block">
              <label htmlFor="grant-period">پلن و دوره <span className="req">*</span></label>
              <SearchableSelect
                inputId="grant-period"
                options={periodOptions}
                value={periodUuid}
                onChange={(v) => setPeriodUuid(v === null ? null : String(v))}
                isClearable
                placeholder="انتخاب کنید..."
                ariaLabel="پلن و دوره اشتراک"
              />
              <span className="field-hint">
                فقط دوره‌های پولی نمایش داده می‌شوند. اگر مقصد اشتراک فعال دارد، مدت روی انقضای فعلی افزوده می‌شود، نه از امروز.
              </span>
            </div>
          </div>

          <div style={{ display: 'flex', gap: 8, marginTop: 20 }}>
            <button type="submit" className="btn primary" disabled={!entityUuid || !periodUuid || grantMut.isPending}>
              اعطای اشتراک
            </button>
          </div>
        </form>
      </div>

      <ConfirmDialog
        open={downgrade !== null}
        title="کاهش سطح پلن"
        message={`پلن این ${entityType === 'doctor' ? 'پزشک' : 'کلینیک'} از «${downgrade?.from}» به «${downgrade?.to}» کاهش می‌یابد. ادامه می‌دهید؟`}
        confirmLabel="اعطا کن"
        danger
        loading={grantMut.isPending}
        onConfirm={submitGrant}
        onCancel={() => setDowngrade(null)}
      />
    </>
  );
}

// ── Report tab ────────────────────────────────────────────────────────────

function ReportTab({ onAdd }: { onAdd: () => void }) {
  const qc = useQueryClient();
  const [page, setPage] = useState(1);
  const [deleteRow, setDeleteRow] = useState<ReportRow | null>(null);
  const limit = 20;

  const { data, isLoading } = useQuery({
    queryKey: ['admin-subscription-report', page],
    queryFn: () => api.get<PaginatedResponse<ReportRow>>(`/api/v1/admin/subscription/report?page=${page}&limit=${limit}`),
  });

  const deleteMut = useMutation({
    mutationFn: (uuid: string) => api.delete(`/api/v1/admin/subscription/${uuid}`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin-subscription-report'] });
      qc.invalidateQueries({ queryKey: ['admin-grant-active'] });
      setDeleteRow(null);
      toast.success('اشتراک حذف شد');
    },
    onError: (e: any) => { setDeleteRow(null); toast.error(e.message); },
  });

  const rows: ReportRow[] = data?.data ?? [];
  const total = data?.meta?.totalRecords ?? 0;

  return (
    <div className="card">
      <div className="card-pad" style={{ display: 'flex', justifyContent: 'flex-end', borderBottom: '1px solid var(--border)' }}>
        <button type="button" className="btn primary" onClick={onAdd}>
          <PlusIcon style={{ width: 15 }} /> اعطای اشتراک جدید
        </button>
      </div>
      {isLoading ? (
        <div className="card-pad" style={{ color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : rows.length === 0 ? (
        <div className="card-pad" style={{ color: 'var(--text-3)', textAlign: 'center', padding: '40px 0' }}>هیچ اشتراکی ثبت نشده</div>
      ) : (
        <>
          <div className="table-wrap"><table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--border)' }}>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>مقصد</th>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>پلن</th>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>نوع اشتراک</th>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>شروع</th>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>انقضا</th>
                <th style={{ textAlign: 'right', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>تاریخ ثبت</th>
                <th style={{ textAlign: 'left', padding: '10px 16px', color: 'var(--text-3)', fontWeight: 500 }}>عملیات</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((row, i) => (
                <tr key={row.uuid} style={{ borderBottom: i < rows.length - 1 ? '1px solid var(--border)' : 'none' }}>
                  <td style={{ padding: '10px 16px' }}>
                    <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                      <span className={`badge ${row.entityType === 'clinic' ? 'blue' : 'green'}`}>
                        {row.entityType === 'clinic' ? 'کلینیک' : 'پزشک'}
                      </span>
                      <b>{row.entityName ?? `#${row.entityId}`}</b>
                    </span>
                  </td>
                  <td style={{ padding: '10px 16px' }}>
                    <b>{PLAN_DISPLAY[row.plan_name] ?? row.plan_name}</b>
                    <span className="muted" style={{ fontSize: 11, marginRight: 6 }}>سطح {row.plan_level}</span>
                  </td>
                  <td style={{ padding: '10px 16px' }}>
                    {row.isTrial ? (
                      <span className="badge amber">تریال</span>
                    ) : row.isGranted ? (
                      <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                        <span className="badge violet">اعطایی</span>
                        {row.grantedBy && <span className="muted" style={{ fontSize: 11 }}>{row.grantedBy}</span>}
                      </span>
                    ) : (
                      <span className="badge blue">پولی</span>
                    )}
                  </td>
                  <td style={{ padding: '10px 16px', color: 'var(--text-2)' }}>{formatDate(row.startsAt)}</td>
                  <td style={{ padding: '10px 16px', color: 'var(--text-2)' }}>
                    {row.expiresAt ? formatDate(row.expiresAt) : <span className="muted">بی‌نهایت</span>}
                  </td>
                  <td style={{ padding: '10px 16px', color: 'var(--text-3)' }}>{formatDate(row.createdAt)}</td>
                  <td style={{ padding: '10px 16px', textAlign: 'left' }}>
                    <button
                      type="button"
                      className="btn sm"
                      title="حذف اشتراک"
                      aria-label={`حذف اشتراک ${row.entityName ?? row.entityId}`}
                      onClick={() => setDeleteRow(row)}
                    >
                      <TrashIcon style={{ width: 13 }} />
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table></div>
          <div style={{ padding: '12px 16px' }}>
            <Pagination page={page} total={total} limit={limit} onPageChange={setPage} />
          </div>
        </>
      )}

      <ConfirmDialog
        open={!!deleteRow}
        title="حذف اشتراک"
        message={`آیا مطمئن هستید که می‌خواهید اشتراک «${deleteRow?.entityName ?? ''}» را حذف کنید؟ دسترسی این محیط به قابلیت‌های پلن قطع می‌شود.`}
        confirmLabel="حذف"
        danger
        loading={deleteMut.isPending}
        onConfirm={() => deleteRow && deleteMut.mutate(deleteRow.uuid)}
        onCancel={() => setDeleteRow(null)}
      />
    </div>
  );
}

// ── Main ──────────────────────────────────────────────────────────────────

export default function AdminSubscriptionPage() {
  // تب در URL می‌نشیند، نه در state: بازگشت از صفحهٔ دیگر باید همان تب را برگرداند.
  const [urlState, setUrlState] = useUrlState({ tab: 'plans' });
  const tab    = urlState.tab;
  const setTab = (next: string) => setUrlState({ tab: next });

  return (
    <>
      <PageHeader title="مدیریت اشتراک‌ها" description="تعریف پلن‌ها و دوره‌ها، اعطای اشتراک و گزارش فروش" />

      <div className="seg" style={{ marginBottom: 20 }}>
        <button className={tab === 'plans'  ? 'on' : ''} onClick={() => setTab('plans')}>پلن‌ها و دوره‌ها</button>
        <button className={tab === 'grant'  ? 'on' : ''} onClick={() => setTab('grant')}>اعطای اشتراک</button>
        <button className={tab === 'report' ? 'on' : ''} onClick={() => setTab('report')}>گزارش فروش</button>
      </div>

      {tab === 'plans'  && <PlansTab />}
      {tab === 'grant'  && <GrantTab />}
      {tab === 'report' && <ReportTab onAdd={() => setTab('grant')} />}
    </>
  );
}
