import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { useNavigate } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  EllipsisHorizontalIcon, PencilIcon, PlusIcon, EyeIcon,
  ArrowsRightLeftIcon, ArrowDownOnSquareIcon, ArrowPathIcon,
  ClockIcon, PhoneIcon, TagIcon, UserIcon, WalletIcon, Squares2X2Icon,
} from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import type { Appointment } from '../types';
import { formatRial } from '../lib/utils';
import Modal from './ui/Modal';
import PersianDateInput from './ui/PersianDateInput';
import AppointmentStatusDropdown from './ui/AppointmentStatusDropdown';

/** Row actions for the appointments table (Figma عملیات menu). */
type ModalKind = null | 'info' | 'move' | 'transfer' | 'replace';

const toEpoch = (isoDate: string, time: string) =>
  Math.floor(new Date(`${isoDate}T${time || '00:00'}`).getTime() / 1000);

/**
 * Resolve the patient-record uuid behind an appointment via the patient list
 * search (mobile is unique per user). Returns null when no record exists yet.
 */
async function findRecordUuid(mobile: string): Promise<string | null> {
  const res: any = await api.get(`/api/v1/patient?search=${encodeURIComponent(mobile)}&limit=1`);
  return res?.data?.[0]?.uuid ?? null;
}

export default function AppointmentActionsMenu({ appointment, queryKey }: {
  appointment: Appointment; queryKey: unknown[];
}) {
  const [open, setOpen] = useState(false);
  const [modal, setModal] = useState<ModalKind>(null);
  const [menuPos, setMenuPos] = 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 openMenu = () => {
    if (!open && btnRef.current) {
      const r = btnRef.current.getBoundingClientRect();
      setMenuPos({ top: r.bottom + 4, right: window.innerWidth - r.right });
    }
    setOpen(o => !o);
  };

  const goToServiceRegistration = async () => {
    setOpen(false);
    try {
      const recordUuid = await findRecordUuid(appointment.patient_mobile);
      if (!recordUuid) { toast.error('پرونده‌ای برای این بیمار یافت نشد'); return; }
      navigate(`/admin/patients/${recordUuid}/session/new`);
    } catch { toast.error('خطا در یافتن پرونده بیمار'); }
  };

  const items: { label: string; icon: React.ElementType; onClick: () => void }[] = [
    { label: 'ویرایش', icon: PencilIcon, onClick: () => { setOpen(false); navigate(`/admin/appointments/${appointment.uuid}/edit`); } },
    { label: 'ثبت سرویس', icon: PlusIcon, onClick: goToServiceRegistration },
    { label: 'مشاهده', icon: EyeIcon, onClick: () => { setOpen(false); setModal('info'); } },
    { label: 'جا به جایی نوبت', icon: ArrowsRightLeftIcon, onClick: () => { setOpen(false); setModal('move'); } },
    { label: appointment.is_reserve ? 'انتقال به لیست نوبت‌ها' : 'انتقال به لیست رزرو', icon: ArrowDownOnSquareIcon, onClick: () => { setOpen(false); setModal('transfer'); } },
    { label: 'جایگزینی نوبت', icon: ArrowPathIcon, onClick: () => { setOpen(false); setModal('replace'); } },
  ];

  return (
    <>
      <button ref={btnRef} onClick={openMenu} aria-label="عملیات" className="btn sm ghost" style={{ color: 'var(--primary)', gap: 4 }}>
        <EllipsisHorizontalIcon style={{ width: 18 }} /> عملیات
      </button>

      {open && menuPos && ReactDOM.createPortal(
        <div ref={menuRef} style={{
          position: 'fixed', top: menuPos.top, right: menuPos.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 === 'move' && <MoveAppointmentModal appointment={appointment} queryKey={queryKey} onClose={() => setModal(null)} />}
      {modal === 'transfer' && <TransferReserveModal appointment={appointment} queryKey={queryKey} onClose={() => setModal(null)} />}
      {modal === 'replace' && <ReplaceAppointmentModal appointment={appointment} queryKey={queryKey} onClose={() => setModal(null)} />}
    </>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// مشاهده — appointment info + patient wallet balance (Figma appointments-info)
// ─────────────────────────────────────────────────────────────────────────────

function InfoRow({ icon: Icon, label, value, ltr }: { icon: React.ElementType; label: string; value?: string | null; ltr?: boolean }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '11px 0', borderBottom: '1px solid var(--border)', gap: 12 }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 13, color: 'var(--text-2)' }}>
        <Icon style={{ width: 16, color: 'var(--text-3)' }} /> {label}
      </span>
      <span style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--text)', direction: ltr ? 'ltr' : undefined }}>{value || '—'}</span>
    </div>
  );
}

export function AppointmentInfoModal({ appointment: a, queryKey, onClose }: {
  appointment: Appointment; queryKey: unknown[]; onClose: () => void;
}) {
  const navigate = useNavigate();

  // record uuid → wallet balance + «مشاهده پرونده» target (both need the record)
  const recordQ = useQuery<string | null>({
    queryKey: ['appt-record', a.patient_mobile],
    queryFn: () => findRecordUuid(a.patient_mobile),
  });
  const walletQ = useQuery<ApiResponse<{ balance_rials: number }>>({
    queryKey: ['appt-wallet', recordQ.data],
    queryFn: () => api.get(`/api/v1/patient/${recordQ.data}/wallet`),
    enabled: !!recordQ.data,
  });

  const durationMin = Math.max(0, Math.round((a.slot_end - a.slot_start) / 60));

  return (
    <Modal open title={a.patient_name || 'نوبت'} onClose={onClose}>
      <div>
        <InfoRow icon={ClockIcon} label="ساعت شروع:" value={a.appointment_time} ltr />
        <InfoRow icon={ClockIcon} label="مدت انجام:" value={`${durationMin.toLocaleString('fa-IR')} دقیقه`} />
        <InfoRow icon={PhoneIcon} label="تلفن:" value={a.patient_mobile} ltr />
        <InfoRow icon={Squares2X2Icon} label="بخش:" value={a.service_section?.name} />
        <InfoRow icon={TagIcon} label="سرویس:" value={a.service_item?.name} />
        <InfoRow icon={UserIcon} label="پرسنل:" value={a.staff?.full_name} />
        <InfoRow icon={WalletIcon} label="موجودی کیف پول:"
          value={walletQ.data?.data ? `${formatRial(walletQ.data.data.balance_rials)}` : undefined} />

        <div style={{ margin: '14px 0' }}>
          <AppointmentStatusDropdown uuid={a.uuid} currentStatus={a.status} version={a.version} queryKey={queryKey} />
        </div>

        <button className="btn" style={{ width: '100%', color: 'var(--primary)', border: '1px solid var(--primary-soft2, var(--border))', background: 'var(--primary-soft)' }}
          disabled={!recordQ.data}
          onClick={() => recordQ.data && navigate(`/admin/patients/${recordQ.data}`)}>
          مشاهده پرونده
        </button>
      </div>
    </Modal>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// جا به جایی نوبت — pick a new date + start/end time
// ─────────────────────────────────────────────────────────────────────────────

export function MoveAppointmentModal({ appointment: a, queryKey, onClose }: {
  appointment: Appointment; queryKey: unknown[]; onClose: () => void;
}) {
  const qc = useQueryClient();
  const [date, setDate] = useState(a.appointment_date);
  const [start, setStart] = useState(a.appointment_time);
  const [end, setEnd] = useState(a.end_time);

  const move = useMutation({
    mutationFn: () => api.patch(`/api/v1/appointment/${a.uuid}`, {
      slot_start: toEpoch(date, start), slot_end: toEpoch(date, end), version: a.version,
    }),
    onSuccess: () => { qc.invalidateQueries({ queryKey }); toast.success('نوبت جا به جا شد'); onClose(); },
    onError: (e: any) => toast.error(e.message || 'خطا در جا به جایی نوبت'),
  });

  return (
    <Modal open title="جا به جایی نوبت" onClose={onClose}>
      <div>
        <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>انتخاب تاریخ</label>
        <div style={{ margin: '6px 0 12px' }}><PersianDateInput value={date} onChange={setDate} /></div>
        <div style={{ display: 'flex', gap: 10, marginBottom: 16 }}>
          <div style={{ flex: 1 }}>
            <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>ساعت شروع</label>
            <div className="field" style={{ marginTop: 6 }}><input aria-label="ساعت شروع" type="time" value={start} onChange={e => setStart(e.target.value)} dir="ltr" /></div>
          </div>
          <div style={{ flex: 1 }}>
            <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>ساعت پایان</label>
            <div className="field" style={{ marginTop: 6 }}><input aria-label="ساعت پایان" type="time" value={end} onChange={e => setEnd(e.target.value)} dir="ltr" /></div>
          </div>
        </div>
        <button className="btn primary" style={{ width: '100%' }} disabled={!date || !start || !end || move.isPending} onClick={() => move.mutate()}>
          اعمال تغییرات
        </button>
      </div>
    </Modal>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// انتقال به لیست رزرو (و بازگشت) — flips is_reserve for a chosen day
// ─────────────────────────────────────────────────────────────────────────────

export function TransferReserveModal({ appointment: a, queryKey, onClose }: {
  appointment: Appointment; queryKey: unknown[]; onClose: () => void;
}) {
  const qc = useQueryClient();
  const [date, setDate] = useState(a.appointment_date);
  const toReserve = !a.is_reserve;

  const transfer = useMutation({
    mutationFn: () => {
      const day = toEpoch(date, '00:00');
      return api.patch(`/api/v1/appointment/${a.uuid}`, toReserve
        // reserve entries are day-level: midnight-to-midnight, no slot occupation
        ? { is_reserve: true, slot_start: day, slot_end: day, version: a.version }
        : { is_reserve: false, slot_start: toEpoch(date, a.appointment_time), slot_end: toEpoch(date, a.end_time), version: a.version });
    },
    onSuccess: () => { qc.invalidateQueries({ queryKey }); toast.success(toReserve ? 'به لیست رزرو منتقل شد' : 'به لیست نوبت‌ها منتقل شد'); onClose(); },
    onError: (e: any) => toast.error(e.message || 'خطا در انتقال'),
  });

  return (
    <Modal open title={toReserve ? 'انتقال به لیست رزرو' : 'انتقال به لیست نوبت‌ها'} onClose={onClose}>
      <div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', background: 'var(--warning-bg)', border: '1px solid var(--border)', borderRadius: 'var(--r)', padding: '10px 12px', marginBottom: 14, fontSize: 12.5, color: 'var(--text-2)' }}>
          <span style={{ color: 'var(--warning)', fontWeight: 800 }}>!</span>
          {toReserve
            ? 'نوبت از لیست نوبت های تایید شده حذف شده و به لیست نوبت های رزرو شده منتقل می شود.'
            : 'نوبت از لیست رزرو حذف شده و به لیست نوبت های تایید شده منتقل می شود.'}
        </div>
        <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>انتخاب تاریخ</label>
        <div style={{ margin: '6px 0 16px' }}><PersianDateInput value={date} onChange={setDate} /></div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn primary" style={{ flex: 1 }} disabled={!date || transfer.isPending} onClick={() => transfer.mutate()}>
            انتقال و حذف از لیست
          </button>
          <button className="btn" style={{ flex: 1 }} onClick={onClose}>انصراف</button>
        </div>
      </div>
    </Modal>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// جایگزینی نوبت — put a different patient into the same slot
// ─────────────────────────────────────────────────────────────────────────────

export function ReplaceAppointmentModal({ appointment: a, queryKey, onClose }: {
  appointment: Appointment; queryKey: unknown[]; onClose: () => void;
}) {
  const qc = useQueryClient();
  const [name, setName] = useState('');
  const [mobile, setMobile] = useState('');
  const [note, setNote] = useState('');

  const replace = useMutation({
    mutationFn: () => api.patch(`/api/v1/appointment/${a.uuid}`, {
      patient_name: name.trim(), patient_mobile: mobile.trim(),
      ...(note.trim() ? { note: note.trim() } : {}),
      version: a.version,
    }),
    onSuccess: () => { qc.invalidateQueries({ queryKey }); toast.success('نوبت جایگزین شد'); onClose(); },
    onError: (e: any) => toast.error(e.message || 'خطا در جایگزینی نوبت'),
  });

  return (
    <Modal open title="جایگزینی نوبت" onClose={onClose}>
      <div>
        <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>نام و نام خانوادگی</label>
        <div className="field" style={{ margin: '6px 0 12px' }}>
          <input value={name} onChange={e => setName(e.target.value)} placeholder="نام و نام خانوادگی مراجعه کننده" />
        </div>
        <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>شماره تماس</label>
        <div className="field" style={{ margin: '6px 0 12px' }}>
          <input value={mobile} onChange={e => setMobile(e.target.value)} placeholder="شماره تماس" dir="ltr" />
        </div>
        <label style={{ fontSize: 12.5, color: 'var(--text-3)' }}>توضیحات</label>
        <div className="field" style={{ height: 'auto', margin: '6px 0 16px' }}>
          <textarea value={note} onChange={e => setNote(e.target.value)} rows={3} placeholder="توضیحات..."
            style={{ width: '100%', border: 'none', background: 'transparent', fontFamily: 'inherit', resize: 'vertical' }} />
        </div>
        <button className="btn primary" style={{ width: '100%' }}
          disabled={name.trim().length < 2 || mobile.trim().length < 10 || replace.isPending}
          onClick={() => replace.mutate()}>
          ثبت نوبت
        </button>
      </div>
    </Modal>
  );
}
