import React, { useEffect, useRef, useState } from 'react';
import { useUrlState } from '../hooks/useUrlState';
import { useQuery } from '@tanstack/react-query';
import ReactDOM from 'react-dom';
import { useNavigate } from 'react-router-dom';
import {
  PlusIcon, EllipsisHorizontalIcon, EyeIcon, PencilIcon, ArrowDownOnSquareIcon,
  UserCircleIcon, PhoneIcon,
} from '@heroicons/react/24/outline';
import { api } from '../lib/api';
import type { PaginatedResponse } from '../lib/api';
import type { Appointment } from '../types';
import { formatDate } from '../lib/utils';
import { useAuthStore } from '../stores/authStore';
import AppointmentStatusDropdown from '../components/ui/AppointmentStatusDropdown';
import SearchableSelect from '../components/ui/SearchableSelect';
import Pagination from '../components/ui/Pagination';
import NewAppointmentDrawer from '../components/NewAppointmentDrawer';
import BackButton from '../components/ui/BackButton';
import { AppointmentInfoModal, TransferReserveModal } from '../components/AppointmentActions';

const LIMIT = 20;

/** Row menu for reserve entries — the design offers only مشاهده/ویرایش/انتقال. */
function ReserveRowMenu({ appointment, queryKey }: { appointment: Appointment; queryKey: unknown[] }) {
  const [open, setOpen] = useState(false);
  const [modal, setModal] = useState<null | 'info' | 'transfer'>(null);
  const [pos, setPos] = useState<{ top: number; right: number } | null>(null);
  const btnRef = useRef<HTMLButtonElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  const navigate = useNavigate();

  useEffect(() => {
    if (!open) return;
    const handler = (e: MouseEvent) => {
      const t = e.target as Node;
      if (!btnRef.current?.contains(t) && !menuRef.current?.contains(t)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  const items = [
    { label: 'مشاهده', icon: EyeIcon, onClick: () => { setOpen(false); setModal('info'); } },
    { label: 'ویرایش', icon: PencilIcon, onClick: () => { setOpen(false); navigate(`/admin/appointments/${appointment.uuid}/edit`); } },
    { label: 'انتقال به لیست نوبت ها', icon: ArrowDownOnSquareIcon, onClick: () => { setOpen(false); setModal('transfer'); } },
  ];

  return (
    <>
      <button ref={btnRef} aria-label="عملیات" className="btn sm ghost" style={{ color: 'var(--primary)', gap: 4 }}
        onClick={() => {
          if (!open && btnRef.current) {
            const r = btnRef.current.getBoundingClientRect();
            setPos({ top: r.bottom + 4, right: window.innerWidth - r.right });
          }
          setOpen(o => !o);
        }}>
        <EllipsisHorizontalIcon style={{ width: 18 }} /> عملیات
      </button>
      {open && pos && ReactDOM.createPortal(
        <div ref={menuRef} style={{
          position: 'fixed', top: pos.top, right: pos.right, zIndex: 9000,
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 'var(--r)', boxShadow: 'var(--shadow-lg)', minWidth: 190, overflow: 'hidden',
        }}>
          {items.map(({ label, icon: Icon, onClick }) => (
            <button key={label} onClick={onClick} style={{
              display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '9px 12px',
              fontSize: 13, background: 'transparent', border: 'none', cursor: 'pointer',
              color: 'var(--text)', fontFamily: 'inherit', textAlign: 'right',
            }}
              onMouseEnter={e => (e.currentTarget.style.background = 'var(--surface-2)')}
              onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}>
              <Icon style={{ width: 15, color: 'var(--text-2)' }} /> {label}
            </button>
          ))}
        </div>,
        document.body,
      )}
      {modal === 'info' && <AppointmentInfoModal appointment={appointment} queryKey={queryKey} onClose={() => setModal(null)} />}
      {modal === 'transfer' && <TransferReserveModal appointment={appointment} queryKey={queryKey} onClose={() => setModal(null)} />}
    </>
  );
}

/** نوبت‌های رزرو شده (reserve-table.pdf) — day-level reserve entries with transfer back to the live list. */
export default function ReserveAppointmentsPage() {
  // شمارهٔ صفحه در URL، مثل بقیهٔ لیست‌های پنل: `navigate(-1)` از صفحهٔ جزئیات باید
  // همان صفحه‌ای را برگرداند که کاربر در آن بود، نه صفحهٔ یک.
  const [urlState, setUrlState] = useUrlState({ page: '1' });
  const page = Math.max(1, Number(urlState.page) || 1);
  const setPage = (v: number) => setUrlState({ page: String(v) });
  const [drawerOpen, setDrawerOpen] = useState(false);
  const primaryRole = useAuthStore(s => s.primaryRole);
  const dbUuid = useAuthStore(s => s.dbUuid);
  const isClinic = primaryRole === 'clinic';
  // the doctor the new reserve is booked for (doctors book for themselves)
  const [doctorUuid, setDoctorUuid] = useState(primaryRole === 'doctor' && dbUuid ? dbUuid : '');

  const clinicDoctorsQ = useQuery<any>({
    queryKey: ['clinic-doctors', dbUuid],
    queryFn: () => api.get(`/api/v1/clinic/doctor-list/${dbUuid}`),
    enabled: isClinic && !!dbUuid,
  });
  const clinicDoctors: { uuid: string; name: string }[] = clinicDoctorsQ.data?.data?.data ?? [];

  const queryKey = ['reserve-appointments', page];
  const { data, isLoading } = useQuery<PaginatedResponse<Appointment>>({
    queryKey,
    queryFn: () => api.get(`/api/v1/my/appointments?reserve=1&page=${page}&limit=${LIMIT}`),
  });
  const items = data?.data ?? [];
  const total = data?.meta?.totalRecords ?? 0;

  const today = new Date();
  const defaultDate = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;

  const th: React.CSSProperties = { padding: '10px 14px', textAlign: 'right', fontWeight: 600, color: 'var(--text-2)', whiteSpace: 'nowrap' };
  const td: React.CSSProperties = { padding: '10px 14px', textAlign: 'right', color: 'var(--text)', verticalAlign: 'middle' };

  return (
    <div className="fade-in" style={{ padding: '20px 24px' }}>
      <div style={{ marginBottom: 14 }}>
        <BackButton fallback="/admin/appointments" />
      </div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 10, marginBottom: 16 }}>
        <h1 style={{ fontSize: 17, fontWeight: 800 }}>نوبت های رزرو شده</h1>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {isClinic && (
            <div style={{ minWidth: 180 }}>
              <SearchableSelect
                options={clinicDoctors.map(d => ({ value: d.uuid, label: d.name }))}
                value={doctorUuid || null}
                onChange={v => setDoctorUuid(v ? String(v) : '')}
                placeholder="انتخاب پزشک..."
                isClearable
                height={34}
              />
            </div>
          )}
          {primaryRole !== 'representation' && (
            <button className="btn primary sm" disabled={!doctorUuid}
              onClick={() => setDrawerOpen(true)} style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
              <PlusIcon style={{ width: 15 }} /> نوبت رزرو
            </button>
          )}
        </div>
      </div>

      <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r)', overflow: 'hidden' }}>
        {isLoading ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>در حال بارگذاری...</div>
        ) : items.length === 0 ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>نوبت رزروی ثبت نشده است</div>
        ) : (
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--border)', background: 'var(--surface-2)' }}>
                  <th style={th}>ردیف</th>
                  <th style={th}>مراجعه کننده</th>
                  <th style={th}>شماره تماس</th>
                  <th style={th}>تاریخ</th>
                  <th style={th}>سرویس</th>
                  <th style={th}>پرسنل</th>
                  <th style={th}>وضعیت</th>
                  <th style={th}>عملیات</th>
                </tr>
              </thead>
              <tbody>
                {items.map((a, i) => (
                  <tr key={a.uuid} style={{ borderBottom: '1px solid var(--border)' }}>
                    <td style={td}>{((page - 1) * LIMIT + i + 1).toLocaleString('fa-IR')}</td>
                    <td style={td}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                        <UserCircleIcon style={{ width: 18, color: 'var(--text-3)' }} />
                        {a.patient_name || '—'}
                      </div>
                    </td>
                    <td style={{ ...td, direction: 'ltr', textAlign: 'right' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 4, justifyContent: 'flex-end' }}>
                        <PhoneIcon style={{ width: 14, color: 'var(--text-3)' }} />
                        {a.patient_mobile}
                      </div>
                    </td>
                    <td style={{ ...td, fontWeight: 600 }}>{formatDate(a.slot_start)}</td>
                    <td style={td}>
                      {/* چند-سرویسی: نگه‌داشتن فقط سرویس تکی یعنی بقیه دیده نمی‌شوند. */}
                      {a.service_items?.length
                        ? a.service_items.map(s => s.name).join('، ')
                        : a.service_item?.name || '—'}
                      {a.service_total_minutes ? (
                        <span style={{ color: 'var(--text-3)', fontSize: 12, marginInlineStart: 6 }}>
                          ({a.service_total_minutes} دقیقه
                          {a.service_buffer_minutes ? ` +${a.service_buffer_minutes} فاصله` : ''})
                        </span>
                      ) : null}
                    </td>
                    <td style={td}>{a.staff?.full_name || '—'}</td>
                    <td style={td}>
                      <AppointmentStatusDropdown uuid={a.uuid} currentStatus={a.status} version={a.version} queryKey={queryKey} />
                    </td>
                    <td style={td}><ReserveRowMenu appointment={a} queryKey={queryKey} /></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {total > LIMIT && (
        <div style={{ marginTop: 14 }}>
          <Pagination page={page} total={total} limit={LIMIT} onPageChange={setPage} />
        </div>
      )}

      {drawerOpen && (
        <NewAppointmentDrawer
          doctorUuid={doctorUuid}
          defaultDate={defaultDate}
          queryKey={queryKey}
          onClose={() => setDrawerOpen(false)}
          isReserve
        />
      )}
    </div>
  );
}
