import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { MagnifyingGlassIcon, PencilSquareIcon, XMarkIcon } from '@heroicons/react/24/outline';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import PageHeader from '../components/ui/PageHeader';
import StatusBadge from '../components/ui/StatusBadge';
import { formatDate, formatDateTime, formatNumber } from '../lib/utils';
import { useUrlState } from '../hooks/useUrlState';
import TreatmentCaseEditModal from '../components/TreatmentCaseEditModal';
import type { TreatmentCaseSummary, StaffTreatmentSession, SlotSuggestionResponse } from '../types';

const TABS = [
  { id: 'cases',    label: 'پرونده‌های درمان' },
  { id: 'unbooked', label: 'جلسات بدون نوبت' },
] as const;

type TabId = typeof TABS[number]['id'];

const CASE_STATUS_LABEL: Record<TreatmentCaseSummary['status'], string> = {
  active:    'در جریان',
  completed: 'تمام شده',
  abandoned: 'رها شده',
};

/**
 * پرونده‌های درمان و کارِ باقی‌ماندهٔ منشی.
 *
 * صفِ «جلسات بدون نوبت» عمداً کنار فهرست پرونده‌هاست نه صفحهٔ جدا: هر دو یک سؤال
 * را جواب می‌دهند — «کدام بیمار در چه مرحله‌ای است و چه کاری مانده».
 */
export default function TreatmentCasesPage() {
  const [urlState, setUrlState] = useUrlState({ tab: 'cases', status: '', q: '' });
  const tab = (TABS.some((t) => t.id === urlState.tab) ? urlState.tab : 'cases') as TabId;

  return (
    <>
      <PageHeader title="درمان‌های چندجلسه‌ای" />

      <div className="tabs" style={{ marginBottom: 16 }}>
        {TABS.map((t) => (
          <button
            key={t.id}
            type="button"
            className={tab === t.id ? 'active' : ''}
            onClick={() => setUrlState({ tab: t.id })}
          >
            {t.label}
          </button>
        ))}
      </div>

      {tab === 'cases'
        ? <CasesTab
            status={urlState.status}
            onStatus={(s) => setUrlState({ status: s })}
            search={urlState.q}
            onSearch={(q) => setUrlState({ q })}
          />
        : <UnbookedTab />}
    </>
  );
}

const STATUS_FILTERS = [
  ['',          'همه'],
  ['active',    'در جریان'],
  ['completed', 'تمام شده'],
  ['abandoned', 'رها شده'],
] as const;

function CasesTab({ status, onStatus, search, onSearch }: {
  status: string;
  onStatus: (s: string) => void;
  search: string;
  onSearch: (s: string) => void;
}) {
  // فیلد جستجو محلی می‌ماند و فقط مقدار نهایی به URL می‌رود؛ وگرنه هر حرف یک ورودی
  // تاریخچه می‌سازد و «بازگشت» بی‌معنی می‌شود.
  const [term, setTerm] = useState(search);
  useEffect(() => setTerm(search), [search]);
  useEffect(() => {
    const t = setTimeout(() => { if (term !== search) onSearch(term); }, 350);
    return () => clearTimeout(t);
  }, [term]);

  const [editing, setEditing] = useState<string | null>(null);

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ['treatment-cases', status, search],
    queryFn: () => {
      const qs = new URLSearchParams();
      if (status) qs.set('status', status);
      if (search) qs.set('q', search);
      const suffix = qs.toString();

      return api.get<ApiResponse<TreatmentCaseSummary[]>>(
        `/api/v1/treatment-cases${suffix ? `?${suffix}` : ''}`,
      );
    },
    staleTime: 30_000,
  });

  const cases = data?.data ?? [];

  return (
    <>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center', marginBottom: 14 }}>
        <div className="field" style={{ flex: '1 1 260px', maxWidth: 380 }}>
          <MagnifyingGlassIcon style={{ width: 16, height: 16, flexShrink: 0, color: 'var(--text-3)' }} />
          <input
            value={term}
            onChange={(e) => setTerm(e.target.value)}
            placeholder="نام بیمار، موبایل، کد ملی، شمارهٔ پرونده یا سرویس"
            aria-label="جستجوی پرونده"
          />
          {term !== '' && (
            <button type="button" className="mini-btn" aria-label="پاک کردن جستجو" onClick={() => setTerm('')}>
              <XMarkIcon style={{ width: 15, height: 15 }} />
            </button>
          )}
        </div>

        <div className="seg">
          {STATUS_FILTERS.map(([v, label]) => (
            <button
              key={v}
              type="button"
              className={status === v ? 'on' : ''}
              aria-pressed={status === v}
              onClick={() => onStatus(v)}
            >
              {label}
            </button>
          ))}
        </div>
      </div>

      {isLoading ? (
        <div style={{ display: 'grid', gap: 12 }}>
          {[0, 1].map((i) => <div key={i} className="card" style={{ height: 96 }} />)}
        </div>
      ) : isError ? (
        /* خطای سرور نباید «پرونده‌ای یافت نشد» خوانده شود — آن یعنی جستجو نتیجه نداشت. */
        <div className="card card-pad" style={{ display: 'grid', gap: 10, justifyItems: 'start' }}>
          <span style={{ fontSize: 13, color: 'var(--danger)' }}>خواندن پرونده‌ها ناموفق بود.</span>
          <button type="button" className="btn secondary sm" onClick={() => refetch()}>تلاش دوباره</button>
        </div>
      ) : cases.length === 0 ? (
        <div className="card card-pad" style={{ fontSize: 13, color: 'var(--text-3)', lineHeight: 1.9 }}>
          {search
            ? `برای «${search}» پرونده‌ای پیدا نشد.`
            : 'پرونده‌ای یافت نشد. پرونده وقتی ساخته می‌شود که نوبتِ سرویسی با «طول درمان» قطعی شود.'}
        </div>
      ) : (
        <div style={{ display: 'grid', gap: 12 }}>
          {cases.map((c) => <CaseCard key={c.uuid} item={c} onEdit={() => setEditing(c.uuid)} />)}
        </div>
      )}

      {editing !== null && (
        <TreatmentCaseEditModal caseUuid={editing} onClose={() => setEditing(null)} />
      )}
    </>
  );
}

function CaseCard({ item: c, onEdit }: { item: TreatmentCaseSummary; onEdit: () => void }) {
  const percent = c.total_sessions > 0
    ? Math.round((c.completed_sessions / c.total_sessions) * 100)
    : 0;

  return (
    <div className="card card-pad" style={{ display: 'grid', gap: 10 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        {/* بیمار سرتیتر است نه سرویس: دو پروندهٔ یک سرویس فقط با نام بیمار از هم جدا می‌شوند. */}
        <strong style={{ fontSize: 14 }}>{c.patient.name || 'بیمار بدون نام'}</strong>
        <span className={`badge ${c.status === 'active' ? 'blue' : c.status === 'completed' ? 'green' : 'gray'}`}>
          <span className="bdot" />{CASE_STATUS_LABEL[c.status]}
        </span>
        <span style={{ fontSize: 12.5, color: 'var(--text-3)' }}>
          {formatNumber(c.completed_sessions)} از {formatNumber(c.total_sessions)} جلسه
        </span>
        <button type="button" className="btn secondary sm" style={{ marginInlineStart: 'auto' }} onClick={onEdit}>
          <PencilSquareIcon style={{ width: 15, height: 15 }} />
          ویرایش
        </button>
      </div>

      <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', fontSize: 12.5, color: 'var(--text-2)' }}>
        <span>{c.service.name}</span>
        <span style={{ direction: 'ltr' }}>{c.patient.mobile}</span>
        <span>شروع: {formatDate(c.opened_at)}</span>
        {c.supervisor && <span>پزشک ناظر: {c.supervisor.name}</span>}
        {c.areas.length > 0 && <span>نواحی: {c.areas.map((a) => a.name).join('، ')}</span>}
      </div>

      {/* `<progress>` نیتیو ظاهر مرورگر را می‌گیرد و با توکن‌های تم نمی‌خواند. */}
      <div
        role="progressbar"
        aria-valuenow={c.completed_sessions}
        aria-valuemin={0}
        aria-valuemax={c.total_sessions}
        aria-label={`پیشرفت دوره: ${c.completed_sessions} از ${c.total_sessions}`}
        style={{ height: 6, borderRadius: 999, background: 'var(--surface-3)', overflow: 'hidden' }}
      >
        <div style={{
          width: `${percent}%`, height: '100%', borderRadius: 999,
          background: c.status === 'completed' ? 'var(--success)' : 'var(--primary)',
          transition: 'width .3s var(--ease)',
        }} />
      </div>
    </div>
  );
}

function UnbookedTab() {
  const { data, isLoading } = useQuery({
    queryKey: ['treatment-sessions-unbooked'],
    queryFn: () => api.get<ApiResponse<StaffTreatmentSession[]>>('/api/v1/treatment-sessions/unbooked?within_days=14'),
    staleTime: 30_000,
  });

  const sessions = data?.data ?? [];

  return (
    <>
      <p style={{ margin: '0 0 12px', fontSize: 12.5, color: 'var(--text-3)', lineHeight: 1.9 }}>
        جلساتی که سررسیدشان رسیده و هنوز نوبت نگرفته‌اند. رزرو عمداً خودکار نیست — وقتِ مناسب را
        باید با خود بیمار هماهنگ کرد.
      </p>

      {isLoading ? (
        <div className="card card-pad" style={{ fontSize: 13, color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : sessions.length === 0 ? (
        <div className="card card-pad" style={{ fontSize: 13, color: 'var(--text-3)' }}>
          جلسه‌ای در انتظار رزرو نیست.
        </div>
      ) : (
        <div style={{ display: 'grid', gap: 12 }}>
          {sessions.map((s) => (
            <div key={s.uuid} className="card card-pad" style={{ display: 'grid', gap: 8 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                <strong style={{ fontSize: 14 }}>{s.service_name}</strong>
                <StatusBadge type="treatment-session" value={s.status} />
                <span style={{ fontSize: 12.5, color: 'var(--text-3)' }}>
                  جلسهٔ {s.session_number} از {s.total_sessions}
                </span>
              </div>

              {s.due_at !== null && (
                <span style={{ fontSize: 12.5, color: 'var(--warning)' }}>
                  سررسید: {formatDate(s.due_at)}
                </span>
              )}

              <SlotSuggestions sessionUuid={s.uuid} />
            </div>
          ))}
        </div>
      )}
    </>
  );
}

/**
 * وقت‌های آزادِ همان دستگاهی که جلسهٔ قبلی رویش انجام شد.
 *
 * پیشنهاد است نه رزرو: منشی با بیمار هماهنگ می‌کند و بعد از فرم عادی نوبت ثبتش
 * می‌کند. خودکار رزرو کردن یعنی سیستم به‌جای بیمار تصمیم بگیرد و بعد او نیاید.
 */
function SlotSuggestions({ sessionUuid }: { sessionUuid: string }) {
  const [open, setOpen] = useState(false);

  const { data, isLoading, isError } = useQuery({
    queryKey: ['session-slot-suggestions', sessionUuid],
    queryFn: () => api.get<ApiResponse<SlotSuggestionResponse>>(
      `/api/v1/treatment-session/${sessionUuid}/slot-suggestions?days=14`,
    ),
    enabled: open,
    staleTime: 60_000,
  });

  if (!open) {
    return (
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        <button type="button" className="btn secondary sm" onClick={() => setOpen(true)}>
          پیشنهاد وقت
        </button>
        <Link to="/admin/appointments/new" className="btn primary sm">ثبت نوبت این جلسه</Link>
      </div>
    );
  }

  const days = data?.data?.days ?? [];

  return (
    <div style={{ display: 'grid', gap: 8 }}>
      {isLoading && <span style={{ fontSize: 12.5, color: 'var(--text-3)' }}>در حال جست‌وجوی وقت...</span>}

      {isError && (
        <span style={{ fontSize: 12.5, color: 'var(--text-3)' }}>
          دستگاهی برای پیشنهاد وقت مشخص نیست — این جلسه هنوز روی هیچ دستگاهی انجام نشده.
        </span>
      )}

      {!isLoading && !isError && days.length === 0 && (
        <span style={{ fontSize: 12.5, color: 'var(--text-3)' }}>
          در دو هفتهٔ آینده وقت آزادی روی این دستگاه نیست.
        </span>
      )}

      {days.slice(0, 3).map((day) => (
        <div key={day.date} style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
          <span style={{ fontSize: 12.5, minWidth: 96, color: 'var(--text-2)' }}>
            {formatDate(Math.floor(new Date(day.date).getTime() / 1000))}
          </span>
          {day.slots.slice(0, 6).map((slot) => (
            <Link
              key={slot.start}
              to={`/admin/appointments/new?slot_start=${slot.start}&resource_uuid=${data?.data?.resource_uuid ?? ''}`}
              className="btn secondary sm"
              title={formatDateTime(slot.start)}
            >
              {slot.start_time}
            </Link>
          ))}
        </div>
      ))}

      <button type="button" className="btn ghost sm" onClick={() => setOpen(false)} style={{ justifySelf: 'start' }}>
        بستن
      </button>
    </div>
  );
}
