import { useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useNavigate, useParams, Link } from 'react-router-dom';
import { ChevronRightIcon } from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import PersianDateInput from '../components/ui/PersianDateInput';
import PriceInput from '../components/ui/PriceInput';
import SearchableSelect from '../components/ui/SearchableSelect';
import { WalletChargeLink } from '../components/AppointmentActions';
import { formatRial, rialToToman, tomanToRial } from '../lib/utils';
import { DEFAULT_SERVICE_CATEGORY } from '../lib/insuranceShares';
import BackButton from '../components/ui/BackButton';
import { useAppointmentInsurance } from '../hooks/useAppointmentInsurance';

interface Option { uuid: string; name?: string; full_name?: string }

interface AppointmentDetail {
  uuid: string; slot_start: number; slot_end: number; status: string; version: number;
  note?: string | null;
  patient_mobile?: string | null;
  user?: { uuid: string; mobile: string } | null;
  deposit_required?: boolean; deposit_amount_rials?: number | null;
  service_section?: Option | null; service_item?: Option | null; staff?: Option | null;
  visit_price_rials?: number | null;
  service_items?: { uuid: string; price_rials?: number | null; service_category?: string | null; insurance_covered?: boolean }[] | null;
  insurance_service_category?: string | null;
  insurance_base_id?: number | null;
}

const isoDate = (ts: number) => {
  const d = new Date(ts * 1000);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
};
const isoTime = (ts: number) => {
  const d = new Date(ts * 1000);
  return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
};
const toEpoch = (date: string, time: string) => Math.floor(new Date(`${date}T${time || '00:00'}`).getTime() / 1000);

/** ویرایش نوبت (Figma edit.pdf) — full-page edit of service specs, timing, deposit, status and notes. */
export default function AppointmentEditPage() {
  const { uuid = '' } = useParams();
  const navigate = useNavigate();
  const qc = useQueryClient();

  const { data, isLoading } = useQuery<ApiResponse<{ data: AppointmentDetail }>>({
    queryKey: ['appointment-edit', uuid],
    queryFn: () => api.get(`/api/v1/appointment/${uuid}`),
    enabled: !!uuid,
  });
  const a = data?.data?.data;

  const [sectionUuid, setSectionUuid] = useState('');
  const [itemUuid, setItemUuid] = useState('');
  const [staffUuid, setStaffUuid] = useState('');
  const [date, setDate] = useState('');
  const [start, setStart] = useState('');
  const [end, setEnd] = useState('');
  const [depositRequired, setDepositRequired] = useState(false);
  const [depositToman, setDepositToman] = useState(0);
  const [status, setStatus] = useState('');
  const [note, setNote] = useState('');
  const [serviceCategory, setServiceCategory] = useState('');
  const [insuranceId, setInsuranceId] = useState('');

  // hydrate once the appointment arrives
  useEffect(() => {
    if (!a) return;
    setSectionUuid(a.service_section?.uuid ?? '');
    setItemUuid(a.service_item?.uuid ?? '');
    setStaffUuid(a.staff?.uuid ?? '');
    setDate(isoDate(a.slot_start));
    setStart(isoTime(a.slot_start));
    setEnd(isoTime(a.slot_end));
    setDepositRequired(!!a.deposit_required);
    setDepositToman(rialToToman(a.deposit_amount_rials ?? 0));
    setStatus(a.status);
    setNote(a.note ?? '');
    setServiceCategory(a.insurance_service_category ?? '');
    setInsuranceId(a.insurance_base_id ? String(a.insurance_base_id) : '');
  }, [a]);

  const insurance = useAppointmentInsurance(!!uuid);

  // نوع خدمتِ مؤثر: انتخاب نوبت، وگرنه تنها نوع فعالِ tenant (همان قاعدهٔ سرور).
  const effectiveCategory = serviceCategory || insurance.defaultCategory || DEFAULT_SERVICE_CATEGORY;

  const shares = insurance.breakdown([
    // نوبتِ بدون هزینهٔ ویزیت، «قیمت ویزیت آزاد» تنظیمات را می‌گیرد (مثل سرور).
    { total: insurance.visitPriceOf(a?.visit_price_rials), category: effectiveCategory, insured: true },
    ...(a?.service_items ?? []).map((s) => ({
      total: Number(s.price_rials ?? 0),
      category: s.service_category ?? DEFAULT_SERVICE_CATEGORY,
      insured: s.insurance_covered !== false,
    })),
  ], insuranceId);

  const sectionsQ = useQuery<ApiResponse<Option[]>>({ queryKey: ['service-sections'], queryFn: () => api.get('/api/v1/service-sections') });
  const itemsQ = useQuery<ApiResponse<Option[]>>({
    queryKey: ['service-items', sectionUuid],
    queryFn: () => api.get(`/api/v1/service-items/${sectionUuid}`),
    enabled: !!sectionUuid,
  });
  const staffQ = useQuery<ApiResponse<Option[]>>({ queryKey: ['staff-list'], queryFn: () => api.get('/api/v1/staff') });

  const save = useMutation({
    mutationFn: () => api.patch(`/api/v1/appointment/${uuid}`, {
      slot_start: toEpoch(date, start),
      slot_end: toEpoch(date, end),
      service_section_uuid: sectionUuid,
      service_item_uuid: itemUuid,
      staff_uuid: staffUuid,
      deposit_required: depositRequired,
      deposit_amount_rials: depositRequired ? tomanToRial(depositToman) : null,
      note,
      insurance_service_category: serviceCategory || null,
      insurance_base_id: insuranceId ? Number(insuranceId) : null,
      ...(status !== a?.status ? { status } : {}),
      version: a?.version,
    }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['appointments'] });
      toast.success('نوبت به‌روزرسانی شد');
      // به همان روزِ نوبت برگرد، نه امروز.
      navigate(`/admin/appointments?date=${date}`);
    },
    onError: (e: any) => toast.error(e.message || 'خطا در ذخیره اطلاعات'),
  });

  const label = { fontSize: 12.5, color: 'var(--text-3)' } as const;

  if (isLoading || !a) return <div style={{ padding: 24, color: 'var(--text-3)', fontSize: 13 }}>در حال بارگذاری...</div>;

  const statusOptions: [string, string][] = [
    ['pending', 'ثبت شده'], ['confirmed', 'قطعی شده'], ['following_up', 'در حال پیگیری'],
    ['salon', 'سالن'], ['completed', 'ویزیت شده'], ['cancelled_by_doctor', 'لغو شده'],
  ];

  return (
    <div className="fade-in" style={{ maxWidth: 860, margin: '0 auto' }}>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 14 }}>
        <BackButton fallback={`/admin/appointments?date=${date}`} />
      </div>

      <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 22 }}>
        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 12 }}>مشخصات سرویس:</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12, marginBottom: 18 }}>
          <div>
            <label style={label}>بخش</label>
            <div style={{ marginTop: 6 }}>
              <SearchableSelect
                options={(sectionsQ.data?.data ?? []).map(o => ({ value: o.uuid, label: o.name ?? '' }))}
                value={sectionUuid || null}
                onChange={v => { setSectionUuid(v ? String(v) : ''); setItemUuid(''); }}
                placeholder="انتخاب بخش"
                isLoading={sectionsQ.isLoading}
                isClearable
                height={38}
              />
            </div>
          </div>
          <div>
            <label style={label}>سرویس</label>
            <div style={{ marginTop: 6 }}>
              <SearchableSelect
                options={(itemsQ.data?.data ?? []).map(o => ({ value: o.uuid, label: o.name ?? '' }))}
                value={itemUuid || null}
                onChange={v => setItemUuid(v ? String(v) : '')}
                placeholder="انتخاب سرویس"
                isDisabled={!sectionUuid}
                isLoading={itemsQ.isLoading}
                isClearable
                height={38}
              />
            </div>
          </div>
          <div>
            <label style={label}>پرسنل</label>
            <div style={{ marginTop: 6 }}>
              <SearchableSelect
                options={(staffQ.data?.data ?? []).map(o => ({ value: o.uuid, label: o.full_name ?? '' }))}
                value={staffUuid || null}
                onChange={v => setStaffUuid(v ? String(v) : '')}
                placeholder="انتخاب پرسنل"
                isLoading={staffQ.isLoading}
                isClearable
                height={38}
              />
            </div>
          </div>
        </div>

        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 12 }}>بیمه:</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12, marginBottom: 18 }}>
          {/* نوع خدمت فقط وقتی چند نوع فعال است پرسیده می‌شود. */}
          {insurance.needsCategoryChoice && (
            <div>
              <label style={label}>نوع خدمت</label>
              <div style={{ marginTop: 6 }}>
                <SearchableSelect
                  options={insurance.categoryOptions}
                  value={serviceCategory || null}
                  onChange={v => setServiceCategory(v ? String(v) : '')}
                  placeholder="انتخاب نوع خدمت"
                  isClearable
                  height={38}
                />
              </div>
            </div>
          )}
          <div>
            <label style={label}>بیمه</label>
            <div style={{ marginTop: 6 }}>
              <SearchableSelect
                options={insurance.insuranceOptions}
                value={insuranceId || null}
                onChange={v => setInsuranceId(v ? String(v) : '')}
                placeholder="بدون بیمه"
                noOptionsMessage="قرارداد بیمهٔ فعالی ندارید"
                isClearable
                height={38}
              />
            </div>
          </div>
          {insuranceId !== '' && (
            <div>
              <label style={label}>سهم بیمه / سهم بیمار</label>
              <div style={{ marginTop: 6, display: 'flex', alignItems: 'center', gap: 8, minHeight: 38, fontSize: 13 }}>
                <span style={{ color: 'var(--success)', fontWeight: 700 }}>{formatRial(shares.insurance)}</span>
                <span style={{ color: 'var(--text-3)' }}>/</span>
                <span style={{ color: 'var(--primary)', fontWeight: 700 }}>{formatRial(shares.patient)}</span>
              </div>
            </div>
          )}
        </div>

        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 12 }}>زمان نوبت:</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 12, marginBottom: 18 }}>
          <div>
            <label style={label}>انتخاب تاریخ</label>
            <div style={{ marginTop: 6 }}><PersianDateInput value={date} onChange={setDate} /></div>
          </div>
          <div>
            <label style={label}>ساعت شروع</label>
            <div className="field" style={{ marginTop: 6 }}><input aria-label="ساعت شروع" type="time" value={start} onChange={e => setStart(e.target.value)} dir="ltr" /></div>
          </div>
          <div>
            <label style={label}>ساعت پایان</label>
            <div className="field" style={{ marginTop: 6 }}><input aria-label="ساعت پایان" type="time" value={end} onChange={e => setEnd(e.target.value)} dir="ltr" /></div>
          </div>
        </div>

        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 12 }}>بیعانه:</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', marginBottom: 18 }}>
          <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontSize: 13, cursor: 'pointer' }}>
            <input type="checkbox" checked={depositRequired} onChange={e => setDepositRequired(e.target.checked)} />
            بیعانه مورد نیاز است.
          </label>
          {depositRequired && (
            <>
              <div style={{ minWidth: 220 }}>
                <label style={label}>مبلغ بیعانه (تومان)</label>
                <div style={{ marginTop: 6 }}><PriceInput value={depositToman} onChange={setDepositToman} /></div>
              </div>
              <WalletChargeLink mobile={a.patient_mobile || a.user?.mobile || ''} />
            </>
          )}
        </div>

        <div style={{ maxWidth: 320, marginBottom: 18 }}>
          <label style={label}>انتخاب وضعیت</label>
          <div style={{ marginTop: 6 }}>
            <SearchableSelect
              options={statusOptions.map(([v, l]) => ({ value: v, label: l }))}
              value={status || null}
              onChange={v => setStatus(v ? String(v) : '')}
              placeholder="انتخاب وضعیت"
              height={38}
            />
          </div>
        </div>

        <label style={label}>توضیحات</label>
        <div className="field" style={{ height: 'auto', margin: '6px 0 18px' }}>
          <textarea value={note} onChange={e => setNote(e.target.value)} rows={4} placeholder="توضیحات"
            style={{ width: '100%', border: 'none', background: 'transparent', fontFamily: 'inherit', resize: 'vertical' }} />
        </div>

        <button className="btn primary" disabled={!date || !start || !end || save.isPending} onClick={() => save.mutate()}>
          ثبت اطلاعات
        </button>
      </div>
    </div>
  );
}
