import { useEffect, useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { PlusIcon, TrashIcon } from '@heroicons/react/24/outline';
import Switch from './ui/Switch';
import SearchableSelect from './ui/SearchableSelect';
import { api, ApiError, type ApiResponse } from '../lib/api';

interface ProtocolStep {
  step_number: number;
  offset_days: number;
}

interface ProtocolStaff {
  uuid: string;
  name: string;
}

interface TreatmentProtocol {
  uuid: string;
  /** آیا هیچ منبعی این سرویس را ارائه می‌دهد؛ نبودش رزرو را قفل نمی‌کند ولی باید دیده شود. */
  service_has_resources?: boolean;
  active: boolean;
  total_sessions: number;
  supervisor: { uuid: string; name: string } | null;
  steps: ProtocolStep[];
  staff: ProtocolStaff[];
}

interface StaffRow {
  uuid: string;
  full_name: string;
  active?: boolean;
}

interface DoctorRow {
  uuid: string;
  name: string;
}

/** پیش‌فرضِ روشن‌کردن سوییچ: کوتاه‌ترین دوره‌ای که معنی دارد. */
const DEFAULT_STEPS: ProtocolStep[] = [
  { step_number: 1, offset_days: 0 },
  { step_number: 2, offset_days: 30 },
];

/**
 * «طول درمان» یک سرویس.
 *
 * وجودِ پروتکل خودش سوییچ است — سرویس بدون پروتکل تک‌جلسه‌ای است — پس روشن‌کردن یعنی
 * ساختن و خاموش‌کردن یعنی حذف. فاصلهٔ هر گام از **جلسهٔ قبل** است، نه از شروع دوره،
 * چون فاصلهٔ درمان به آخرین جلسه گره خورده نه به روز باز شدن پرونده.
 */
export default function TreatmentProtocolTab({ serviceUuid, canEdit }: {
  serviceUuid: string;
  canEdit: boolean;
}) {
  const qc = useQueryClient();

  const { data, isLoading } = useQuery({
    queryKey: ['treatment-protocol', serviceUuid],
    queryFn: () => api.get<ApiResponse<TreatmentProtocol | null>>(
      `/api/v1/service-item/${serviceUuid}/treatment-protocol`,
    ),
  });

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

  const { data: doctorData } = useQuery({
    queryKey: ['my-clinic-doctors'],
    queryFn: () => api.get<ApiResponse<{ data: DoctorRow[] }>>('/api/v1/my/clinic-doctors'),
    staleTime: 60_000,
  });

  const protocol = data?.data ?? null;

  const [enabled, setEnabled]       = useState(false);
  const [steps, setSteps]           = useState<ProtocolStep[]>(DEFAULT_STEPS);
  const [staffUuids, setStaffUuids] = useState<string[]>([]);
  const [supervisor, setSupervisor] = useState<string | null>(null);

  useEffect(() => {
    setEnabled(protocol !== null);
    setSteps(protocol?.steps?.length ? protocol.steps : DEFAULT_STEPS);
    setStaffUuids(protocol?.staff?.map((s) => s.uuid) ?? []);
    setSupervisor(protocol?.supervisor?.uuid ?? null);
  }, [protocol]);

  const staffOptions = (staffData?.data ?? [])
    .filter((s) => s.active !== false)
    .map((s) => ({ value: s.uuid, label: s.full_name }));

  const doctorOptions = (doctorData?.data?.data ?? []).map((d) => ({ value: d.uuid, label: d.name }));

  const save = useMutation({
    mutationFn: () => api.put<ApiResponse<TreatmentProtocol>>(
      `/api/v1/service-item/${serviceUuid}/treatment-protocol`,
      {
        steps: steps.map((s, i) => ({ step_number: i + 1, offset_days: s.offset_days })),
        staff_uuids: staffUuids,
        supervisor_doctor_uuid: supervisor,
      },
    ),
    onSuccess: () => {
      toast.success('طول درمان ذخیره شد');
      qc.invalidateQueries({ queryKey: ['treatment-protocol', serviceUuid] });
    },
    onError: (e) => toast.error(e instanceof ApiError ? e.message : 'ذخیرهٔ طول درمان ناموفق بود'),
  });

  const remove = useMutation({
    mutationFn: () => api.delete<ApiResponse<null>>(`/api/v1/service-item/${serviceUuid}/treatment-protocol`),
    onSuccess: () => {
      toast.success('طول درمان خاموش شد');
      qc.invalidateQueries({ queryKey: ['treatment-protocol', serviceUuid] });
    },
    onError: (e) => toast.error(e instanceof ApiError ? e.message : 'خاموش‌کردن ناموفق بود'),
  });

  const toggle = (on: boolean) => {
    setEnabled(on);
    if (!on && protocol !== null) remove.mutate();
  };

  const setOffset = (index: number, value: number) => {
    setSteps((prev) => prev.map((s, i) => (i === index ? { ...s, offset_days: value } : s)));
  };

  const addStep = () => {
    setSteps((prev) => [
      ...prev,
      { step_number: prev.length + 1, offset_days: prev[prev.length - 1]?.offset_days || 30 },
    ]);
  };

  const removeStep = (index: number) => {
    setSteps((prev) => (prev.length <= 2 ? prev : prev.filter((_, i) => i !== index)));
  };

  const addStaff = (uuid: string | number | null) => {
    const id = uuid === null ? '' : String(uuid);
    if (id && !staffUuids.includes(id)) setStaffUuids((prev) => [...prev, id]);
  };

  if (isLoading) {
    return <div className="card card-pad" style={{ fontSize: 13, color: 'var(--text-3)' }}>در حال بارگذاری...</div>;
  }

  return (
    <div className="card card-pad" style={{ display: 'grid', gap: 16 }}>
      <Switch
        checked={enabled}
        onChange={toggle}
        disabled={!canEdit}
        label="طول درمان"
        hint="سرویس‌هایی که در چند جلسه انجام می‌شوند — لیزر، بوتاکس، مزوتراپی. خاموش یعنی تک‌جلسه‌ای."
      />

      {enabled && protocol !== null && protocol.service_has_resources === false && (
        <div
          className="card card-pad"
          style={{ background: 'var(--warning-bg)', display: 'grid', gap: 4 }}
        >
          <strong style={{ fontSize: 13 }}>هیچ دستگاهی به این سرویس وصل نیست</strong>
          <span style={{ fontSize: 12.5, color: 'var(--text-2)', lineHeight: 1.9 }}>
            رزرو قفل نمی‌شود، ولی منشی می‌تواند این سرویس را روی هر منبعی ثبت کند و اپراتور فرم
            دستگاه درست را نمی‌بیند. در «منابع» مشخص کنید کدام دستگاه‌ها این سرویس را می‌دهند.
          </span>
        </div>
      )}

      {enabled && (
        <>
          <section style={{ display: 'grid', gap: 10 }}>
            <h3 style={{ margin: 0, fontSize: 13.5 }}>
              جلسات دوره <span style={{ color: 'var(--text-3)', fontWeight: 400 }}>({steps.length} جلسه)</span>
            </h3>
            <p style={{ margin: 0, fontSize: 12.5, color: 'var(--text-3)', lineHeight: 1.9 }}>
              فاصلهٔ هر جلسه از <b>جلسهٔ قبل</b> حساب می‌شود، نه از شروع دوره. اگر بیمار دیر بیاید،
              بقیهٔ دوره هم جابه‌جا می‌شود.
            </p>

            {steps.map((step, index) => (
              <div key={index} className="field" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <span style={{ minWidth: 62, fontSize: 13 }}>جلسهٔ {index + 1}</span>

                {index === 0 ? (
                  <span style={{ fontSize: 12.5, color: 'var(--text-3)', flex: 1 }}>
                    شروع دوره — همان روز اولین نوبت
                  </span>
                ) : (
                  <>
                    <input
                      type="number"
                      min={1}
                      value={step.offset_days}
                      disabled={!canEdit}
                      onChange={(e) => setOffset(index, Number(e.target.value))}
                      aria-label={`فاصلهٔ جلسهٔ ${index + 1} از جلسهٔ قبل به روز`}
                      style={{ width: 96 }}
                    />
                    <span style={{ fontSize: 12.5, color: 'var(--text-3)', flex: 1 }}>روز بعد از جلسهٔ قبل</span>
                  </>
                )}

                {canEdit && steps.length > 2 && (
                  <button
                    type="button"
                    className="btn ghost sm"
                    onClick={() => removeStep(index)}
                    aria-label={`حذف جلسهٔ ${index + 1}`}
                  >
                    <TrashIcon style={{ width: 16, height: 16 }} />
                  </button>
                )}
              </div>
            ))}

            {canEdit && (
              <button type="button" className="btn secondary sm" onClick={addStep} style={{ justifySelf: 'start' }}>
                <PlusIcon style={{ width: 16, height: 16 }} /> افزودن جلسه
              </button>
            )}
          </section>

          <section style={{ display: 'grid', gap: 8 }}>
            <h3 style={{ margin: 0, fontSize: 13.5 }}>پرسنل مجاز</h3>
            <p style={{ margin: 0, fontSize: 12.5, color: 'var(--text-3)' }}>
              منشی هنگام رزرو فقط از میان همین‌ها انتخاب می‌کند.
            </p>

            {canEdit && (
              <SearchableSelect
                options={staffOptions.filter((o) => !staffUuids.includes(String(o.value)))}
                value={null}
                onChange={addStaff}
                placeholder="افزودن پرسنل..."
                ariaLabel="افزودن پرسنل مجاز"
              />
            )}

            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
              {staffUuids.length === 0 && (
                <span style={{ fontSize: 12.5, color: 'var(--danger)' }}>حداقل یک پرسنل الزامی است</span>
              )}
              {staffUuids.map((uuid) => (
                <span key={uuid} className="badge" style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                  {staffOptions.find((o) => String(o.value) === uuid)?.label ?? uuid}
                  {canEdit && (
                    <button
                      type="button"
                      className="btn ghost sm"
                      onClick={() => setStaffUuids((prev) => prev.filter((u) => u !== uuid))}
                      aria-label="حذف این پرسنل"
                      style={{ padding: 0, minWidth: 18, height: 18 }}
                    >
                      ×
                    </button>
                  )}
                </span>
              ))}
            </div>
          </section>

          <section style={{ display: 'grid', gap: 8 }}>
            <h3 style={{ margin: 0, fontSize: 13.5 }}>پزشک ناظر</h3>
            <p style={{ margin: 0, fontSize: 12.5, color: 'var(--text-3)' }}>
              پاسخگوی بالینی دوره. لازم نیست خودش درمان را انجام دهد.
            </p>
            <SearchableSelect
              options={doctorOptions}
              value={supervisor}
              onChange={(v) => setSupervisor(v === null ? null : String(v))}
              placeholder="بدون پزشک ناظر"
              isClearable
              isDisabled={!canEdit}
              ariaLabel="پزشک ناظر دوره"
            />
          </section>

          {canEdit && (
            <button
              type="button"
              className="btn primary"
              onClick={() => save.mutate()}
              disabled={save.isPending || staffUuids.length === 0}
              style={{ justifySelf: 'start' }}
            >
              {save.isPending ? 'در حال ذخیره...' : 'ذخیرهٔ طول درمان'}
            </button>
          )}
        </>
      )}
    </div>
  );
}
