import React, { useState, useEffect, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import {
  MagnifyingGlassIcon, PlusIcon,
  EyeIcon, TrashIcon, ArrowPathIcon,
  CheckCircleIcon, XCircleIcon, ShieldCheckIcon,
} from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../lib/api';
import { useUrlState, pageOf } from '../hooks/useUrlState';
import Portal from '../components/ui/Portal';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import { formatDate, formatNumber, maskMobile } from '../lib/utils';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import Pagination from '../components/ui/Pagination';
import SearchableSelect from '../components/ui/SearchableSelect';
import { XMarkIcon } from '@heroicons/react/24/outline';

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

interface AdminUser {
  uuid: string;
  id: number;
  mobile_number: string;
  name: string | null;
  email: string | null;
  roles: string[];
  is_active: boolean;
  status: number;
  created_at: string;
}

interface UserStats {
  total: number;
  active: number;
  inactive: number;
  admins: number;
  doctors: number;
  patients: number;
}

// ── Helpers ───────────────────────────────────────────────────────────────

const HUES_LIST = [256, 205, 162, 295, 272];

const ROLE_META: Record<string, { label: string; badgeCls: string }> = {
  admin:          { label: 'ادمین',   badgeCls: 'violet' },
  doctor:         { label: 'پزشک',    badgeCls: 'blue'   },
  secretary:      { label: 'منشی',    badgeCls: 'amber'  },
  clinic:         { label: 'کلینیک',  badgeCls: 'green'  },
  representation: { label: 'نماینده', badgeCls: 'red'    },
  patient:        { label: 'بیمار',   badgeCls: 'gray'   },
};

// نقش‌هایی که از این صفحه قابل تغییرِ مستقیم‌اند (backend `roleMap`). «نماینده» از این‌جا ست نمی‌شود
// چون ساخت نماینده رکورد Representation هم می‌خواهد؛ فقط برای نمایش badge/فیلتر تعریف شده است.
const ASSIGNABLE_ROLES = ['admin', 'doctor', 'secretary', 'clinic', 'patient'];

function getPrimaryRole(roles: string[]): string {
  if (roles.includes('ROLE_ADMIN'))          return 'admin';
  if (roles.includes('ROLE_DOCTOR'))         return 'doctor';
  if (roles.includes('ROLE_SECRETARY'))      return 'secretary';
  if (roles.includes('ROLE_CLINIC'))         return 'clinic';
  if (roles.includes('ROLE_REPRESENTATION')) return 'representation';
  return 'patient';
}

function UserAvatar({ name, id, size = 'sm' }: { name: string | null; id: number; size?: 'sm' | 'lg' }) {
  const initials = name
    ? name.split(' ').filter(Boolean).map((w) => w[0]).join('').toUpperCase().slice(0, 2)
    : '؟';
  const hue = HUES_LIST[id % HUES_LIST.length];
  return (
    <div
      className={`avatar ${size}`}
      style={{ background: `linear-gradient(145deg, oklch(0.62 0.15 ${hue}), oklch(0.48 0.16 ${hue}))` }}
    >
      {initials}
    </div>
  );
}

function RoleBadge({ roles }: { roles: string[] }) {
  const key  = getPrimaryRole(roles);
  const meta = ROLE_META[key];
  return (
    <span className={`badge ${meta.badgeCls}`}>
      <span className="bdot" />
      {meta.label}
    </span>
  );
}

function ActiveBadge({ active }: { active: boolean }) {
  return (
    <span className={`badge ${active ? 'green' : 'gray'}`}>
      <span className="bdot" />
      {active ? 'فعال' : 'غیرفعال'}
    </span>
  );
}

// ── Role Change Modal ─────────────────────────────────────────────────────

function ChangeRoleModal({ user, onClose, onSave, loading }: {
  user: AdminUser; onClose: () => void;
  onSave: (role: string) => void; loading: boolean;
}) {
  const [selected, setSelected] = useState(getPrimaryRole(user.roles));
  return (
    <Portal>
    <div className="overlay" onClick={onClose}>
      <div className="modal" style={{ maxWidth: 400 }} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h2 style={{ fontSize: 16 }}>تغییر نقش</h2>
          <button className="mini-btn" onClick={onClose}>
            <XMarkIcon style={{ width: 18, height: 18 }} />
          </button>
        </div>
        <div className="modal-body">
          <p className="muted" style={{ fontSize: 13, marginBottom: 16 }}>{user.name || user.mobile_number}</p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {Object.entries(ROLE_META).filter(([key]) => ASSIGNABLE_ROLES.includes(key)).map(([key, meta]) => (
              <label
                key={key}
                style={{
                  display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px',
                  borderRadius: 'var(--r)', cursor: 'pointer',
                  border: `2px solid ${selected === key ? 'var(--primary)' : 'var(--border)'}`,
                  background: selected === key ? 'var(--primary-soft)' : 'var(--surface-2)',
                  transition: '.15s',
                }}
              >
                <input type="radio" name="role" value={key} checked={selected === key}
                  onChange={() => setSelected(key)} style={{ accentColor: 'var(--primary)', width: 16, height: 16 }} />
                <span className={`badge ${meta.badgeCls}`} style={{ pointerEvents: 'none' }}>
                  <span className="bdot" />{meta.label}
                </span>
              </label>
            ))}
          </div>
        </div>
        <div className="modal-foot" style={{ justifyContent: 'flex-end' }}>
          <button className="btn ghost sm" onClick={onClose} disabled={loading}>انصراف</button>
          <button className="btn primary sm" onClick={() => onSave(selected)} disabled={loading}>
            {loading ? 'در حال ذخیره...' : 'ذخیره'}
          </button>
        </div>
      </div>
    </div>
    </Portal>
  );
}

// ── Constants ─────────────────────────────────────────────────────────────

const ROLE_TABS = [
  { key: '',          label: 'همه نقش‌ها' },
  { key: 'admin',     label: 'ادمین'      },
  { key: 'doctor',    label: 'پزشک'       },
  { key: 'secretary', label: 'منشی'       },
  { key: 'clinic',    label: 'کلینیک'     },
  { key: 'representation', label: 'نماینده' },
  { key: 'patient',   label: 'بیمار'      },
];

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

export default function UsersPage() {
  const navigate = useNavigate();
  const qc = useQueryClient();

  // وضعیت لیست در URL می‌ماند تا «بازگشت» از پروفایل کاربر، همین فیلترها و صفحه را برگرداند.
  const [urlState, setUrlState] = useUrlState({ page: '1', search: '', role: '', status: '' });
  const page   = pageOf(urlState.page);
  const search = urlState.search;
  const role   = urlState.role;
  const status = urlState.status;
  const setPage   = (p: number) => setUrlState({ page: String(p) });
  const setRole   = (v: string) => setUrlState({ role: v, page: '1' });
  const setStatus = (v: string) => setUrlState({ status: v, page: '1' });

  const [limit]                       = useState(25);
  // فیلد جستجو local می‌ماند (تایپ روان)؛ مقدارِ debounce‌شده به URL می‌رود.
  const [searchInput, setSearchInput] = useState(urlState.search);
  const [deleteTarget, setDeleteTarget] = useState<AdminUser | null>(null);
  const [roleTarget, setRoleTarget]     = useState<AdminUser | null>(null);

  useEffect(() => {
    const t = setTimeout(() => setUrlState({ search: searchInput, page: '1' }), 350);
    return () => clearTimeout(t);
  }, [searchInput]);

  // ── Queries ──

  const statsQ = useQuery({
    queryKey: ['users-stats'],
    queryFn: () => api.get<ApiResponse<UserStats>>('/api/v1/admin/users/stats'),
    staleTime: 30_000,
  });

  const usersQ = useQuery({
    queryKey: ['users', page, limit, search, role, status],
    queryFn: () => {
      const p = new URLSearchParams({ page: String(page), limit: String(limit) });
      if (search) p.set('search', search);
      if (role)   p.set('role', role);
      if (status) p.set('status', status);
      return api.get<PaginatedResponse<AdminUser>>(`/api/v1/admin/users?${p}`);
    },
  });

  const stats = useMemo<UserStats | undefined>(
    () => (statsQ.data?.data as any)?.data ?? statsQ.data?.data, [statsQ.data]
  );
  const items = usersQ.data?.data ?? [];
  const total = usersQ.data?.meta?.totalRecords ?? 0;

  // ── Mutations ──

  const deleteMut = useMutation({
    mutationFn: (uuid: string) => api.delete<ApiResponse<null>>(`/api/v1/admin/users/${uuid}`),
    onSuccess: () => {
      toast.success('کاربر حذف شد');
      setDeleteTarget(null);
      qc.invalidateQueries({ queryKey: ['users'] });
      qc.invalidateQueries({ queryKey: ['users-stats'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const toggleStatusMut = useMutation({
    mutationFn: (uuid: string) => api.post<ApiResponse<{ is_active: boolean }>>(`/api/v1/admin/users/${uuid}/status`, {}),
    onSuccess: () => {
      toast.success('وضعیت کاربر تغییر کرد');
      qc.invalidateQueries({ queryKey: ['users'] });
      qc.invalidateQueries({ queryKey: ['users-stats'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateRoleMut = useMutation({
    mutationFn: ({ uuid, role: r }: { uuid: string; role: string }) =>
      api.put<ApiResponse<null>>(`/api/v1/admin/users/${uuid}/role`, { role: r }),
    onSuccess: () => {
      toast.success('نقش کاربر بروزرسانی شد');
      setRoleTarget(null);
      qc.invalidateQueries({ queryKey: ['users'] });
      qc.invalidateQueries({ queryKey: ['users-stats'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  // ── KPI data ──

  const kpiCards = [
    { label: 'کل کاربران', value: stats?.total,    bg: 'var(--surface-3)',  color: 'var(--text-2)'  },
    { label: 'فعال',        value: stats?.active,   bg: 'var(--success-bg)', color: 'var(--success)' },
    { label: 'غیرفعال',     value: stats?.inactive, bg: 'var(--surface-3)',  color: 'var(--text-3)'  },
    { label: 'ادمین‌ها',    value: stats?.admins,   bg: 'var(--violet-bg)',  color: 'var(--violet)'  },
    { label: 'پزشکان',      value: stats?.doctors,  bg: 'var(--info-bg)',    color: 'var(--info)'    },
    { label: 'بیماران',     value: stats?.patients, bg: 'var(--warning-bg)', color: 'var(--warning)' },
  ];

  return (
    <div className="fade-in">
      {/* Header */}
      <div className="card-title-row" style={{ marginBottom: 'var(--gap)' }}>
        <div>
          <h1 className="section-title">کاربران</h1>
          <div className="muted" style={{ fontSize: 13, marginTop: 3 }}>مدیریت کاربران، نقش‌ها و سطح دسترسی</div>
        </div>
        <button className="btn primary sm">
          <PlusIcon style={{ width: 15, height: 15 }} />
          افزودن کاربر
        </button>
      </div>

      {/* KPI cards */}
      <div className="stat-grid">
        {kpiCards.map((c) => (
          <div key={c.label} className="stat">
            <div className="ico" style={{ background: c.bg, color: c.color }}>
              <svg style={{ width: 20, height: 20 }} fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
              </svg>
            </div>
            <div className="lbl">{c.label}</div>
            <div className="val">
              {c.value === undefined
                ? <span className="skeleton" style={{ display: 'inline-block', width: 48, height: 26, borderRadius: 4 }} />
                : formatNumber(c.value)}
            </div>
          </div>
        ))}
      </div>

      {/* Main card */}
      <div className="card">
        {/* Toolbar */}
        <div className="card-pad" style={{ paddingBottom: 0 }}>
          <div className="toolbar">
            <div className="field" style={{ minWidth: 240 }}>
              <MagnifyingGlassIcon style={{ width: 17, height: 17 }} />
              <input
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                placeholder="شماره کاربری، نام، موبایل یا ایمیل..."
              />
            </div>
            <div style={{ minWidth: 160 }}>
              <SearchableSelect
                options={ROLE_TABS.map(t => ({ value: t.key, label: t.label }))}
                value={role || ''}
                onChange={(v) => setRole(v ? String(v) : '')}
                height={36}
              />
            </div>
            <div className="seg">
              <button className={!status ? 'on' : ''} onClick={() => setStatus('')}>همه</button>
              <button className={status === '1' ? 'on' : ''} onClick={() => setStatus('1')}>فعال</button>
              <button className={status === '0' ? 'on' : ''} onClick={() => setStatus('0')}>غیرفعال</button>
            </div>
            <div className="spacer" />
            <button className="btn ghost sm" onClick={() => usersQ.refetch()} disabled={usersQ.isFetching} title="به‌روزرسانی">
              <ArrowPathIcon style={{ width: 15, height: 15, animation: usersQ.isFetching ? 'spin 1s linear infinite' : undefined }} />
            </button>
          </div>
        </div>

        {/* Table */}
        <div className="table-wrap">
          <table className="t">
            <thead>
              <tr>
                <th>کاربر</th>
                <th>شماره موبایل</th>
                <th>نقش</th>
                <th>تاریخ عضویت</th>
                <th>وضعیت</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {usersQ.isLoading && Array.from({ length: 7 }).map((_, i) => (
                <tr key={i}>
                  {Array.from({ length: 6 }).map((_, j) => (
                    <td key={j}>
                      <div className="skeleton" style={{ height: 14, borderRadius: 6, width: j === 1 ? '70%' : '55%' }} />
                    </td>
                  ))}
                </tr>
              ))}

              {!usersQ.isLoading && items.length === 0 && (
                <tr>
                  <td colSpan={6}>
                    <div className="empty">هیچ کاربری یافت نشد</div>
                  </td>
                </tr>
              )}

              {!usersQ.isLoading && items.map((user) => (
                <tr key={user.uuid}>
                  <td>
                    <div className="cell-user">
                      <UserAvatar name={user.name} id={user.id} />
                      <div>
                        <b style={{ cursor: 'pointer' }} onClick={() => navigate(`/admin/users/${user.uuid}`)}>
                          {user.name || '—'}
                        </b>
                        <br /><small>#{user.id}</small>
                      </div>
                    </div>
                  </td>
                  <td style={{ fontFamily: 'monospace', direction: 'ltr', textAlign: 'right' }}>
                    {user.mobile_number}
                  </td>
                  <td><RoleBadge roles={user.roles} /></td>
                  <td className="muted">{formatDate(user.created_at)}</td>
                  <td><ActiveBadge active={user.is_active} /></td>
                  <td>
                    <div className="row-actions">
                      <button className="mini-btn" title="مشاهده"
                        onClick={() => navigate(`/admin/users/${user.uuid}`)}>
                        <EyeIcon style={{ width: 16, height: 16 }} />
                      </button>
                      <button className="mini-btn" title="تغییر نقش"
                        onClick={() => setRoleTarget(user)}>
                        <ShieldCheckIcon style={{ width: 16, height: 16 }} />
                      </button>
                      <button className="mini-btn" title={user.is_active ? 'غیرفعال کردن' : 'فعال‌سازی'}
                        onClick={() => toggleStatusMut.mutate(user.uuid)} disabled={toggleStatusMut.isPending}>
                        {user.is_active
                          ? <XCircleIcon style={{ width: 16, height: 16 }} />
                          : <CheckCircleIcon style={{ width: 16, height: 16 }} />}
                      </button>
                      <button className="mini-btn danger" title="حذف" onClick={() => setDeleteTarget(user)}>
                        <TrashIcon style={{ width: 16, height: 16 }} />
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <Pagination page={page} total={total} limit={limit} onPageChange={setPage} />
      </div>

      {/* Dialogs */}
      <ConfirmDialog
        open={!!deleteTarget}
        title="حذف کاربر"
        message={`آیا از حذف کاربر "${deleteTarget?.name ?? deleteTarget?.mobile_number}" اطمینان دارید؟ این عمل قابل بازگشت نیست.`}
        confirmLabel="حذف"
        danger
        loading={deleteMut.isPending}
        onConfirm={() => deleteTarget && deleteMut.mutate(deleteTarget.uuid)}
        onCancel={() => setDeleteTarget(null)}
      />

      {roleTarget && (
        <ChangeRoleModal
          user={roleTarget}
          loading={updateRoleMut.isPending}
          onClose={() => setRoleTarget(null)}
          onSave={(r) => updateRoleMut.mutate({ uuid: roleTarget.uuid, role: r })}
        />
      )}
    </div>
  );
}
