import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ChevronDownIcon } from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../../lib/api';
import ConfirmAppointmentModal from '../appointments/ConfirmAppointmentModal';

// Labels follow the Figma نوبت‌ها design (ثبت شده / قطعی شده / ویزیت شده …).
export const STATUS_META: Record<string, { label: string; color: string }> = {
  pending:              { label: 'ثبت شده',         color: 'var(--info)' },
  confirmed:            { label: 'قطعی شده',        color: 'var(--primary)' },
  following_up:         { label: 'در حال پیگیری',   color: 'var(--warning)' },
  salon:                { label: 'سالن',             color: 'var(--violet)' },
  completed:            { label: 'ویزیت شده',       color: 'var(--success)' },
  cancelled_by_doctor:  { label: 'لغو شده',          color: 'var(--danger)' },
  cancelled_by_user:    { label: 'لغو توسط بیمار',  color: 'var(--danger)' },
  no_show:              { label: 'غیبت',             color: 'var(--text-3)' },
  expired:              { label: 'منقضی شده',        color: 'var(--text-3)' },
};

// Mirrors Appointment::ALLOWED_TRANSITIONS on the backend.
const TRANSITIONS: Record<string, string[]> = {
  pending:      ['confirmed', 'following_up', 'cancelled_by_doctor', 'cancelled_by_user'],
  confirmed:    ['completed', 'following_up', 'salon', 'cancelled_by_doctor', 'cancelled_by_user', 'no_show'],
  following_up: ['confirmed', 'salon', 'completed', 'cancelled_by_doctor', 'cancelled_by_user', 'no_show'],
  salon:        ['completed', 'following_up', 'cancelled_by_doctor', 'cancelled_by_user', 'no_show'],
};

interface Props {
  uuid: string;
  currentStatus: string;
  version: number;
  queryKey: unknown[];
}

export default function AppointmentStatusDropdown({ uuid, currentStatus, version, queryKey }: Props) {
  const [open, setOpen] = useState(false);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [menuPos, setMenuPos] = useState<{ top: number; right: number } | null>(null);
  const btnRef  = useRef<HTMLButtonElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  const qc = useQueryClient();

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

  // Reposition on scroll/resize while open
  useEffect(() => {
    if (!open) return;
    function reposition() {
      if (btnRef.current) {
        const rect = btnRef.current.getBoundingClientRect();
        setMenuPos({ top: rect.bottom + 4, right: window.innerWidth - rect.right });
      }
    }
    window.addEventListener('scroll', reposition, true);
    window.addEventListener('resize', reposition);
    return () => {
      window.removeEventListener('scroll', reposition, true);
      window.removeEventListener('resize', reposition);
    };
  }, [open]);

  const mutation = useMutation({
    mutationFn: (newStatus: string) =>
      api.patch(`/api/v1/appointment/${uuid}/status`, { status: newStatus, version }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey });
      setOpen(false);
    },
    // پیام سرور را نشان بده: تداخل نسخه (۴۰۹) و نبودِ دسترسی (۴۰۳) پیام فارسی
    // دقیق دارند و «خطا در تغییر وضعیت» آن را پنهان می‌کرد.
    onError: (e: any) => toast.error(e?.message || 'خطا در تغییر وضعیت'),
  });

  const meta = STATUS_META[currentStatus] ?? { label: currentStatus, color: 'var(--text-3)' };
  const nextStatuses = TRANSITIONS[currentStatus] ?? [];

  function handleToggle() {
    if (!open && btnRef.current) {
      const rect = btnRef.current.getBoundingClientRect();
      setMenuPos({ top: rect.bottom + 4, right: window.innerWidth - rect.right });
    }
    setOpen(o => !o);
  }

  /**
   * «قطعی شده» راه میان‌بر ندارد: قطعی‌کردن یعنی ثبت هزینه‌ها و پرداخت در پرونده،
   * پس همیشه از مودال رد می‌شود. بقیهٔ وضعیت‌ها همان PATCH ساده‌اند.
   */
  function handlePick(status: string) {
    if (status === 'confirmed') {
      setOpen(false);
      setConfirmOpen(true);
      return;
    }
    mutation.mutate(status);
  }

  return (
    <div style={{ position: 'relative', display: 'inline-block' }}>
      <button
        ref={btnRef}
        onClick={handleToggle}
        disabled={nextStatuses.length === 0}
        style={{
          display: 'inline-flex', alignItems: 'center', gap: 5,
          padding: '3px 10px', borderRadius: 99, fontSize: 12, fontWeight: 700,
          border: `1.5px solid ${meta.color}30`,
          background: `${meta.color}15`,
          color: meta.color,
          cursor: nextStatuses.length > 0 ? 'pointer' : 'default',
          whiteSpace: 'nowrap',
        }}
      >
        <span style={{ width: 7, height: 7, borderRadius: '50%', background: meta.color, flexShrink: 0 }} />
        {meta.label}
        {nextStatuses.length > 0 && (
          <ChevronDownIcon style={{ width: 12, height: 12, flexShrink: 0 }} />
        )}
      </button>

      {open && menuPos && nextStatuses.length > 0 && 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: 160, overflow: 'hidden',
          }}
        >
          {nextStatuses.map(s => {
            const sm = STATUS_META[s] ?? { label: s, color: 'var(--text-3)' };
            return (
              <button
                key={s}
                onClick={() => handlePick(s)}
                disabled={mutation.isPending}
                style={{
                  display: 'flex', alignItems: 'center', gap: 8,
                  width: '100%', padding: '8px 12px', fontSize: 13,
                  background: 'transparent', border: 'none', cursor: 'pointer',
                  color: sm.color, fontWeight: 400,
                  textAlign: 'right',
                }}
                onMouseEnter={e => (e.currentTarget.style.background = 'var(--surface-2)')}
                onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
              >
                <span style={{
                  width: 10, height: 10, borderRadius: '50%', flexShrink: 0,
                  border: `2px solid ${sm.color}`,
                }} />
                {sm.label}
              </button>
            );
          })}
        </div>,
        document.body
      )}

      <ConfirmAppointmentModal
        open={confirmOpen}
        appointmentUuid={uuid}
        onClose={() => setConfirmOpen(false)}
        queryKey={queryKey}
      />
    </div>
  );
}
