import React, { useState, useEffect, useMemo, useRef } from 'react';
import { createPortal } from 'react-dom';
import { useParams, useNavigate } from 'react-router-dom';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
  ArrowRightIcon, PencilIcon, TrashIcon,
  BuildingOffice2Icon, PhoneIcon, MapPinIcon, XMarkIcon,
  PlusIcon, CameraIcon, ChevronDownIcon,
  EnvelopeIcon, ArrowPathIcon, NoSymbolIcon, EyeIcon,
} from '@heroicons/react/24/outline';
import { MapContainer, TileLayer, Marker, useMapEvents, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import type { ClinicDetail } from '../types';
import { formatNumber } from '../lib/utils';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import NotificationMobileCard from '../components/ui/NotificationMobileCard';
import InviteDoctorModal from '../components/ui/InviteDoctorModal';
import { useAuthStore } from '../stores/authStore';

// Fix leaflet icons
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
  iconUrl:       'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
  shadowUrl:     'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
});

const HUES_LIST = [256, 205, 162, 295, 272];
const IRAN_CENTER: [number, number] = [32.4279, 53.6880];
const MAX_GALLERY_IMAGES = 5;

// ── Types ──────────────────────────────────────────────────────────────────

interface ClinicInvitation {
  uuid: string;
  mobile: string;
  invited_name: string | null;
  invited_specialty: string | null;
  status: 'pending' | 'accepted' | 'rejected' | 'suspended' | 'removed';
  token_used: boolean;
  invited_at: number;
  expires_at: number;
  responded_at: number | null;
  doctor: { uuid: string; name: string } | null;
}

interface ClinicDoctorItem {
  id: string; uuid: string; name: string;
  gender: string | null; degree: string | null;
  img: { url: string }[];
  specialties: { id: string; name: string }[];
  active: boolean;
}

interface ClinicAddress {
  id: string; uuid: string;
  name: string | null; address: string | null;
  telephone: string | null;
  map: { latitude: string | null; longitude: string | null };
  city:     { id: string; name: string } | null;
  province: { id: string; name: string } | null;
}

interface Opt { id: number; name: string; }
interface OptUuid { id: number; uuid: string; name: string; }

// ── Edit form schema ───────────────────────────────────────────────────────

const urlOrEmpty = z.string().refine(v => v === '' || /^https?:\/\/.+/.test(v), { message: 'آدرس URL معتبر نیست' });

const editSchema = z.object({
  name:        z.string().min(1, 'نام الزامی است'),
  telephone:   z.string().optional(),
  info:        z.string().optional(),
  is_247:      z.boolean(),
  specialties: z.array(z.number()),
  insurance:   z.array(z.number()),
  doctor_services: z.array(z.number()),
  sm_instagram: urlOrEmpty,
  sm_telegram:  urlOrEmpty,
  sm_aparat:    urlOrEmpty,
  sm_youtube:   urlOrEmpty,
  sm_linkedin:  urlOrEmpty,
});
type EditForm = z.infer<typeof editSchema>;

// ── Searchable Select (template CSS) ──────────────────────────────────────

function SearchableSelectField({ options, value, onChange, placeholder, disabled = false }: {
  options: Opt[];
  value: number | null;
  onChange: (v: number | null, label?: string) => void;
  placeholder?: string;
  disabled?: boolean;
}) {
  const [open, setOpen] = useState(false);
  const [q,    setQ]    = useState('');
  const [rect, setRect] = useState<DOMRect | null>(null);
  const btnRef = useRef<HTMLButtonElement>(null);
  const dropRef = useRef<HTMLDivElement>(null);

  const filtered = useMemo(
    () => q ? options.filter(o => o.name.includes(q)) : options,
    [options, q],
  );
  const selected = useMemo(() => options.find(o => o.id === value) ?? null, [options, value]);

  const openDD = () => {
    if (disabled || !btnRef.current) return;
    setRect(btnRef.current.getBoundingClientRect());
    setOpen(v => !v);
    setQ('');
  };

  useEffect(() => {
    if (!open) return;
    const onDown = (e: MouseEvent) => {
      if (dropRef.current && !dropRef.current.contains(e.target as Node) &&
          btnRef.current  && !btnRef.current.contains(e.target as Node))
        setOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);

  const dropStyle: React.CSSProperties = rect
    ? { position: 'fixed', top: rect.bottom + 4, left: rect.left, width: rect.width, zIndex: 9999 }
    : {};

  return (
    <div>
      <button ref={btnRef} type="button" disabled={disabled} onClick={openDD}
        style={{
          width: '100%', textAlign: 'right', display: 'flex', alignItems: 'center',
          justifyContent: 'space-between', padding: '8px 12px', borderRadius: 8,
          border: '1px solid var(--border)', background: disabled ? 'var(--surface-2, var(--bg))' : 'var(--surface)',
          color: selected ? 'var(--text)' : 'var(--text-3)', cursor: disabled ? 'not-allowed' : 'pointer',
          fontSize: 14, opacity: disabled ? 0.6 : 1,
        }}>
        <span>{selected?.name ?? placeholder ?? 'انتخاب کنید'}</span>
        <ChevronDownIcon style={{ width: 14, height: 14, flexShrink: 0, transform: open ? 'rotate(180deg)' : 'none', transition: 'transform .15s' }} />
      </button>
      {open && createPortal(
        <div ref={dropRef} style={{
          ...dropStyle,
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 10, boxShadow: '0 8px 32px rgba(0,0,0,.12)', overflow: 'hidden',
        }}>
          <div style={{ padding: '8px 8px 0' }}>
            <input autoFocus value={q} onChange={e => setQ(e.target.value)} placeholder="جستجو..."
              className="input" style={{ fontSize: 13 }} />
          </div>
          <div style={{ maxHeight: 200, overflowY: 'auto', padding: '4px 0' }}>
            <button type="button"
              onClick={() => { onChange(null); setOpen(false); }}
              style={{ width: '100%', textAlign: 'right', padding: '8px 12px', fontSize: 13, color: 'var(--text-3)', background: 'none', border: 'none', cursor: 'pointer' }}>
              {placeholder ?? 'انتخاب کنید'}
            </button>
            {filtered.map(o => (
              <button key={o.id} type="button"
                onClick={() => { onChange(o.id, o.name); setOpen(false); setQ(''); }}
                style={{
                  width: '100%', textAlign: 'right', padding: '8px 12px', fontSize: 13,
                  background: value === o.id ? 'var(--primary-light, oklch(0.95 0.04 256))' : 'none',
                  color: value === o.id ? 'var(--primary)' : 'var(--text)', border: 'none', cursor: 'pointer',
                }}>
                {o.name}
              </button>
            ))}
            {filtered.length === 0 && (
              <p style={{ textAlign: 'center', padding: '10px 0', fontSize: 12, color: 'var(--text-3)' }}>نتیجه‌ای یافت نشد</p>
            )}
          </div>
        </div>,
        document.body,
      )}
    </div>
  );
}

// ── Multi-select checkbox list ─────────────────────────────────────────────

function MultiCheckList({ options, selected, onChange, placeholder }: {
  options: Opt[]; selected: number[]; onChange: (v: number[]) => void; placeholder?: string;
}) {
  const [q, setQ] = useState('');
  const filtered = useMemo(() => q ? options.filter(o => o.name.includes(q)) : options, [options, q]);
  const toggle = (id: number) =>
    onChange(selected.includes(id) ? selected.filter(x => x !== id) : [...selected, id]);

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden' }}>
      <div style={{ padding: '6px 8px', borderBottom: '1px solid var(--border)', background: 'var(--surface-2, var(--bg))' }}>
        <input value={q} onChange={e => setQ(e.target.value)} placeholder={placeholder ?? 'جستجو...'}
          className="input" style={{ fontSize: 13 }} />
      </div>
      {selected.length > 0 && (
        <div style={{ padding: '6px 10px', borderBottom: '1px solid var(--border)', display: 'flex', flexWrap: 'wrap', gap: 4 }}>
          {selected.map(id => {
            const opt = options.find(o => o.id === id);
            if (!opt) return null;
            return (
              <span key={id} className="badge violet" style={{ cursor: 'pointer', userSelect: 'none' }}
                onClick={() => toggle(id)}>
                <span className="bdot" />{opt.name} ×
              </span>
            );
          })}
        </div>
      )}
      <div style={{ maxHeight: 180, overflowY: 'auto' }}>
        {filtered.length === 0
          ? <p style={{ textAlign: 'center', padding: '10px 0', fontSize: 12, color: 'var(--text-3)' }}>نتیجه‌ای یافت نشد</p>
          : filtered.map(o => (
            <label key={o.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '7px 12px', cursor: 'pointer' }}>
              <input type="checkbox" checked={selected.includes(o.id)} onChange={() => toggle(o.id)} />
              <span style={{ fontSize: 13, color: 'var(--text)' }}>{o.name}</span>
            </label>
          ))}
      </div>
    </div>
  );
}

// ── Leaflet helpers ────────────────────────────────────────────────────────

function MapClickHandler({ onPick }: { onPick: (lat: number, lng: number) => void }) {
  useMapEvents({ click: e => onPick(e.latlng.lat, e.latlng.lng) });
  return null;
}
function MapFlyController({ target }: { target: [number, number] | null }) {
  const map = useMap();
  useEffect(() => { if (target) map.flyTo(target, 12, { duration: 1.2 }); }, [target, map]);
  return null;
}
function MapPicker({ lat, lng, onChange, flyTarget, initialCenter }: {
  lat: number | null; lng: number | null;
  onChange: (lat: number, lng: number) => void;
  flyTarget?: [number, number] | null;
  initialCenter?: [number, number] | null;
}) {
  const pos: [number, number] | null = lat !== null && lng !== null ? [lat, lng] : null;
  const center: [number, number] = initialCenter ?? pos ?? IRAN_CENTER;
  const zoom = initialCenter ?? pos ? 13 : 5;
  return (
    <div style={{ borderRadius: 10, overflow: 'hidden', border: '1px solid var(--border)', height: 260 }}>
      <MapContainer key={`${center[0]},${center[1]}`} center={center} zoom={zoom} style={{ height: '100%', width: '100%' }}>
        <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://openstreetmap.org">OpenStreetMap</a>' />
        <MapClickHandler onPick={onChange} />
        <MapFlyController target={flyTarget ?? null} />
        {pos && <Marker position={pos} />}
      </MapContainer>
    </div>
  );
}

// ── Geocode helper ─────────────────────────────────────────────────────────

async function geocodeCity(name: string): Promise<[number, number] | null> {
  try {
    const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(name + ',ایران')}&format=json&countrycodes=ir&limit=1`;
    const res = await fetch(url, { headers: { 'Accept-Language': 'fa' } });
    const d = await res.json();
    if (d?.[0]) return [parseFloat(d[0].lat), parseFloat(d[0].lon)];
    return null;
  } catch { return null; }
}

// ── Edit Modal ─────────────────────────────────────────────────────────────

function EditModal({ clinic, onClose, onSaved }: {
  clinic: ClinicDetail; onClose: () => void; onSaved: () => void;
}) {
  const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm<EditForm>({
    resolver: zodResolver(editSchema),
    defaultValues: {
      name:        clinic.name ?? '',
      telephone:   clinic.phone ?? clinic.phone_number ?? '',
      info:        clinic.caption ?? '',
      is_247:      clinic['24_7'] ?? false,
      specialties: (clinic.specialties ?? []).map(s => Number(s.id)),
      insurance:   (clinic.list_bime  ?? []).map(s => Number(s.id)),
      doctor_services: (clinic.services ?? []).map(s => Number(s.id)),
      sm_instagram: clinic.social_media?.instagram ?? '',
      sm_telegram:  clinic.social_media?.telegram  ?? '',
      sm_aparat:    clinic.social_media?.aparat    ?? '',
      sm_youtube:   clinic.social_media?.youtube   ?? '',
      sm_linkedin:  clinic.social_media?.linkedin  ?? '',
    },
  });

  const watchedSpec  = (watch('specialties') ?? []) as number[];
  const watchedIns   = (watch('insurance')   ?? []) as number[];
  const watchedSrv   = (watch('doctor_services') ?? []) as number[];

  const specialtiesQ = useQuery({
    queryKey: ['specialties-all'], staleTime: 600_000,
    queryFn: () => api.get<ApiResponse<any>>('/api/v1/specialties'),
  });
  const insurancesQ = useQuery({
    queryKey: ['insurances-all'], staleTime: 600_000,
    queryFn: () => api.get<ApiResponse<any>>('/api/v1/insurances'),
  });
  const servicesQ = useQuery({
    queryKey: ['doctor-services-all'], staleTime: 600_000,
    queryFn: () => api.get<ApiResponse<any>>('/api/v1/doctor-services'),
  });

  const specialties: Opt[] = useMemo(() => {
    const raw = specialtiesQ.data?.data?.data ?? specialtiesQ.data?.data ?? [];
    return raw.map((s: any) => ({ id: Number(s.id), name: s.name }));
  }, [specialtiesQ.data]);
  const insurances: Opt[] = useMemo(() => {
    const raw = insurancesQ.data?.data?.data ?? insurancesQ.data?.data ?? [];
    return raw.map((i: any) => ({ id: Number(i.id), name: i.name }));
  }, [insurancesQ.data]);
  const services: Opt[] = useMemo(() => {
    const raw = servicesQ.data?.data?.data ?? servicesQ.data?.data ?? [];
    return raw.map((s: any) => ({ id: Number(s.id), name: s.name }));
  }, [servicesQ.data]);

  const saveMut = useMutation({
    mutationFn: (values: EditForm) => api.patch<ApiResponse<any>>(`/api/v1/clinic/${clinic.uuid}`, {
      name:            values.name,
      telephone:       values.telephone || undefined,
      info:            values.info      || undefined,
      '24_7':          values.is_247,
      specialties:     values.specialties,
      insurance:       values.insurance,
      doctor_services: values.doctor_services,
      social_media: {
        instagram: values.sm_instagram || null,
        telegram:  values.sm_telegram  || null,
        aparat:    values.sm_aparat    || null,
        youtube:   values.sm_youtube   || null,
        linkedin:  values.sm_linkedin  || null,
      },
    }),
    onSuccess: () => { toast.success('اطلاعات کلینیک ذخیره شد'); onSaved(); onClose(); },
    onError:   (e: Error) => toast.error(e.message),
  });

  const [activeTab, setActiveTab] = useState<'basic' | 'tags' | 'social'>('basic');

  return createPortal(
    <div className="overlay" onClick={onClose}>
      <div className="modal" style={{ maxWidth: 560, maxHeight: '90vh', overflowY: 'auto' }} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <b>ویرایش کلینیک</b>
          <button className="mini-btn" onClick={onClose}>
            <XMarkIcon style={{ width: 16, height: 16 }} />
          </button>
        </div>

        {/* Tab switcher */}
        <div style={{ borderBottom: '1px solid var(--border)', padding: '0 16px', display: 'flex', gap: 4 }}>
          {([['basic', 'اطلاعات پایه'], ['tags', 'تخصص و بیمه'], ['social', 'شبکه‌های اجتماعی']] as const).map(([id, label]) => (
            <button key={id} type="button" onClick={() => setActiveTab(id)}
              style={{
                padding: '10px 14px', fontSize: 13, fontWeight: 600, border: 'none', background: 'none',
                cursor: 'pointer', borderBottom: activeTab === id ? '2px solid var(--primary)' : '2px solid transparent',
                color: activeTab === id ? 'var(--primary)' : 'var(--text-3)', marginBottom: -1,
              }}>
              {label}
            </button>
          ))}
        </div>

        <form onSubmit={handleSubmit(v => saveMut.mutate(v))}>
          <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>

            {/* ── Basic tab ── */}
            {activeTab === 'basic' && (
              <>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>نام کلینیک</label>
                  <input className="input" {...register('name')} />
                  {errors.name && <div className="err-text">{errors.name.message}</div>}
                </div>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>تلفن</label>
                  <input className="input" dir="ltr" placeholder="021-12345678" {...register('telephone')} />
                </div>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>توضیحات</label>
                  <textarea className="input" rows={3} style={{ resize: 'vertical' }} {...register('info')} />
                </div>
                <label style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', userSelect: 'none' }}>
                  <input type="checkbox" {...register('is_247')} />
                  <span style={{ fontSize: 13, fontWeight: 600 }}>کلینیک ۲۴ ساعته (۷ روز هفته)</span>
                </label>
              </>
            )}

            {/* ── Social tab ── */}
            {activeTab === 'social' && (
              <>
                {([
                  ['sm_instagram', 'اینستاگرام', 'https://instagram.com/...'],
                  ['sm_telegram',  'تلگرام',     'https://t.me/...'],
                  ['sm_aparat',    'آپارات',      'https://aparat.com/...'],
                  ['sm_youtube',   'یوتیوب',      'https://youtube.com/...'],
                  ['sm_linkedin',  'لینکدین',     'https://linkedin.com/...'],
                ] as const).map(([field, label, placeholder]) => (
                  <div key={field}>
                    <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>{label}</label>
                    <input className="input" dir="ltr" placeholder={placeholder} {...register(field)} />
                    {errors[field] && <div className="err-text">{errors[field]?.message}</div>}
                  </div>
                ))}
              </>
            )}

            {/* ── Tags tab ── */}
            {activeTab === 'tags' && (
              <>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>
                    تخصص‌ها ({watchedSpec.length} انتخاب‌شده)
                  </label>
                  <MultiCheckList options={specialties} selected={watchedSpec}
                    onChange={v => setValue('specialties', v)} placeholder="جستجوی تخصص..." />
                </div>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>
                    بیمه‌ها ({watchedIns.length} انتخاب‌شده)
                  </label>
                  <MultiCheckList options={insurances} selected={watchedIns}
                    onChange={v => setValue('insurance', v)} placeholder="جستجوی بیمه..." />
                </div>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>
                    خدمات ({watchedSrv.length} انتخاب‌شده)
                  </label>
                  <MultiCheckList options={services} selected={watchedSrv}
                    onChange={v => setValue('doctor_services', v)} placeholder="جستجوی خدمت..." />
                </div>
              </>
            )}
          </div>

          <div className="modal-foot">
            <button type="button" className="btn ghost sm" onClick={onClose}>انصراف</button>
            <button type="submit" className="btn primary sm" disabled={saveMut.isPending}>
              {saveMut.isPending ? 'در حال ذخیره...' : 'ذخیره تغییرات'}
            </button>
          </div>
        </form>
      </div>
    </div>,
    document.body,
  );
}

// ── Invitation status badge ────────────────────────────────────────────────

const INV_STATUS_MAP: Record<string, { label: string; cls: string }> = {
  pending:   { label: 'در انتظار',   cls: 'amber' },
  accepted:  { label: 'پذیرفته‌شده', cls: 'green' },
  rejected:  { label: 'رد شده',      cls: 'gray'  },
  suspended: { label: 'تعلیق',       cls: 'violet' },
  removed:   { label: 'حذف‌شده',     cls: 'gray'  },
};


// ── Main Page ──────────────────────────────────────────────────────────────

export default function ClinicDetailPage() {
  const { uuid }   = useParams<{ uuid: string }>();
  const navigate   = useNavigate();
  const qc         = useQueryClient();
  const primaryRole = useAuthStore(s => s.primaryRole);
  const dbUuid      = useAuthStore(s => s.dbUuid);
  const authToken   = useAuthStore(s => s.token);
  const isOwner     = primaryRole === 'clinic' && dbUuid === uuid;
  // نماینده فقط مشاهده می‌کند؛ هیچ بخشی قابل ویرایش نیست.
  const isReadOnly  = primaryRole === 'representation';

  const [editOpen, setEditOpen]         = useState(false);
  const [deleteOpen, setDeleteOpen]     = useState(false);
  const [inviteOpen, setInviteOpen]     = useState(false);
  const [doctorsTab, setDoctorsTab] = useState<'doctors' | 'invitations'>('doctors');
  const logoInputRef    = useRef<HTMLInputElement>(null);
  const galleryInputRef = useRef<HTMLInputElement>(null);
  const [logoUploading,    setLogoUploading]    = useState(false);
  const [galleryUploading, setGalleryUploading] = useState(false);

  const { data, isLoading } = useQuery({
    queryKey: ['clinic-detail', uuid],
    queryFn:  () => api.get<ApiResponse<{ data: ClinicDetail }>>(`/api/v1/clinic/${uuid}`),
    enabled:  !!uuid,
  });

  const doctorsQ = useQuery({
    queryKey: ['clinic-doctors', uuid],
    queryFn:  () => api.get<ApiResponse<{ data: ClinicDoctorItem[] }>>(`/api/v1/clinic/doctor-list/${uuid}`),
    enabled:  !!uuid,
  });

  const invitationsQ = useQuery({
    queryKey: ['clinic-invitations', uuid],
    queryFn:  () => api.get<PaginatedResponse<ClinicInvitation>>(`/api/v1/admin/clinic/${uuid}/invitations?limit=50`),
    enabled:  !!uuid,
  });

  const clinicAddressesQ = useQuery({
    queryKey: ['clinic-addresses', uuid],
    queryFn:  () => api.get<ApiResponse<ClinicAddress[]>>(`/api/v1/clinic/${uuid}/addresses`),
    enabled:  !!uuid,
  });
  const clinicAddresses: ClinicAddress[] = (clinicAddressesQ.data?.data as any)?.data ?? clinicAddressesQ.data?.data ?? [];

  const [addrFormOpen,      setAddrFormOpen]      = useState(false);
  const [editingClinicAddr, setEditingClinicAddr] = useState<ClinicAddress | null>(null);
  const [deleteAddrConfirm, setDeleteAddrConfirm] = useState<ClinicAddress | null>(null);
  const [deleteImageConfirm, setDeleteImageConfirm] = useState<string | null>(null);
  const [detachDoctorConfirm, setDetachDoctorConfirm] = useState<ClinicDoctorItem | null>(null);

  const emptyAddrForm = { name: '', address: '', telephone: '', province_id: null as number | null, city_id: null as number | null, latitude: null as number | null, longitude: null as number | null };
  const [addrForm, setAddrForm] = useState(emptyAddrForm);
  const [addrMapFlyTarget, setAddrMapFlyTarget] = useState<[number, number] | null>(null);

  const provincesQ = useQuery({
    queryKey: ['provinces'], staleTime: 600_000,
    queryFn: () => api.get<ApiResponse<any>>('/api/v1/provinces'),
  });
  const citiesQ = useQuery({
    queryKey: ['cities', addrForm.province_id], staleTime: 300_000,
    queryFn: () => api.get<ApiResponse<any>>(`/api/v1/cities?province_id=${addrForm.province_id}`),
    enabled: !!addrForm.province_id,
  });
  const provinces: Opt[] = useMemo(() => (provincesQ.data?.data?.data ?? provincesQ.data?.data ?? []).map((p: any) => ({ id: Number(p.id ?? p.nid), name: p.name })), [provincesQ.data]);
  const addrCities: Opt[] = useMemo(() => (citiesQ.data?.data?.data ?? citiesQ.data?.data ?? []).map((c: any) => ({ id: Number(c.id ?? c.nid), name: c.name })), [citiesQ.data]);

  const openAddrForm = (addr: ClinicAddress | null) => {
    setEditingClinicAddr(addr);
    const lat = addr?.map?.latitude  ? parseFloat(addr.map.latitude)  : null;
    const lng = addr?.map?.longitude ? parseFloat(addr.map.longitude) : null;
    setAddrForm(addr ? {
      name: addr.name ?? '', address: addr.address ?? '', telephone: addr.telephone ?? '',
      province_id: addr.province ? Number(addr.province.id) : null,
      city_id:     addr.city     ? Number(addr.city.id)     : null,
      latitude: lat, longitude: lng,
    } : emptyAddrForm);
    setAddrMapFlyTarget(lat && lng ? [lat, lng] : null);
    setAddrFormOpen(true);
  };

  const saveAddrMutation = useMutation({
    mutationFn: (payload: typeof addrForm) => {
      if (editingClinicAddr) {
        return api.patch<ApiResponse<ClinicAddress>>(`/api/v1/clinic/${uuid}/address/${editingClinicAddr.uuid}`, payload);
      }
      return api.post<ApiResponse<ClinicAddress>>(`/api/v1/clinic/${uuid}/address`, payload);
    },
    onSuccess: () => {
      toast.success(editingClinicAddr ? 'آدرس ویرایش شد' : 'آدرس اضافه شد');
      qc.invalidateQueries({ queryKey: ['clinic-addresses', uuid] });
      setAddrFormOpen(false);
      setEditingClinicAddr(null);
      setAddrForm(emptyAddrForm);
    },
    onError: () => toast.error('خطا در ذخیره آدرس'),
  });

  const deleteAddrMutation = useMutation({
    mutationFn: (addrUuid: string) => api.delete<ApiResponse<null>>(`/api/v1/clinic/${uuid}/address/${addrUuid}`),
    onSuccess: () => {
      toast.success('آدرس حذف شد');
      qc.invalidateQueries({ queryKey: ['clinic-addresses', uuid] });
      setDeleteAddrConfirm(null);
    },
    onError: (err: any) => toast.error(err?.message ?? 'خطا در حذف آدرس'),
  });

  const clinic: ClinicDetail | undefined = useMemo(() => {
    const raw = data?.data;
    return (raw as any)?.data ?? raw;
  }, [data]);

  const doctorList: ClinicDoctorItem[] = useMemo(() => {
    const raw = doctorsQ.data?.data;
    return (raw as any)?.data ?? raw ?? [];
  }, [doctorsQ.data]);

  const invitationList: ClinicInvitation[] = invitationsQ.data?.data ?? [];

  const openEdit = () => setEditOpen(true);

  const toggleMut = useMutation({
    mutationFn: () => api.patch<ApiResponse<any>>(`/api/v1/admin/clinic/${uuid}/status`, {}),
    onSuccess: () => {
      toast.success('وضعیت کلینیک تغییر کرد');
      qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] });
      qc.invalidateQueries({ queryKey: ['admin-clinics'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMut = useMutation({
    mutationFn: () => api.delete<ApiResponse<null>>(`/api/v1/admin/clinic/${uuid}`),
    onSuccess: () => { toast.success('کلینیک حذف شد'); navigate('/admin/clinics'); },
    onError:   (e: Error) => toast.error(e.message),
  });

  const resendInvMut = useMutation({
    mutationFn: (invUuid: string) => api.post<ApiResponse<any>>(`/api/v1/admin/clinic/invitation/${invUuid}/resend`, {}),
    onSuccess: () => { toast.success('پیامک مجدداً ارسال شد'); qc.invalidateQueries({ queryKey: ['clinic-invitations', uuid] }); },
    onError:   (e: Error) => toast.error(e.message),
  });

  const changeInvStatusMut = useMutation({
    mutationFn: ({ invUuid, status }: { invUuid: string; status: string }) =>
      api.patch<ApiResponse<any>>(`/api/v1/admin/clinic/invitation/${invUuid}/status`, { status }),
    onSuccess: () => { toast.success('وضعیت دعوتنامه تغییر کرد'); qc.invalidateQueries({ queryKey: ['clinic-invitations', uuid] }); },
    onError:   (e: Error) => toast.error(e.message),
  });

  const deleteInvMut = useMutation({
    mutationFn: (invUuid: string) => api.delete<ApiResponse<null>>(`/api/v1/admin/clinic/invitation/${invUuid}`),
    onSuccess: () => { toast.success('دعوتنامه حذف شد'); qc.invalidateQueries({ queryKey: ['clinic-invitations', uuid] }); },
    onError:   (e: Error) => toast.error(e.message),
  });

  const detachDoctorMut = useMutation({
    mutationFn: (doctorUuid: string) =>
      api.delete<ApiResponse<{ message: string }>>(`/api/v1/admin/clinic/${uuid}/doctor/${doctorUuid}`),
    onSuccess: () => {
      toast.success('پزشک از کلینیک جدا شد');
      qc.invalidateQueries({ queryKey: ['clinic-doctors', uuid] });
      qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const handleLogoUpload = async (file: File) => {
    setLogoUploading(true);
    try {
      const res = await fetch('/file/upload/clinic_pro/clinic/field_clinic_logo', {
        method: 'POST',
        headers: {
          'Content-Disposition': `filename="${file.name}"`,
          'Content-Type': file.type || 'application/octet-stream',
          Authorization: `Bearer ${authToken ?? ''}`,
        },
        body: file,
      });
      const json = await res.json();
      const url  = json?.data?.url;
      if (url) {
        await api.patch(`/api/v1/clinic/${uuid}`, { clinic_logo: url });
        toast.success('لوگو آپلود شد');
        qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] });
      }
    } catch (e: any) { toast.error(e.message); }
    finally { setLogoUploading(false); }
  };

  const handleGalleryUpload = async (files: FileList) => {
    const existing = (clinic?.images_clinic ?? []).filter(img => img?.url);
    const remaining = MAX_GALLERY_IMAGES - existing.length;
    if (remaining <= 0) {
      toast.error(`گالری حداکثر ${MAX_GALLERY_IMAGES} عکس می‌تواند داشته باشد`);
      return;
    }
    const selected = Array.from(files);
    if (selected.length > remaining) {
      toast.error(`فقط ${remaining} عکس دیگر می‌توانید اضافه کنید (حداکثر ${MAX_GALLERY_IMAGES})`);
    }
    const toUpload = selected.slice(0, remaining);
    setGalleryUploading(true);
    try {
      const uploaded: { url: string }[] = [];
      for (const file of toUpload) {
        const res = await fetch('/file/upload/clinic_pro/clinic/field_image_clinic', {
          method: 'POST',
          headers: {
            'Content-Disposition': `filename="${file.name}"`,
            'Content-Type': file.type || 'application/octet-stream',
            Authorization: `Bearer ${authToken ?? ''}`,
          },
          body: file,
        });
        const json = await res.json();
        if (json?.data?.url) uploaded.push({ url: json.data.url });
      }
      if (uploaded.length > 0 && clinic) {
        await api.patch(`/api/v1/clinic/${uuid}`, { image_clinic: [...existing, ...uploaded] });
        toast.success(`${uploaded.length} تصویر اضافه شد`);
        qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] });
      }
    } catch (e: any) { toast.error(e.message); }
    finally { setGalleryUploading(false); }
  };

  const handleGalleryRemove = async (url: string) => {
    if (!clinic) return;
    try {
      const remaining = (clinic.images_clinic ?? []).filter(img => img?.url && img.url !== url);
      await api.patch(`/api/v1/clinic/${uuid}`, { image_clinic: remaining });
      toast.success('تصویر حذف شد');
      qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] });
    } catch (e: any) { toast.error(e?.message ?? 'خطا در حذف تصویر'); }
  };

  const hue = HUES_LIST[(uuid?.charCodeAt(0) ?? 0) % HUES_LIST.length];
  const logo = clinic?.logo ?? clinic?.clinic_logo;
  // شهر و استان از آدرس DoctorAddress (منبع واقعی) نه از Clinic entity
  const primaryAddr  = clinicAddresses[0] ?? null;
  const cityName     = primaryAddr?.city?.name     ?? clinic?.city?.[0]?.name;
  const provinceName = primaryAddr?.province?.name ?? clinic?.state?.[0]?.name;
  const lat  = primaryAddr?.map?.latitude  ? parseFloat(primaryAddr.map.latitude)
             : clinic?.map?.latitude  ? parseFloat(clinic.map.latitude)  : null;
  const lng  = primaryAddr?.map?.longitude ? parseFloat(primaryAddr.map.longitude)
             : clinic?.map?.longitude ? parseFloat(clinic.map.longitude) : null;

  if (isLoading) {
    return (
      <div className="fade-in">
        <div className="card card-pad">
          {Array.from({ length: 6 }).map((_, i) => (
            <div key={i} className="skeleton" style={{ height: 20, borderRadius: 6, marginBottom: 12 }} />
          ))}
        </div>
      </div>
    );
  }

  if (!clinic) {
    return (
      <div className="fade-in">
        <div className="card card-pad">
          <div className="empty">
            <BuildingOffice2Icon style={{ width: 36, height: 36 }} />
            <p>کلینیک یافت نشد</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="fade-in">

      {/* ── Header ── */}
      <div className="card-title-row" style={{ marginBottom: 'var(--gap)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button className="btn ghost sm" onClick={() => navigate('/admin/clinics')} style={{ padding: '6px 10px' }}>
            <ArrowRightIcon style={{ width: 16, height: 16 }} />
          </button>
          <div>
            <h1 className="section-title">{clinic.name}</h1>
            <div className="muted">جزئیات کلینیک</div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          {!isReadOnly && (
            <button className="btn ghost sm" onClick={() => openEdit()}>
              <PencilIcon style={{ width: 15, height: 15 }} /> ویرایش
            </button>
          )}
          {primaryRole === 'admin' && (
            <>
              <button className={`btn sm ${clinic.is_active ? 'soft' : 'primary'}`}
                onClick={() => toggleMut.mutate()} disabled={toggleMut.isPending}>
                {clinic.is_active ? 'غیرفعال کردن' : 'فعال کردن'}
              </button>
              <button className="btn danger sm" onClick={() => setDeleteOpen(true)}>
                <TrashIcon style={{ width: 15, height: 15 }} /> حذف
              </button>
            </>
          )}
        </div>
      </div>

      {/* ── Main grid ── */}
      <div className="split-2">

        {/* Left column */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--gap)' }}>

          {/* Identity card */}
          <div className="card card-pad">
            <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 20 }}>
              <div style={{ position: 'relative', flexShrink: 0 }}>
                {logo ? (
                  <img src={logo} alt="" className="avatar lg" style={{ objectFit: 'cover' }} />
                ) : (
                  <div className="avatar lg"
                    style={{ background: `linear-gradient(145deg, oklch(0.62 0.15 ${hue}), oklch(0.48 0.16 ${hue}))`, fontSize: 28, fontWeight: 700 }}>
                    {clinic.name?.[0] ?? '?'}
                  </div>
                )}
                {!isReadOnly && (
                  <>
                    <button onClick={() => logoInputRef.current?.click()} disabled={logoUploading}
                      style={{
                        position: 'absolute', insetInlineEnd: -6, bottom: -6, width: 24, height: 24,
                        borderRadius: '50%', background: 'var(--primary)', border: '2px solid var(--surface)',
                        display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
                      }}>
                      <CameraIcon style={{ width: 12, height: 12, color: '#fff' }} />
                    </button>
                    <input ref={logoInputRef} type="file" accept="image/*" style={{ display: 'none' }}
                      onChange={e => e.target.files?.[0] && handleLogoUpload(e.target.files[0])} />
                  </>
                )}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 20, fontWeight: 700 }}>{clinic.name}</div>
                <div style={{ display: 'flex', gap: 6, marginTop: 6, flexWrap: 'wrap' }}>
                  <span className={`badge ${clinic.is_active ? 'green' : 'gray'}`}>
                    <span className="bdot" />{clinic.is_active ? 'فعال' : 'غیرفعال'}
                  </span>
                  {clinic['24_7'] && <span className="badge amber"><span className="bdot" />۲۴ ساعته</span>}
                </div>
              </div>
            </div>

            {/* Info rows */}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <InfoTile icon={<PhoneIcon style={{ width: 15, height: 15 }} />}
                label="تلفن" value={clinic.phone ? <span dir="ltr">{clinic.phone}</span> : '—'} />
              <InfoTile icon={<MapPinIcon style={{ width: 15, height: 15 }} />}
                label="شهر"
                value={[cityName, provinceName].filter(Boolean).join('، ') || '—'} />
              <InfoTile icon={<BuildingOffice2Icon style={{ width: 15, height: 15 }} />}
                label="آدرس" value={primaryAddr?.address ?? clinic.location ?? '—'} fullWidth />
            </div>

            {clinic.caption && (
              <div style={{ marginTop: 16, padding: '12px 14px', background: 'var(--surface-2, var(--bg))', borderRadius: 8 }}>
                <div className="muted" style={{ fontSize: 12, marginBottom: 4 }}>توضیحات</div>
                <p style={{ fontSize: 13, lineHeight: 1.7 }}>{clinic.caption}</p>
              </div>
            )}
          </div>

          {/* Doctors + Invitations card */}
          <div className="card card-pad">
            {/* Card header */}
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
              <div className="seg">
                <button className={doctorsTab === 'doctors' ? 'active' : ''} onClick={() => setDoctorsTab('doctors')}>
                  پزشکان ({formatNumber(doctorList.length)})
                </button>
                <button className={doctorsTab === 'invitations' ? 'active' : ''} onClick={() => setDoctorsTab('invitations')}>
                  دعوتنامه‌ها ({formatNumber(invitationList.length)})
                </button>
              </div>
              {!isReadOnly && (
                <button className="btn primary sm" onClick={() => setInviteOpen(true)}>
                  <EnvelopeIcon style={{ width: 14, height: 14 }} /> دعوت پزشک
                </button>
              )}
            </div>

            {/* Doctors tab */}
            {doctorsTab === 'doctors' && (
              doctorList.length === 0 ? (
                <div className="empty" style={{ padding: '20px 0' }}>
                  <p className="muted">هیچ پزشکی به این کلینیک متصل نیست</p>
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {doctorList.map(doc => {
                    const dHue = HUES_LIST[(doc.uuid?.charCodeAt(0) ?? 0) % HUES_LIST.length];
                    const img  = doc.img?.[0]?.url;
                    return (
                      <div key={doc.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', borderRadius: 8, background: 'var(--surface-2, var(--bg))' }}>
                        {img
                          ? <img src={img} alt="" className="avatar sm" style={{ objectFit: 'cover', flexShrink: 0 }} />
                          : <div className="avatar sm" style={{ background: `linear-gradient(145deg, oklch(0.62 0.15 ${dHue}), oklch(0.48 0.16 ${dHue}))`, flexShrink: 0 }}>{doc.name?.[0] ?? '?'}</div>
                        }
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontWeight: 600, fontSize: 13 }}>{doc.name}</div>
                          {doc.specialties?.length > 0 && (
                            <div className="muted" style={{ fontSize: 11 }}>{doc.specialties.map(s => s.name).join('، ')}</div>
                          )}
                        </div>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                          <span className={`badge ${doc.active ? 'green' : 'gray'}`} style={{ fontSize: 11 }}>
                            <span className="bdot" />{doc.active ? 'فعال' : 'غیرفعال'}
                          </span>
                          <button
                            className="mini-btn"
                            title="مشاهده پروفایل"
                            onClick={() => navigate(`/admin/doctors/${doc.uuid}`)}
                          >
                            <EyeIcon style={{ width: 14, height: 14 }} />
                          </button>
                          <button
                            className="mini-btn danger"
                            title="جداسازی از کلینیک"
                            onClick={() => setDetachDoctorConfirm(doc)}
                          >
                            <TrashIcon style={{ width: 14, height: 14 }} />
                          </button>
                        </div>
                      </div>
                    );
                  })}
                </div>
              )
            )}

            {/* Invitations tab */}
            {doctorsTab === 'invitations' && (
              invitationList.length === 0 ? (
                <div className="empty" style={{ padding: '20px 0' }}>
                  <EnvelopeIcon style={{ width: 30, height: 30 }} />
                  <p className="muted">هیچ دعوتنامه‌ای ارسال نشده</p>
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {invitationList.map(inv => {
                    const statusInfo = INV_STATUS_MAP[inv.status] ?? { label: inv.status, cls: 'gray' };
                    const isExpired  = !inv.token_used && inv.status === 'pending' && Date.now() / 1000 > inv.expires_at;
                    return (
                      <div key={inv.uuid} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', borderRadius: 8, background: 'var(--surface-2, var(--bg))' }}>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontWeight: 600, fontSize: 13 }}>{inv.invited_name ?? inv.mobile}</div>
                          <div style={{ display: 'flex', gap: 6, marginTop: 3, flexWrap: 'wrap', alignItems: 'center' }}>
                            <span className="muted" style={{ fontSize: 11, direction: 'ltr' }}>{inv.mobile}</span>
                            {inv.invited_specialty && (
                              <span className="muted" style={{ fontSize: 11 }}>{inv.invited_specialty}</span>
                            )}
                            {inv.doctor && (
                              <button
                                className="badge blue"
                                style={{ fontSize: 11, cursor: 'pointer', border: 'none', background: 'none', padding: 0 }}
                                onClick={() => navigate(`/admin/doctors/${inv.doctor!.uuid}`)}
                              >
                                <span className="bdot" />{inv.doctor.name}
                              </button>
                            )}
                          </div>
                        </div>
                        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 6 }}>
                          <span className={`badge ${isExpired ? 'gray' : statusInfo.cls}`} style={{ fontSize: 11 }}>
                            <span className="bdot" />{isExpired ? 'منقضی' : statusInfo.label}
                          </span>
                          {!isReadOnly && (
                            <div style={{ display: 'flex', gap: 4 }}>
                              {inv.status === 'pending' && (
                                <button
                                  className="mini-btn"
                                  title="ارسال مجدد"
                                  disabled={resendInvMut.isPending}
                                  onClick={() => resendInvMut.mutate(inv.uuid)}
                                >
                                  <ArrowPathIcon style={{ width: 13, height: 13 }} />
                                </button>
                              )}
                              {inv.status !== 'removed' && inv.status !== 'accepted' && (
                                <button
                                  className="mini-btn"
                                  title="تعلیق"
                                  disabled={changeInvStatusMut.isPending}
                                  onClick={() => changeInvStatusMut.mutate({ invUuid: inv.uuid, status: inv.status === 'suspended' ? 'pending' : 'suspended' })}
                                >
                                  <NoSymbolIcon style={{ width: 13, height: 13 }} />
                                </button>
                              )}
                              <button
                                className="mini-btn danger"
                                title="حذف"
                                disabled={deleteInvMut.isPending}
                                onClick={() => deleteInvMut.mutate(inv.uuid)}
                              >
                                <TrashIcon style={{ width: 13, height: 13 }} />
                              </button>
                            </div>
                          )}
                        </div>
                      </div>
                    );
                  })}
                </div>
              )
            )}
          </div>

          {/* Gallery */}
          <div className="card card-pad">
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
              <b style={{ fontSize: 14 }}>
                گالری تصاویر ({formatNumber((clinic.images_clinic ?? []).filter(i => i?.url).length)}/{formatNumber(MAX_GALLERY_IMAGES)})
              </b>
              {!isReadOnly && (
                <>
                  <button className="btn ghost sm" onClick={() => galleryInputRef.current?.click()}
                    disabled={galleryUploading || (clinic.images_clinic ?? []).filter(i => i?.url).length >= MAX_GALLERY_IMAGES}>
                    <PlusIcon style={{ width: 14, height: 14 }} />
                    {galleryUploading ? 'در حال آپلود...' : 'افزودن تصویر'}
                  </button>
                  <input ref={galleryInputRef} type="file" accept="image/*" multiple style={{ display: 'none' }}
                    onChange={e => e.target.files?.length && handleGalleryUpload(e.target.files)} />
                </>
              )}
            </div>
            {(clinic.images_clinic ?? []).length === 0 ? (
              <div className="empty" style={{ padding: '20px 0' }}>
                <p className="muted">هیچ تصویری در گالری وجود ندارد</p>
              </div>
            ) : (
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))', gap: 8 }}>
                {clinic.images_clinic.filter(img => img?.url).map((img, i) => (
                  <div key={i} style={{ position: 'relative', borderRadius: 8, overflow: 'hidden', aspectRatio: '1', background: 'var(--surface-2, var(--bg))' }}>
                    <img src={img.url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                    {!isReadOnly && (
                      <button
                        type="button"
                        className="mini-btn danger"
                        title="حذف تصویر"
                        onClick={() => setDeleteImageConfirm(img.url)}
                        style={{ position: 'absolute', top: 6, left: 6 }}
                      >
                        <TrashIcon style={{ width: 14, height: 14 }} />
                      </button>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>

          {/* Map (read-only) */}
          {lat !== null && lng !== null && (
            <div className="card card-pad">
              <b style={{ fontSize: 14, display: 'block', marginBottom: 12 }}>موقعیت روی نقشه</b>
              <div style={{ borderRadius: 10, overflow: 'hidden', border: '1px solid var(--border)', height: 260 }}>
                <MapContainer center={[lat, lng]} zoom={13} style={{ height: '100%', width: '100%' }}>
                  <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                    attribution='&copy; <a href="https://openstreetmap.org">OpenStreetMap</a>' />
                  <Marker position={[lat, lng]} />
                </MapContainer>
              </div>
            </div>
          )}
        </div>

        {/* Right sidebar */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--gap)' }}>

          {/* Specialties + Insurances + Services combined */}
          <div className="card card-pad">
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
              <b style={{ fontSize: 13 }}>تخصص‌ها، بیمه و خدمات</b>
              {!isReadOnly && (
                <button className="btn ghost sm" style={{ fontSize: 12 }} onClick={() => openEdit()}>
                  <PencilIcon style={{ width: 13, height: 13 }} /> ویرایش
                </button>
              )}
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div>
                <div className="muted" style={{ fontSize: 11, marginBottom: 6 }}>
                  تخصص‌ها ({formatNumber((clinic.specialties ?? []).length)})
                </div>
                {(clinic.specialties ?? []).length === 0
                  ? <p className="muted" style={{ fontSize: 12 }}>ثبت نشده</p>
                  : <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                      {clinic.specialties.map(s => (
                        <span key={s.id} className="badge violet"><span className="bdot" />{s.name}</span>
                      ))}
                    </div>
                }
              </div>

              <div style={{ borderTop: '1px solid var(--border)', paddingTop: 12 }}>
                <div className="muted" style={{ fontSize: 11, marginBottom: 6 }}>
                  بیمه‌ها ({formatNumber((clinic.list_bime ?? []).length)})
                </div>
                {(clinic.list_bime ?? []).length === 0
                  ? <p className="muted" style={{ fontSize: 12 }}>ثبت نشده</p>
                  : <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                      {clinic.list_bime.map(ins => (
                        <span key={ins.id} className="badge blue"><span className="bdot" />{ins.name}</span>
                      ))}
                    </div>
                }
              </div>

              <div style={{ borderTop: '1px solid var(--border)', paddingTop: 12 }}>
                <div className="muted" style={{ fontSize: 11, marginBottom: 6 }}>
                  خدمات ({formatNumber((clinic.services ?? []).length)})
                </div>
                {(clinic.services ?? []).length === 0
                  ? <p className="muted" style={{ fontSize: 12 }}>ثبت نشده</p>
                  : <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                      {clinic.services.map(s => (
                        <span key={s.id} className="badge green"><span className="bdot" />{s.name}</span>
                      ))}
                    </div>
                }
              </div>
            </div>
          </div>

          {primaryRole === 'clinic' && (
            <NotificationMobileCard target="clinic" />
          )}

          {/* Clinic Addresses Section */}
          {(isOwner || primaryRole === 'admin' || isReadOnly) && (
            <div className="card">
              <div className="toolbar" style={{ padding: '12px 16px' }}>
                <div style={{ fontWeight: 600, fontSize: 14 }}>
                  آدرس‌های کلینیک ({formatNumber(clinicAddresses.length)})
                </div>
                {(isOwner || primaryRole === 'admin') && clinicAddresses.length === 0 && (
                  <button className="btn primary sm" onClick={() => openAddrForm(null)}>
                    <PlusIcon style={{ width: 14, height: 14 }} />
                    افزودن آدرس
                  </button>
                )}
              </div>

              {clinicAddresses.length === 0 ? (
                <div className="empty" style={{ padding: '24px 16px' }}>
                  <MapPinIcon style={{ width: 28, height: 28 }} />
                  <p className="muted" style={{ marginTop: 8, fontSize: 13 }}>
                    هنوز آدرسی ثبت نشده — دکتران نمی‌توانند این کلینیک را به عنوان لوکیشن انتخاب کنند
                  </p>
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
                  {clinicAddresses.map((addr, idx) => (
                    <div key={addr.uuid} style={{
                      display: 'flex', alignItems: 'flex-start', gap: 10,
                      padding: '12px 16px',
                      borderTop: idx === 0 ? '1px solid var(--border)' : undefined,
                      borderBottom: '1px solid var(--border)',
                    }}>
                      <MapPinIcon style={{ width: 18, height: 18, color: 'var(--primary)', flexShrink: 0, marginTop: 2 }} />
                      <div style={{ flex: 1, minWidth: 0 }}>
                        {addr.name && <div style={{ fontWeight: 600, fontSize: 13 }}>{addr.name}</div>}
                        {addr.address && <div className="muted" style={{ fontSize: 12, marginTop: 2 }}>{addr.address}</div>}
                        {addr.telephone && (
                          <div style={{ fontSize: 12, marginTop: 2, color: 'var(--text-2)' }}>
                            <PhoneIcon style={{ width: 12, height: 12, display: 'inline', marginLeft: 4 }} />
                            {addr.telephone}
                          </div>
                        )}
                      </div>
                      {(isOwner || primaryRole === 'admin') && (
                        <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                          <button className="btn ghost sm" style={{ padding: '4px 8px' }} onClick={() => openAddrForm(addr)}>
                            <PencilIcon style={{ width: 14, height: 14 }} />
                          </button>
                          <button className="btn ghost sm" style={{ padding: '4px 8px', color: 'var(--error)' }}
                            onClick={() => setDeleteAddrConfirm(addr)}>
                            <TrashIcon style={{ width: 14, height: 14 }} />
                          </button>
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

        </div>
      </div>

      {/* Clinic Address Form Modal */}
      {addrFormOpen && createPortal(
        <div className="overlay" onClick={() => setAddrFormOpen(false)}>
          <div className="modal" style={{ maxWidth: 460 }} onClick={e => e.stopPropagation()}>
            <div className="modal-head">
              <b>{editingClinicAddr ? 'ویرایش آدرس' : 'افزودن آدرس جدید'}</b>
              <button className="mini-btn" onClick={() => setAddrFormOpen(false)}>
                <XMarkIcon style={{ width: 16, height: 16 }} />
              </button>
            </div>
            <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div>
                <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>نام شعبه / عنوان</label>
                <input className="input" placeholder="مثال: شعبه مرکزی"
                  value={addrForm.name}
                  onChange={e => setAddrForm(f => ({ ...f, name: e.target.value }))} />
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>استان</label>
                  <SearchableSelectField
                    options={provinces}
                    value={addrForm.province_id}
                    placeholder="انتخاب استان"
                    onChange={val => setAddrForm(f => ({ ...f, province_id: val, city_id: null }))}
                  />
                </div>
                <div>
                  <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>شهر</label>
                  <SearchableSelectField
                    options={addrCities}
                    value={addrForm.city_id}
                    placeholder={addrForm.province_id ? 'انتخاب شهر' : 'ابتدا استان'}
                    disabled={!addrForm.province_id}
                    onChange={(val, label) => {
                      setAddrForm(f => ({ ...f, city_id: val }));
                      if (label) geocodeCity(label).then(c => { if (c) setAddrMapFlyTarget(c); });
                    }}
                  />
                </div>
              </div>
              <div>
                <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>آدرس کامل</label>
                <textarea className="input" rows={2} style={{ resize: 'none' }} placeholder="خیابان، کوچه، پلاک..."
                  value={addrForm.address}
                  onChange={e => setAddrForm(f => ({ ...f, address: e.target.value }))} />
              </div>
              <div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
                  <label style={{ fontSize: 13, fontWeight: 600 }}>موقعیت روی نقشه</label>
                  {addrForm.latitude && addrForm.longitude && (
                    <span className="muted" style={{ fontSize: 11, direction: 'ltr' }}>
                      {addrForm.latitude.toFixed(4)}, {addrForm.longitude.toFixed(4)}
                    </span>
                  )}
                </div>
                <p className="muted" style={{ fontSize: 12, marginBottom: 6 }}>برای تعیین موقعیت دقیق روی نقشه کلیک کنید</p>
                <MapPicker
                  lat={addrForm.latitude} lng={addrForm.longitude}
                  flyTarget={addrMapFlyTarget}
                  initialCenter={addrForm.latitude && addrForm.longitude ? [addrForm.latitude, addrForm.longitude] : null}
                  onChange={(lt, ln) => setAddrForm(f => ({ ...f, latitude: lt, longitude: ln }))}
                />
                {addrForm.latitude && addrForm.longitude && (
                  <button type="button" className="btn ghost sm" style={{ marginTop: 6, fontSize: 12 }}
                    onClick={() => setAddrForm(f => ({ ...f, latitude: null, longitude: null }))}>
                    <XMarkIcon style={{ width: 13, height: 13 }} /> حذف موقعیت
                  </button>
                )}
              </div>
              <div>
                <label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>تلفن</label>
                <input className="input" dir="ltr" placeholder="مثال: 02112345678"
                  value={addrForm.telephone}
                  onChange={e => setAddrForm(f => ({ ...f, telephone: e.target.value }))} />
              </div>
            </div>
            <div className="modal-foot">
              <button className="btn ghost sm" onClick={() => setAddrFormOpen(false)}>انصراف</button>
              <button className="btn primary sm" disabled={saveAddrMutation.isPending}
                onClick={() => saveAddrMutation.mutate(addrForm)}>
                {saveAddrMutation.isPending ? 'در حال ذخیره...' : 'ذخیره'}
              </button>
            </div>
          </div>
        </div>,
        document.body,
      )}

      {/* Delete Address Confirm */}
      <ConfirmDialog
        open={deleteAddrConfirm !== null}
        title="حذف آدرس"
        message={`آیا از حذف آدرس "${deleteAddrConfirm?.name ?? deleteAddrConfirm?.address ?? ''}" اطمینان دارید؟`}
        confirmLabel="حذف"
        onConfirm={() => deleteAddrConfirm && deleteAddrMutation.mutate(deleteAddrConfirm.uuid)}
        onCancel={() => setDeleteAddrConfirm(null)}
      />

      {/* Delete Gallery Image Confirm */}
      <ConfirmDialog
        open={deleteImageConfirm !== null}
        title="حذف تصویر"
        message="آیا از حذف این تصویر از گالری اطمینان دارید؟"
        confirmLabel="حذف"
        danger
        onConfirm={() => {
          if (deleteImageConfirm) handleGalleryRemove(deleteImageConfirm);
          setDeleteImageConfirm(null);
        }}
        onCancel={() => setDeleteImageConfirm(null)}
      />

      {/* Detach Doctor From Clinic Confirm */}
      <ConfirmDialog
        open={detachDoctorConfirm !== null}
        title="جداسازی پزشک از کلینیک"
        message={`آیا پزشک "${detachDoctorConfirm?.name ?? ''}" از این کلینیک جدا شود؟ این کار فقط ارتباط پزشک با این کلینیک را حذف می‌کند.`}
        confirmLabel="جداسازی"
        danger
        loading={detachDoctorMut.isPending}
        onConfirm={() => {
          if (detachDoctorConfirm) detachDoctorMut.mutate(detachDoctorConfirm.uuid);
          setDetachDoctorConfirm(null);
        }}
        onCancel={() => setDetachDoctorConfirm(null)}
      />

      {/* Edit modal — self-portals to escape transform context */}
      {editOpen && (
        <EditModal
          clinic={clinic}
          onClose={() => setEditOpen(false)}
          onSaved={() => { qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] }); qc.invalidateQueries({ queryKey: ['admin-clinics'] }); }}
        />
      )}

      {/* Invite doctor modal */}
      {inviteOpen && uuid && (
        <InviteDoctorModal
          clinicUuid={uuid}
          onClose={() => setInviteOpen(false)}
          onInvited={() => { qc.invalidateQueries({ queryKey: ['clinic-invitations', uuid] }); setDoctorsTab('invitations'); }}
        />
      )}

      {/* Delete confirm */}
      <ConfirmDialog
        open={deleteOpen}
        title="حذف کلینیک"
        message={`آیا از حذف کلینیک "${clinic.name}" اطمینان دارید؟ این عمل قابل بازگشت نیست.`}
        confirmLabel="حذف"
        danger
        loading={deleteMut.isPending}
        onConfirm={() => deleteMut.mutate()}
        onCancel={() => setDeleteOpen(false)}
      />
    </div>
  );
}

// ── Info tile ──────────────────────────────────────────────────────────────

function InfoTile({ icon, label, value, fullWidth }: {
  icon?: React.ReactNode; label: string; value: React.ReactNode; fullWidth?: boolean;
}) {
  return (
    <div style={{
      gridColumn: fullWidth ? '1 / -1' : undefined,
      padding: '10px 12px', borderRadius: 8,
      background: 'var(--surface-2, var(--bg))',
      border: '1px solid var(--border)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 3, color: 'var(--text-3)' }}>
        {icon}
        <span style={{ fontSize: 11 }}>{label}</span>
      </div>
      <div style={{ fontSize: 13, fontWeight: 600 }}>{value}</div>
    </div>
  );
}
