import React, { useEffect, useState } from 'react';
import Modal from '../ui/Modal';
import { useQuery } from '@tanstack/react-query';
import SearchableSelect from '../ui/SearchableSelect';
import { api, type ApiResponse } from '../../lib/api';
import type { ClinicResource, ResourcePayload, ResourceType } from '../../types';
import { useResourceDetail } from '../../hooks/useResources';
import { formatNumber } from '../../lib/utils';

/** کلیدهای شناخته‌شدهٔ ویژگی — قرارداد است نه اجبار؛ سرور هر کلید snake_case را می‌پذیرد. */
const KNOWN_ATTRIBUTES = ['gender', 'device_model', 'floor', 'brand'];

type AttributeRow = { key: string; value: string };

interface Props {
  open: boolean;
  resource: ClinicResource | null;
  types: ResourceType[];
  saving: boolean;
  onClose: () => void;
  onSave: (payload: ResourcePayload) => void;
}

export default function ResourceFormModal({
  open, resource, types, saving, onClose, onSave,
}: Props) {
  // شمار نوبت‌های آینده فقط برای منبعِ موجود معنا دارد و فقط وقتی مودال باز است.
  const { upcomingAppointments: upcoming } = useResourceDetail(open ? resource?.uuid : undefined);
  // پزشکان محیط جاری برای انتخاب ناظر — همان اندپوینت احرازشده‌ای که صفحهٔ نوبت‌ها
  // استفاده می‌کند، تا منشی فقط پزشکان مجازش را ببیند.
  const doctorsQuery = useQuery<ApiResponse<{ data: { uuid: string; name: string }[] }>>({
    queryKey: ['booking-doctors'],
    queryFn: () => api.get('/api/v1/my/clinic-doctors'),
    enabled: open,
    staleTime: 60_000,
  });
  const doctors = doctorsQuery.data?.data?.data ?? [];
  const doctorsLoading = doctorsQuery.isLoading;

  const [name, setName] = useState('');
  const [typeUuid, setTypeUuid] = useState<string | null>(null);
  const [supervisorUuid, setSupervisorUuid] = useState<string | null>(null);
  const [capacity, setCapacity] = useState('1');
  const [setupMinutes, setSetupMinutes] = useState('0');
  const [cleanupMinutes, setCleanupMinutes] = useState('0');
  const [active, setActive] = useState(true);
  const [attributes, setAttributes] = useState<AttributeRow[]>([]);

  useEffect(() => {
    if (!open) return;
    setName(resource?.name ?? '');
    setTypeUuid(resource?.type_uuid ?? null);
    setSupervisorUuid(resource?.supervisor?.uuid ?? null);
    setCapacity(String(resource?.capacity ?? 1));
    setSetupMinutes(String(resource?.setup_minutes ?? 0));
    setCleanupMinutes(String(resource?.cleanup_minutes ?? 0));
    setActive(resource?.active ?? true);
    setAttributes(
      Object.entries(resource?.attributes ?? {}).map(([key, value]) => ({ key, value: String(value) })),
    );
  }, [open, resource]);

  const isEdit = resource !== null;
  const parsedCapacity = Number(capacity);
  const invalid =
    name.trim() === '' ||
    !supervisorUuid ||
    (!isEdit && !typeUuid) ||
    !Number.isFinite(parsedCapacity) ||
    parsedCapacity < 1;

  const submit = () => {
    const attrs: Record<string, string> = {};
    attributes.forEach(({ key, value }) => {
      if (key.trim() !== '') attrs[key.trim()] = value;
    });

    const payload: ResourcePayload = {
      name: name.trim(),
      capacity: parsedCapacity,
      setup_minutes: Number(setupMinutes) || 0,
      cleanup_minutes: Number(cleanupMinutes) || 0,
      attributes: attrs,
      active,
      supervisor_doctor_uuid: supervisorUuid!,
    };

    // نوع فقط هنگام ساخت فرستاده می‌شود؛ جفت محیطِ منبع از آدرسِ محیط مشتق می‌شود و
    // جابه‌جا کردنش یعنی همان منبع در محیط دیگری ظاهر شود. آدرس پرسیده نمی‌شود:
    // منابع دامنهٔ شعبه ندارند و سرور آدرسِ خودِ کلینیک را برمی‌دارد.
    if (!isEdit) {
      payload.type_uuid = typeUuid!;
    }

    onSave(payload);
  };

  return (
    <Modal open={open} onClose={onClose} title={isEdit ? 'ویرایش منبع' : 'افزودن منبع'} size="lg">
      <div style={{ display: 'grid', gap: 14 }}>
        <Field label="نام منبع">
          <input className="field" value={name} onChange={(e) => setName(e.target.value)} placeholder="لیزر آلکساندرایت ۱" />
        </Field>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12 }}>
          <Field label="نوع منبع">
            <SearchableSelect
              options={types.map((t) => ({ value: t.uuid, label: t.name }))}
              value={typeUuid}
              onChange={(v) => setTypeUuid(v ? String(v) : null)}
              placeholder="نوع را انتخاب کنید"
              isDisabled={isEdit}
              height={38}
            />
          </Field>
          {/* ناظر برخلاف نوع در ویرایش هم قابل تغییر است: پزشکِ مسئولِ یک دستگاه
              عوض می‌شود، ولی محیطِ منبع نه. */}
          <Field label="پزشک ناظر">
            <SearchableSelect
              options={doctors.map((d) => ({ value: d.uuid, label: d.name }))}
              value={supervisorUuid}
              onChange={(v) => setSupervisorUuid(v ? String(v) : null)}
              placeholder="پزشک ناظر را انتخاب کنید"
              isLoading={doctorsLoading}
              height={38}
            />
          </Field>
        </div>

        {isEdit && (
          <p style={{ fontSize: 12, color: 'var(--text-3)', margin: 0 }}>
            نوع منبع پس از ساخت تغییر نمی‌کند؛ برای تغییرش، منبع تازه بسازید.
          </p>
        )}

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 12 }}>
          <Field label="ظرفیت هم‌زمان">
            <input className="field" type="number" min={1} value={capacity} onChange={(e) => setCapacity(e.target.value)} />
          </Field>
          <Field label="آماده‌سازی (دقیقه)">
            <input className="field" type="number" min={0} value={setupMinutes} onChange={(e) => setSetupMinutes(e.target.value)} />
          </Field>
          <Field label="تمیزکاری (دقیقه)">
            <input className="field" type="number" min={0} value={cleanupMinutes} onChange={(e) => setCleanupMinutes(e.target.value)} />
          </Field>
        </div>

        <p style={{ fontSize: 12, color: 'var(--text-3)', margin: 0 }}>
          ظرفیت یعنی چند بیمار هم‌زمان — اتاق تزریق سه‌تخته یک منبع با ظرفیت ۳ است، نه سه منبع.
          آماده‌سازی و تمیزکاری جزو نوبت بیمار نیستند ولی منبع را اشغال می‌کنند.
        </p>

        <div style={{ display: 'grid', gap: 8 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>ویژگی‌ها (اختیاری)</label>
            <button
              type="button"
              className="btn secondary sm"
              onClick={() => setAttributes((a) => [...a, { key: '', value: '' }])}
            >
              افزودن ویژگی
            </button>
          </div>

          {attributes.map((row, index) => (
            <div key={index} style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <input
                className="field"
                list="resource-attribute-keys"
                value={row.key}
                placeholder="gender"
                onChange={(e) =>
                  setAttributes((a) => a.map((r, i) => (i === index ? { ...r, key: e.target.value } : r)))
                }
                style={{ flex: 1 }}
              />
              <input
                className="field"
                value={row.value}
                placeholder="female"
                onChange={(e) =>
                  setAttributes((a) => a.map((r, i) => (i === index ? { ...r, value: e.target.value } : r)))
                }
                style={{ flex: 1 }}
              />
              <button
                type="button"
                className="btn secondary sm"
                onClick={() => setAttributes((a) => a.filter((_, i) => i !== index))}
                aria-label="حذف ویژگی"
              >
                ✕
              </button>
            </div>
          ))}

          <datalist id="resource-attribute-keys">
            {KNOWN_ATTRIBUTES.map((k) => <option key={k} value={k} />)}
          </datalist>
        </div>

        <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
          <input type="checkbox" checked={active} onChange={(e) => setActive(e.target.checked)} />
          منبع فعال است
        </label>

        {/* غیرفعال‌کردن نوبت‌های ثبت‌شده را لغو نمی‌کند؛ فقط از جستجوی وقتِ بعدی حذف
            می‌شود. پس این هشدار است نه مانع — ولی اپراتور باید بداند چند بیمار روی
            منبعی نوبت دارند که دارد خاموش می‌شود. */}
        {!active && upcoming > 0 && (
          <span
            style={{
              fontSize: 12,
              lineHeight: 1.8,
              color: 'var(--warning)',
              background: 'var(--warning-bg)',
              borderRadius: 'var(--r-sm)',
              padding: '8px 10px',
            }}
          >
            این منبع {formatNumber(upcoming)} نوبت آیندهٔ فعال دارد. غیرفعال‌کردن آن‌ها را
            لغو نمی‌کند؛ فقط این منبع دیگر در جستجوی وقت نمی‌آید.
          </span>
        )}

        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 4 }}>
          <button type="button" className="btn secondary" onClick={onClose}>انصراف</button>
          <button type="button" className="btn primary" disabled={saving || invalid} onClick={submit}>
            {saving ? 'در حال ذخیره...' : 'ذخیره'}
          </button>
        </div>
      </div>
    </Modal>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div style={{ display: 'grid', gap: 6 }}>
      <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{label}</label>
      {children}
    </div>
  );
}
