import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { api, ApiError } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import Modal from './ui/Modal';
import Input from './ui/Input';
import SearchableSelect from './ui/SearchableSelect';
import { formatNumber } from '../lib/utils';
import type { TreatmentCaseDetail, TreatmentCaseStatus } from '../types';

const STATUS_OPTIONS: Array<{ value: TreatmentCaseStatus; label: string }> = [
  { value: 'active',    label: 'در جریان' },
  { value: 'completed', label: 'تمام شده' },
  { value: 'abandoned', label: 'رها شده' },
];

interface DoctorRow { uuid: string; name?: string | null; full_name?: string | null }
interface StaffRow { uuid: string; full_name: string }

/**
 * ویرایش پروندهٔ درمان.
 *
 * پرونده بعد از باز شدن سند است نه فرم، پس فقط چیزهایی اینجا هستند که واقعاً وسط دوره
 * عوض می‌شوند. سرور جلوی ویرایشی را که سابقه را بازنویسی کند می‌گیرد؛ فرم آن خطا را
 * نشان می‌دهد، تکرارش نمی‌کند.
 */
export default function TreatmentCaseEditModal({ caseUuid, onClose }: {
  caseUuid: string;
  onClose: () => void;
}) {
  const qc = useQueryClient();

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ['treatment-case', caseUuid],
    queryFn: () => api.get<ApiResponse<TreatmentCaseDetail>>(`/api/v1/treatment-case/${caseUuid}`),
  });

  // همان اندپوینتی که صفحهٔ نوبت‌ها می‌خواند: فقط پزشکانِ مجازِ همین محیط.
  // پاسخش دو لایه تو در تو است (`data.data`) — الگوی شناخته‌شدهٔ همین اندپوینت.
  const doctorsQ = useQuery<ApiResponse<{ data: DoctorRow[] }>>({
    queryKey: ['clinic-doctors-lite'],
    queryFn: () => api.get('/api/v1/my/clinic-doctors'),
    staleTime: 60_000,
  });

  const staffQ = useQuery<ApiResponse<StaffRow[]>>({
    queryKey: ['staff-list'],
    queryFn: () => api.get('/api/v1/staff'),
    staleTime: 60_000,
  });

  const detail = data?.data;

  return (
    <Modal open title="ویرایش پروندهٔ درمان" size="sm" onClose={onClose} footer={null}>
      {isLoading ? (
        <div style={{ fontSize: 13, color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : isError || !detail ? (
        <div 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>
      ) : (
        <EditForm
          detail={detail}
          doctors={doctorsQ.data?.data?.data ?? []}
          doctorsLoading={doctorsQ.isLoading}
          staff={staffQ.data?.data ?? []}
          onSaved={() => {
            qc.invalidateQueries({ queryKey: ['treatment-cases'] });
            qc.invalidateQueries({ queryKey: ['treatment-case', caseUuid] });
            onClose();
          }}
          onClose={onClose}
        />
      )}
    </Modal>
  );
}

function EditForm({ detail, doctors, doctorsLoading, staff, onSaved, onClose }: {
  detail: TreatmentCaseDetail;
  doctors: DoctorRow[];
  doctorsLoading: boolean;
  staff: StaffRow[];
  onSaved: () => void;
  onClose: () => void;
}) {
  const [status, setStatus] = useState<TreatmentCaseStatus>(detail.status);
  const [supervisor, setSupervisor] = useState<string | null>(detail.supervisor?.uuid ?? null);
  const [total, setTotal] = useState(String(detail.total_sessions));
  const [areas, setAreas] = useState<string[]>(
    detail.areas.map((a) => a.category_uuid).filter((u): u is string => u !== null),
  );
  const [staffUuids, setStaffUuids] = useState<string[]>(detail.assigned_staff.map((s) => s.uuid));

  // ناحیه‌ای که دسته‌اش حذف شده در سابقه هست ولی دیگر قابل انتخاب نیست — باید دیده
  // شود، وگرنه کاربر فکر می‌کند فرم آن را انداخته است.
  const orphanAreas = useMemo(
    () => detail.areas.filter((a) => a.category_uuid === null).map((a) => a.name),
    [detail.areas],
  );

  const minTotal = detail.completed_sessions;

  const save = useMutation({
    mutationFn: () => api.patch<ApiResponse<TreatmentCaseDetail>>(`/api/v1/treatment-case/${detail.uuid}`, {
      status,
      supervisor_doctor_uuid: supervisor,
      area_uuids: areas,
      staff_uuids: staffUuids,
      total_sessions: Number(total) || 0,
    }),
    onSuccess: () => { toast.success('پرونده به‌روزرسانی شد'); onSaved(); },
    onError: (e: unknown) => toast.error(e instanceof ApiError ? e.message : 'ویرایش پرونده ناموفق بود'),
  });

  const toggleArea = (uuid: string) =>
    setAreas((prev) => prev.includes(uuid) ? prev.filter((u) => u !== uuid) : [...prev, uuid]);
  const toggleStaff = (uuid: string) =>
    setStaffUuids((prev) => prev.includes(uuid) ? prev.filter((u) => u !== uuid) : [...prev, uuid]);

  const totalValid = Number(total) >= 2 && Number(total) <= 60;
  const valid = areas.length > 0 && totalValid;

  return (
    <div style={{ display: 'grid', gap: 16 }}>
      <div style={{
        padding: '10px 14px', borderRadius: 'var(--r-sm)', background: 'var(--primary-soft)',
        display: 'flex', gap: 14, flexWrap: 'wrap', fontSize: 13,
      }}>
        <span>
          <span style={{ color: 'var(--text-3)' }}>بیمار: </span>
          <b>{detail.patient.name || 'بدون نام'}</b>
        </span>
        <span>
          <span style={{ color: 'var(--text-3)' }}>سرویس: </span>
          <b>{detail.service.name}</b>
        </span>
      </div>

      <div className="field-block">
        <label>وضعیت پرونده</label>
        <div className="seg" style={{ display: 'flex' }}>
          {STATUS_OPTIONS.map((o) => (
            <button
              key={o.value}
              type="button"
              className={status === o.value ? 'on' : ''}
              aria-pressed={status === o.value}
              onClick={() => setStatus(o.value)}
              style={{ flex: 1, justifyContent: 'center' }}
            >
              {o.label}
            </button>
          ))}
        </div>
      </div>

      <div className="field-block">
        <label htmlFor="case-supervisor">پزشک ناظر</label>
        <SearchableSelect
          inputId="case-supervisor"
          options={doctors.map((d) => ({ value: d.uuid, label: d.name ?? d.full_name ?? '' }))}
          value={supervisor}
          onChange={(v) => setSupervisor(v === null ? null : String(v))}
          placeholder="بدون پزشک ناظر"
          isLoading={doctorsLoading}
          isClearable
          height={40}
        />
      </div>

      <div className="field-block">
        <label>نواحی درمان</label>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {detail.available_areas.map((a) => {
            const on = areas.includes(a.uuid);
            return (
              <button
                key={a.uuid}
                type="button"
                role="checkbox"
                aria-checked={on}
                onClick={() => toggleArea(a.uuid)}
                style={{
                  minHeight: 36, padding: '6px 12px', borderRadius: 'var(--r-sm)',
                  cursor: 'pointer', fontFamily: 'inherit', fontSize: 13,
                  border: on ? '1px solid var(--primary)' : '1px solid var(--border)',
                  background: on ? 'var(--primary-soft)' : 'var(--surface)',
                  color: on ? 'var(--primary-700)' : 'var(--text-2)',
                  fontWeight: on ? 600 : 400,
                }}
              >
                {a.name}
              </button>
            );
          })}
        </div>
        {areas.length === 0 && <span className="field-err">حداقل یک ناحیه لازم است</span>}
        {orphanAreas.length > 0 && (
          <span className="field-hint">
            نواحیِ «{orphanAreas.join('، ')}» در سابقه هستند ولی دسته‌بندی‌شان حذف شده و قابل انتخاب نیستند.
          </span>
        )}
      </div>

      <div className="field-block">
        <label>اپراتور</label>
        {staff.length === 0 ? (
          <span className="field-hint">پرسنلی در این محیط تعریف نشده است.</span>
        ) : (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {staff.map((p) => {
              const on = staffUuids.includes(p.uuid);
              return (
                <button
                  key={p.uuid}
                  type="button"
                  role="checkbox"
                  aria-checked={on}
                  onClick={() => toggleStaff(p.uuid)}
                  style={{
                    minHeight: 36, padding: '6px 12px', borderRadius: 'var(--r-sm)',
                    cursor: 'pointer', fontFamily: 'inherit', fontSize: 13,
                    border: on ? '1px solid var(--primary)' : '1px solid var(--border)',
                    background: on ? 'var(--primary-soft)' : 'var(--surface)',
                    color: on ? 'var(--primary-700)' : 'var(--text-2)',
                    fontWeight: on ? 600 : 400,
                  }}
                >
                  {p.full_name}
                </button>
              );
            })}
          </div>
        )}
        <span className="field-hint">
          {staffUuids.length === 0
            ? 'خالی یعنی هر پرسنلِ مجازِ این سرویس می‌تواند جلسات را انجام دهد.'
            : 'جلسات این پرونده فقط در صف همین افراد دیده می‌شود.'}
        </span>
        {detail.performed_by.length > 0 && (
          <span className="field-hint">
            تا اینجا انجام‌دهنده: {detail.performed_by.map((p) => p.name).join('، ')}
          </span>
        )}
      </div>

      <div className="field-block">
        <label htmlFor="case-total">تعداد جلسات</label>
        <div className="field" style={{ maxWidth: 140 }}>
          <Input
            id="case-total"
            numeric
            className=""
            value={total}
            onChange={(e) => setTotal(e.target.value.replace(/\D/g, '').slice(0, 2))}
          />
        </div>
        <span className={totalValid ? 'field-hint' : 'field-err'}>
          {totalValid
            ? `${formatNumber(minTotal)} جلسه انجام شده. جلسه‌ای که نوبت دارد یا انجام شده حذف نمی‌شود.`
            : 'تعداد جلسات باید بین ۲ و ۶۰ باشد'}
        </span>
      </div>

      <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-start' }}>
        <button
          type="button"
          className="btn primary"
          onClick={() => save.mutate()}
          disabled={!valid || save.isPending}
        >
          {save.isPending ? 'در حال ذخیره…' : 'ذخیره'}
        </button>
        <button type="button" className="btn ghost" onClick={onClose}>انصراف</button>
      </div>
    </div>
  );
}
