import React, { useState, useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  MagnifyingGlassIcon, PlusIcon, ChevronRightIcon, PencilIcon, PhoneIcon,
  FolderOpenIcon, UsersIcon,
} from '@heroicons/react/24/outline';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import type { PatientRecord, PatientSession, ServiceSection, ServiceItem } from '../types';
import { formatDate, formatDateTime, formatRial, formatNumber } from '../lib/utils';
import DataTable, { type Column } from '../components/ui/DataTable';
import Pagination from '../components/ui/Pagination';
import Modal from '../components/ui/Modal';
import PageHeader from '../components/ui/PageHeader';
import SearchableSelect from '../components/ui/SearchableSelect';

const sessionSchema = z.object({
  visit_price_rials: z.coerce.number().min(0),
  base_insurance_discount_percent: z.coerce.number().min(0).max(100),
  supplementary_discount_percent: z.coerce.number().min(0).max(100),
  payment_method: z.enum(['cash', 'card', 'insurance', 'online', 'pending']),
  notes: z.string().optional(),
});
type SessionFormData = z.infer<typeof sessionSchema>;

const PAYMENT_LABELS: Record<string, string> = {
  cash: 'نقدی', card: 'کارت', insurance: 'بیمه', online: 'آنلاین', pending: 'در انتظار',
};

const PAYMENT_BADGE: Record<string, string> = {
  cash: 'green', card: 'blue', insurance: 'purple', online: 'blue', pending: 'amber',
};

const EMPTY_RECORDS: PatientRecord[] = [];
const EMPTY_SESSIONS: PatientSession[] = [];

function calcFinalPrice(visitPrice: number, baseDiscount: number, suppDiscount: number, servicesTotal: number) {
  const afterBase = visitPrice * (1 - baseDiscount / 100);
  const afterSupp = afterBase * (1 - suppDiscount / 100);
  return Math.round(afterSupp) + servicesTotal;
}

export default function MyPatientsPage() {
  const qc = useQueryClient();
  const [selectedRecord, setSelectedRecord] = useState<PatientRecord | null>(null);
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const [sessionPage, setSessionPage] = useState(1);
  const [sessionModal, setSessionModal] = useState(false);
  const [editSession, setEditSession] = useState<PatientSession | null>(null);

  const form = useForm<SessionFormData>({
    resolver: zodResolver(sessionSchema),
    defaultValues: { visit_price_rials: 0, base_insurance_discount_percent: 0, supplementary_discount_percent: 0, payment_method: 'cash' },
  });
  const watchVisit = form.watch('visit_price_rials') ?? 0;
  const watchBase  = form.watch('base_insurance_discount_percent') ?? 0;
  const watchSupp  = form.watch('supplementary_discount_percent') ?? 0;

  const [selectedServices, setSelectedServices] = useState<{ service_item_uuid: string; name: string; price_rials: number }[]>([]);
  const [sectionUuid, setSectionUuid] = useState('');
  const [itemUuid, setItemUuid] = useState('');

  const servicesTotal = selectedServices.reduce((sum, s) => sum + s.price_rials, 0);
  const finalPrice    = calcFinalPrice(Number(watchVisit), Number(watchBase), Number(watchSupp), servicesTotal);

  const limit = 20;

  const { data: recordsData, isLoading } = useQuery<PaginatedResponse<PatientRecord>>({
    queryKey: ['patients', page, search],
    queryFn: () => api.get(`/api/v1/patients?page=${page}&limit=${limit}&search=${encodeURIComponent(search)}`),
  });

  const { data: sessionsData, isLoading: sessionsLoading } = useQuery<PaginatedResponse<PatientSession>>({
    queryKey: ['patient-sessions', selectedRecord?.uuid, sessionPage],
    queryFn: () => api.get(`/api/v1/patient/${selectedRecord!.uuid}/sessions?page=${sessionPage}&limit=20`),
    enabled: !!selectedRecord,
  });

  const { data: sectionsData } = useQuery<ApiResponse<ServiceSection[]>>({
    queryKey: ['service-sections'],
    queryFn: () => api.get('/api/v1/service-sections'),
  });

  const { data: itemsData } = useQuery<ApiResponse<ServiceItem[]>>({
    queryKey: ['service-items-for-session', sectionUuid],
    queryFn: () => api.get(`/api/v1/service-items/${sectionUuid}`),
    enabled: !!sectionUuid,
  });

  const records  = recordsData?.data ?? EMPTY_RECORDS;
  const sessions = sessionsData?.data ?? EMPTY_SESSIONS;
  const totalRec = recordsData?.meta?.totalRecords ?? 0;
  const totalSes = sessionsData?.meta?.totalRecords ?? 0;

  const sectionOptions = (sectionsData?.data ?? []).map((s) => ({ value: s.uuid, label: s.name }));
  const itemOptions    = (itemsData?.data ?? []).filter((i) => i.active).map((i) => ({
    value: i.uuid,
    label: `${i.name} — ${formatRial(i.price_rials)}`,
  }));

  const createSessionMut = useMutation({
    mutationFn: (body: object) => api.post(`/api/v1/patient/${selectedRecord!.uuid}/session`, body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['patient-sessions', selectedRecord?.uuid] });
      setSessionModal(false);
      form.reset();
      setSelectedServices([]);
      toast.success('مراجعه ثبت شد');
    },
    onError: (e: any) => toast.error(e.message),
  });

  const updateSessionMut = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: object }) => api.patch(`/api/v1/session/${uuid}`, body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['patient-sessions', selectedRecord?.uuid] });
      setEditSession(null);
      toast.success('مراجعه ویرایش شد');
    },
    onError: (e: any) => toast.error(e.message),
  });

  const handleAddService = () => {
    if (!itemUuid) return;
    const found = itemsData?.data?.find((i) => i.uuid === itemUuid);
    if (!found || selectedServices.some((s) => s.service_item_uuid === found.uuid)) return;
    setSelectedServices((p) => [...p, { service_item_uuid: found.uuid, name: found.name, price_rials: found.price_rials }]);
    setItemUuid('');
  };

  const handleSubmitSession = form.handleSubmit((d) => {
    createSessionMut.mutate({ ...d, services: selectedServices.map((s) => ({ service_item_uuid: s.service_item_uuid })) });
  });

  const handleSearch = useCallback((v: string) => { setSearch(v); setPage(1); }, []);

  const recordColumns: Column<PatientRecord>[] = [
    {
      key: 'user',
      header: 'بیمار',
      render: (r) => (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div
            className="avatar sm"
            style={{
              background: 'linear-gradient(145deg, oklch(0.62 0.15 256), oklch(0.48 0.16 256))',
              flexShrink: 0,
              fontWeight: 700,
            }}
          >
            {(r.user.fullName ?? '?').charAt(0)}
          </div>
          <div>
            <div style={{ fontWeight: 600, fontSize: 14 }}>{r.user.fullName ?? '—'}</div>
            <div style={{ fontSize: 12, color: 'var(--text-3)', display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }}>
              <PhoneIcon style={{ width: 11 }} />
              <span dir="ltr">{r.user.phone ?? '—'}</span>
            </div>
          </div>
        </div>
      ),
    },
    {
      key: 'created_at',
      header: 'تاریخ ثبت',
      render: (r) => (
        <span style={{ fontSize: 13, color: 'var(--text-3)' }}>{formatDate(r.created_at)}</span>
      ),
    },
    {
      key: 'uuid',
      header: '',
      render: (r) => (
        <button
          className="btn primary sm"
          style={{ display: 'flex', alignItems: 'center', gap: 5 }}
          onClick={() => { setSelectedRecord(r); setSessionPage(1); }}
        >
          <FolderOpenIcon style={{ width: 14 }} />
          مشاهده پرونده
        </button>
      ),
    },
  ];

  if (!selectedRecord) {
    return (
      <>
        <PageHeader title="پرونده بیماران" description="مراجعه‌کنندگان ثبت‌شده شما" />

        <div style={{ marginBottom: 16 }}>
          <div style={{
            background: 'var(--surface)',
            border: '1px solid var(--border)',
            borderRadius: 'var(--r)',
            padding: '10px 14px',
            display: 'flex',
            alignItems: 'center',
            gap: 10,
          }}>
            <MagnifyingGlassIcon style={{ width: 18, color: 'var(--text-3)', flexShrink: 0 }} />
            <input
              style={{ border: 'none', outline: 'none', background: 'transparent', flex: 1, fontSize: 14 }}
              value={search}
              onChange={(e) => handleSearch(e.target.value)}
              placeholder="جستجو بر اساس نام یا تلفن..."
            />
          </div>
        </div>

        <div className="card">
          {records.length === 0 && !isLoading ? (
            <div style={{ textAlign: 'center', padding: '60px 24px', color: 'var(--text-3)' }}>
              <UsersIcon style={{ width: 48, margin: '0 auto 16px', display: 'block', opacity: 0.4 }} />
              <div style={{ fontWeight: 600, fontSize: 15, marginBottom: 8, color: 'var(--text-2)' }}>
                {search ? 'بیماری یافت نشد' : 'هنوز بیماری ثبت نشده است'}
              </div>
              <div style={{ fontSize: 13 }}>
                {search ? 'عبارت جستجو را تغییر دهید' : 'پس از ثبت نوبت، پرونده بیمار به طور خودکار ایجاد می‌شود'}
              </div>
            </div>
          ) : (
            <>
              <DataTable columns={recordColumns} data={records} loading={isLoading} emptyMessage="بیماری ثبت نشده است" />
              <div style={{ padding: '0 16px 12px' }}>
                <Pagination page={page} total={totalRec} limit={limit} onPageChange={setPage} />
              </div>
            </>
          )}
        </div>
      </>
    );
  }

  return (
    <>
      <PageHeader
        title={selectedRecord.user.fullName ?? 'بیمار'}
        description={`تلفن: ${selectedRecord.user.phone ?? '—'} — پرونده از ${formatDate(selectedRecord.created_at)}`}
        action={
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="btn sm" onClick={() => setSelectedRecord(null)}>
              <ChevronRightIcon style={{ width: 15 }} /> بازگشت
            </button>
            <button
              className="btn primary sm"
              onClick={() => { form.reset(); setSelectedServices([]); setSessionModal(true); }}
            >
              <PlusIcon style={{ width: 15 }} /> مراجعه جدید
            </button>
          </div>
        }
      />

      {/* بنر اطلاعات بیمار */}
      <div style={{
        background: 'linear-gradient(135deg, oklch(0.52 0.22 256), oklch(0.40 0.18 256))',
        borderRadius: 'var(--r)',
        padding: '16px 20px',
        marginBottom: 16,
        display: 'flex',
        alignItems: 'center',
        gap: 16,
        color: '#fff',
      }}>
        <div style={{
          width: 48, height: 48, borderRadius: '50%',
          background: 'rgba(255,255,255,0.2)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 20, fontWeight: 700, flexShrink: 0,
        }}>
          {(selectedRecord.user.fullName ?? '?').charAt(0)}
        </div>
        <div style={{ flex: 1 }}>
          <div style={{ fontWeight: 700, fontSize: 17 }}>{selectedRecord.user.fullName ?? '—'}</div>
          <div style={{ fontSize: 13, opacity: 0.85, marginTop: 2, display: 'flex', alignItems: 'center', gap: 6 }}>
            <PhoneIcon style={{ width: 13 }} />
            <span dir="ltr">{selectedRecord.user.phone ?? '—'}</span>
          </div>
        </div>
        <div style={{ textAlign: 'center', background: 'rgba(255,255,255,0.15)', borderRadius: 10, padding: '8px 16px' }}>
          <div style={{ fontSize: 22, fontWeight: 800 }}>{totalSes}</div>
          <div style={{ fontSize: 12, opacity: 0.85 }}>مراجعه</div>
        </div>
      </div>

      <div className="card">
        <div style={{ fontWeight: 600, padding: '14px 16px 10px', borderBottom: '1px solid var(--border)', fontSize: 14 }}>
          تاریخچه مراجعات
        </div>
        {sessionsLoading ? (
          <div style={{ padding: 32, textAlign: 'center', color: 'var(--text-3)' }}>در حال بارگذاری...</div>
        ) : sessions.length === 0 ? (
          <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-3)' }}>
            <FolderOpenIcon style={{ width: 40, margin: '0 auto 12px', display: 'block', opacity: 0.4 }} />
            <div style={{ fontWeight: 600, marginBottom: 6, color: 'var(--text-2)' }}>مراجعه‌ای ثبت نشده است</div>
            <button
              className="btn primary sm"
              style={{ marginTop: 12 }}
              onClick={() => { form.reset(); setSelectedServices([]); setSessionModal(true); }}
            >
              <PlusIcon style={{ width: 14 }} /> ثبت اولین مراجعه
            </button>
          </div>
        ) : (
          sessions.map((s) => <SessionRow key={s.uuid} session={s} onEdit={setEditSession} />)
        )}
        {totalSes > 20 && (
          <div style={{ padding: '0 16px 12px' }}>
            <Pagination page={sessionPage} total={totalSes} limit={20} onPageChange={setSessionPage} />
          </div>
        )}
      </div>

      {/* Modal مراجعه جدید */}
      <Modal open={sessionModal} onClose={() => setSessionModal(false)} title="ثبت مراجعه جدید">
        <form onSubmit={handleSubmitSession}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
              <div className="field">
                <label>قیمت ویزیت (ریال)</label>
                <input {...form.register('visit_price_rials')} type="number" min={0} dir="ltr" />
              </div>
              <div className="field">
                <label>تخفیف بیمه پایه (%)</label>
                <input {...form.register('base_insurance_discount_percent')} type="number" min={0} max={100} dir="ltr" />
              </div>
              <div className="field">
                <label>تخفیف تکمیلی (%)</label>
                <input {...form.register('supplementary_discount_percent')} type="number" min={0} max={100} dir="ltr" />
              </div>
            </div>
            <div className="field">
              <label>روش پرداخت</label>
              <select {...form.register('payment_method')}>
                {Object.entries(PAYMENT_LABELS).map(([v, l]) => (
                  <option key={v} value={v}>{l}</option>
                ))}
              </select>
            </div>
            <div className="field">
              <label>یادداشت</label>
              <textarea {...form.register('notes')} rows={2} placeholder="یادداشت پزشک..." />
            </div>

            <div style={{ borderTop: '1px solid var(--border)', paddingTop: 12 }}>
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 10 }}>افزودن خدمات</div>
              <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
                <div style={{ flex: 1 }}>
                  <SearchableSelect
                    options={sectionOptions}
                    value={sectionUuid}
                    onChange={(v) => { setSectionUuid(v ? String(v) : ''); setItemUuid(''); }}
                    placeholder="انتخاب بخش..."
                  />
                </div>
                <div style={{ flex: 1 }}>
                  <SearchableSelect
                    options={itemOptions}
                    value={itemUuid}
                    onChange={(v) => setItemUuid(v ? String(v) : '')}
                    placeholder="انتخاب سرویس..."
                    isDisabled={!sectionUuid}
                  />
                </div>
                <button type="button" className="btn primary sm" onClick={handleAddService} disabled={!itemUuid}>
                  <PlusIcon style={{ width: 14 }} />
                </button>
              </div>

              {selectedServices.length > 0 && (
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 10 }}>
                  {selectedServices.map((svc) => (
                    <div
                      key={svc.service_item_uuid}
                      style={{
                        display: 'inline-flex', alignItems: 'center', gap: 8,
                        background: 'var(--primary-subtle)', border: '1px solid oklch(0.85 0.06 256)',
                        borderRadius: 20, padding: '4px 10px', fontSize: 12.5,
                      }}
                    >
                      <span style={{ fontWeight: 500 }}>{svc.name}</span>
                      <span style={{ color: 'var(--primary)', fontWeight: 600 }}>{formatRial(svc.price_rials)}</span>
                      <button
                        type="button"
                        style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger)', padding: 0, fontSize: 14, lineHeight: 1 }}
                        onClick={() => setSelectedServices((p) => p.filter((s) => s.service_item_uuid !== svc.service_item_uuid))}
                      >×</button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            <div style={{ background: 'var(--primary-subtle)', border: '1px solid oklch(0.88 0.05 256)', borderRadius: 10, padding: 14 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6, fontSize: 13, color: 'var(--text-3)' }}>
                <span>جمع خدمات</span>
                <span>{formatRial(servicesTotal)}</span>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontWeight: 700, fontSize: 15 }}>
                <span>مبلغ نهایی</span>
                <span style={{ color: 'var(--primary)' }}>{formatRial(finalPrice)}</span>
              </div>
            </div>

            <div style={{ display: 'flex', gap: 8 }}>
              <button type="submit" className="btn primary" disabled={createSessionMut.isPending}>
                {createSessionMut.isPending ? 'در حال ذخیره...' : 'ثبت مراجعه'}
              </button>
              <button type="button" className="btn" onClick={() => setSessionModal(false)}>انصراف</button>
            </div>
          </div>
        </form>
      </Modal>

      <EditSessionModal
        session={editSession}
        onClose={() => setEditSession(null)}
        onSave={(uuid, body) => updateSessionMut.mutate({ uuid, body })}
        loading={updateSessionMut.isPending}
      />
    </>
  );
}

function SessionRow({ session, onEdit }: { session: PatientSession; onEdit: (s: PatientSession) => void }) {
  const [open, setOpen] = useState(false);
  const badgeColor = PAYMENT_BADGE[session.payment_method] ?? 'gray';

  return (
    <div style={{
      borderBottom: '1px solid var(--border)',
      transition: 'background 0.1s',
    }}>
      <div
        style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          padding: '12px 16px', cursor: 'pointer',
        }}
        onClick={() => setOpen(!open)}
      >
        <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
          <div style={{
            width: 8, height: 8, borderRadius: '50%',
            background: open ? 'var(--primary)' : 'var(--border)',
            transition: 'background 0.15s', flexShrink: 0,
          }} />
          <span style={{ fontSize: 13, color: 'var(--text-3)' }}>{formatDateTime(session.created_at)}</span>
          <span className={`badge ${badgeColor}`}>
            {PAYMENT_LABELS[session.payment_method] ?? session.payment_method}
          </span>
          <b style={{ fontSize: 14, color: 'var(--primary)' }}>{formatRial(session.final_price_rials)}</b>
        </div>
        <button
          className="btn sm"
          onClick={(e) => { e.stopPropagation(); onEdit(session); }}
          title="ویرایش مراجعه"
        >
          <PencilIcon style={{ width: 14 }} />
        </button>
      </div>

      {open && (
        <div style={{ padding: '0 16px 14px' }}>
          <div style={{
            background: 'var(--surface)',
            border: '1px solid var(--border)',
            borderRadius: 10,
            padding: 14,
            display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, fontSize: 13,
          }}>
            <div>
              <div style={{ color: 'var(--text-3)', marginBottom: 4, fontSize: 12 }}>قیمت ویزیت</div>
              <div style={{ fontWeight: 600 }}>{formatRial(session.visit_price_rials)}</div>
            </div>
            <div>
              <div style={{ color: 'var(--text-3)', marginBottom: 4, fontSize: 12 }}>تخفیف بیمه پایه</div>
              <div style={{ fontWeight: 600 }}>{formatNumber(parseFloat(session.base_insurance_discount_percent))}٪</div>
            </div>
            <div>
              <div style={{ color: 'var(--text-3)', marginBottom: 4, fontSize: 12 }}>جمع خدمات</div>
              <div style={{ fontWeight: 600 }}>{formatRial(session.services_total_rials)}</div>
            </div>
            {session.notes && (
              <div style={{ gridColumn: '1 / -1', borderTop: '1px solid var(--border)', paddingTop: 10, marginTop: 2 }}>
                <div style={{ color: 'var(--text-3)', marginBottom: 4, fontSize: 12 }}>یادداشت</div>
                <div style={{ lineHeight: 1.6 }}>{session.notes}</div>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

function EditSessionModal({
  session, onClose, onSave, loading,
}: {
  session: PatientSession | null;
  onClose: () => void;
  onSave: (uuid: string, body: object) => void;
  loading: boolean;
}) {
  const [notes, setNotes]   = useState('');
  const [method, setMethod] = useState('cash');

  React.useEffect(() => {
    if (session) { setNotes(session.notes ?? ''); setMethod(session.payment_method); }
  }, [session]);

  return (
    <Modal open={!!session} onClose={onClose} title="ویرایش مراجعه">
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        <div className="field">
          <label>روش پرداخت</label>
          <select value={method} onChange={(e) => setMethod(e.target.value)}>
            {Object.entries(PAYMENT_LABELS).map(([v, l]) => (
              <option key={v} value={v}>{l}</option>
            ))}
          </select>
        </div>
        <div className="field">
          <label>یادداشت</label>
          <textarea value={notes} onChange={(e) => setNotes(e.target.value)} rows={3} />
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button
            className="btn primary"
            disabled={loading}
            onClick={() => session && onSave(session.uuid, { notes, payment_method: method })}
          >
            {loading ? 'در حال ذخیره...' : 'ذخیره'}
          </button>
          <button className="btn" onClick={onClose}>انصراف</button>
        </div>
      </div>
    </Modal>
  );
}
