/**
 * «لیست نوبت‌های جدید» داشبورد پزشک، با فیلتر و صفحه‌بندی سمت سرور.
 *
 * چرا endpoint داشبورد استفاده نمی‌شود: `/api/v1/dashboard/doctor` فقط ۱۰ نوبتِ
 * امروز را برمی‌گرداند و `version` ندارد، پس نه فیلتر معنا می‌دهد نه تغییر وضعیت.
 * به‌جای ساخت endpoint جدید، `/api/v1/appointments/doctor/{uuid}` توسعه داده شد.
 */
import { useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '../../lib/api';
import SearchableSelect from '../ui/SearchableSelect';
import PersianDateInput from '../ui/PersianDateInput';
import Pagination from '../ui/Pagination';
import { NewAppointmentsTable, type ApptRow } from './NewAppointmentsTable';

const PER_PAGE = 20;

/** وضعیت‌هایی که «هنوز ویزیت نشده» محسوب می‌شوند — فیلتر پیش‌فرض. */
export const NOT_VISITED_STATUSES = ['pending', 'confirmed'];

const STATUS_OPTIONS: { value: string; label: string }[] = [
  { value: '',                    label: 'ویزیت‌نشده‌ها: ثبت شده + قطعی شده (پیش‌فرض)' },
  { value: 'pending',             label: 'ثبت شده' },
  { value: 'confirmed',           label: 'قطعی شده' },
  { value: 'following_up',        label: 'در حال پیگیری' },
  { value: 'salon',               label: 'سالن' },
  { value: 'completed',           label: 'ویزیت شده' },
  { value: 'cancelled_by_doctor', label: 'لغو شده' },
  { value: 'cancelled_by_user',   label: 'لغو توسط بیمار' },
  { value: 'no_show',             label: 'غیبت' },
  { value: 'expired',             label: 'منقضی شده' },
];

interface ServiceOption { uuid: string; name?: string }

/** YYYY-MM-DD میلادی → تایم‌استمپ ثانیه‌ای در ابتدا/انتهای همان روز محلی. */
function dayBound(iso: string, edge: 'start' | 'end'): number | null {
  if (!iso) return null;
  const [y, m, d] = iso.split('-').map(Number);
  if (!y || !m || !d) return null;
  const dt = edge === 'start' ? new Date(y, m - 1, d, 0, 0, 0) : new Date(y, m - 1, d, 23, 59, 59);
  return Math.floor(dt.getTime() / 1000);
}

interface ApiAppointment {
  uuid: string;
  status: string;
  version: number;
  slot_start: number;
  slot_end?: number | null;
  patient_name?: string | null;
  patient_mobile?: string | null;
  doctor?: { name?: string | null } | null;
  user?: { mobile?: string | null } | null;
  service_item?: { name?: string | null } | null;
}

export default function DoctorAppointmentsPanel({ doctorUuid, clinicUuid }: {
  doctorUuid?: string | null;
  clinicUuid?: string | null;
}) {
  const [status, setStatus]   = useState('');
  const [from, setFrom]       = useState('');
  const [to, setTo]           = useState('');
  const [q, setQ]             = useState('');
  const [service, setService] = useState('');
  const [page, setPage]       = useState(1);

  const servicesQ = useQuery<{ data?: ServiceOption[] }>({
    queryKey: ['service-sections'],
    queryFn: () => api.get('/api/v1/service-sections'),
  });

  const params = useMemo(() => {
    const p = new URLSearchParams();
    // فیلتر پیش‌فرض: هر نوبتی که هنوز ویزیت یا لغو نشده.
    // براکت لازم است تا Symfony پارامتر را آرایه ببیند، نه رشته.
    (status ? [status] : NOT_VISITED_STATUSES).forEach(s => p.append('statuses[]', s));
    const f = dayBound(from, 'start');
    const t = dayBound(to, 'end');
    if (f !== null) p.set('from', String(f));
    if (t !== null) p.set('to', String(t));
    if (q.trim()) p.set('q', q.trim());
    if (service) p.set('service_uuid', service);
    if (clinicUuid) p.set('clinic_uuid', clinicUuid);
    p.set('page', String(page));
    p.set('limit', String(PER_PAGE));
    return p.toString();
  }, [status, from, to, q, service, clinicUuid, page]);

  const queryKey = ['doctor-appointments', doctorUuid, params];

  const listQ = useQuery<{ data?: ApiAppointment[]; meta?: { totalRecords?: number } }>({
    queryKey,
    queryFn: () => api.get(`/api/v1/appointments/doctor/${doctorUuid}?${params}`),
    enabled: !!doctorUuid,
    staleTime: 30_000,
  });

  const rows: ApptRow[] = useMemo(
    () => (listQ.data?.data ?? []).map(a => ({
      uuid:           a.uuid,
      patient_name:   a.patient_name ?? null,
      patient_mobile: a.patient_mobile ?? a.user?.mobile ?? null,
      doctor_name:    a.doctor?.name ?? null,
      service_name:   a.service_item?.name ?? null,
      slot_start:     a.slot_start,
      slot_end:       a.slot_end ?? null,
      status:         a.status,
      version:        a.version,
    })),
    [listQ.data],
  );

  const total = listQ.data?.meta?.totalRecords ?? 0;

  /** هر تغییر فیلتر صفحه را به اول برمی‌گرداند تا کاربر روی صفحهٔ خالی نماند. */
  const onFilter = <T,>(setter: (v: T) => void) => (v: T) => { setter(v); setPage(1); };

  return (
    <>
      <div className="flex flex-wrap gap-[10px] items-end mb-[14px]">
        <div style={{ minWidth: 170 }}>
          <SearchableSelect
            value={status}
            onChange={v => onFilter(setStatus)(v == null ? '' : String(v))}
            options={STATUS_OPTIONS}
            placeholder="وضعیت"
          />
        </div>
        <div style={{ minWidth: 150 }}>
          <PersianDateInput value={from} onChange={onFilter(setFrom)} placeholder="از تاریخ" />
        </div>
        <div style={{ minWidth: 150 }}>
          <PersianDateInput value={to} onChange={onFilter(setTo)} placeholder="تا تاریخ" />
        </div>
        <div style={{ minWidth: 170 }}>
          <SearchableSelect
            value={service}
            onChange={v => onFilter(setService)(v == null ? '' : String(v))}
            options={[
              { value: '', label: 'همهٔ سرویس‌ها' },
              ...(servicesQ.data?.data ?? []).map(s => ({ value: s.uuid, label: s.name ?? '—' })),
            ]}
            placeholder="سرویس"
          />
        </div>
        <input
          className="input"
          style={{ minWidth: 190 }}
          value={q}
          onChange={e => onFilter(setQ)(e.target.value)}
          placeholder="نام یا شماره تماس بیمار"
        />
      </div>

      <NewAppointmentsTable
        rows={rows}
        loading={listQ.isLoading}
        queryKey={queryKey}
        emptyText="نوبتی با این فیلترها یافت نشد"
      />

      {total > PER_PAGE && (
        <div className="mt-[14px]">
          <Pagination page={page} total={total} limit={PER_PAGE} onPageChange={setPage} />
        </div>
      )}
    </>
  );
}
