import React, { useEffect, useMemo, useState } from 'react';
import { PlusIcon } from '@heroicons/react/24/outline';
import PageHeader from '../components/ui/PageHeader';
import DataTable, { type Column } from '../components/ui/DataTable';
import Modal from '../components/ui/Modal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import SearchableSelect from '../components/ui/SearchableSelect';
import { ActiveBadge } from '../components/ui/StatusBadge';
import { useUrlState } from '../hooks/useUrlState';
import { usePermissions } from '../hooks/usePermissions';
import { useBranches } from '../hooks/useBranches';
import { useResourcePools, useResources, useResourceTypes } from '../hooks/useResources';
import type { ResourcePool } from '../types';

/**
 * استخر منابع — گروهی از منابع که جایگزین کامل یکدیگرند.
 *
 * اعضا باید هم‌شعبه و هم‌نوعِ خودِ استخر باشند؛ سرور این را اجبار می‌کند و فرم هم
 * فهرست انتخاب را به همان‌ها محدود می‌کند تا کاربر به خطای ۴۲۲ نخورد.
 */
export default function ResourcePoolsPage() {
  const { pools, loading, create, update, remove, setMembers } = useResourcePools();
  const { branches } = useBranches();
  const { types } = useResourceTypes();
  const { can } = usePermissions();
  const canUpdate = can('appointment_settings', 'update');

  const [urlState, setUrlState] = useUrlState({ search: '' });
  const [creating, setCreating] = useState(false);
  const [membersFor, setMembersFor] = useState<ResourcePool | null>(null);
  const [toDelete, setToDelete] = useState<ResourcePool | null>(null);

  const rows = useMemo(() => {
    const q = urlState.search.trim();
    return q === '' ? pools : pools.filter((p) => `${p.name} ${p.type_name}`.includes(q));
  }, [pools, urlState.search]);

  const columns: Column<ResourcePool>[] = [
    {
      key: 'name',
      header: 'استخر',
      render: (p) => (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
          <span style={{ fontWeight: 600 }}>{p.name}</span>
          <span style={{ fontSize: 12, color: 'var(--text-3)' }}>{p.type_name}</span>
        </div>
      ),
    },
    { key: 'address_name', header: 'شعبه', render: (p) => <span style={{ fontSize: 13 }}>{p.address_name || '—'}</span> },
    {
      key: 'members',
      header: 'اعضا',
      render: (p) =>
        p.members.length === 0 ? (
          <span style={{ fontSize: 12, color: 'var(--text-3)' }}>بدون عضو</span>
        ) : (
          <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
            {p.members.map((m) => (
              <span key={m.resource_uuid} className="badge blue" style={{ fontSize: 11 }}>{m.resource_name}</span>
            ))}
          </div>
        ),
    },
    { key: 'active', header: 'وضعیت', render: (p) => <ActiveBadge active={p.active} /> },
  ];

  return (
    <div className="fade-in">
      <PageHeader
        title="استخر منابع"
        description="منابعی که جایگزین کامل یکدیگرند — مثل «لیزرهای آلکساندرایت». همهٔ اعضا باید در یک شعبه و از یک نوع باشند."
        backTo="/admin/resources"
        breadcrumbs={[{ label: 'منابع', to: '/admin/resources' }, { label: 'استخر منابع' }]}
        action={
          canUpdate ? (
            <button type="button" className="btn primary" onClick={() => setCreating(true)}>
              <PlusIcon style={{ width: 16 }} /> افزودن استخر
            </button>
          ) : undefined
        }
      />

      <DataTable
        columns={columns}
        data={rows}
        loading={loading}
        searchValue={urlState.search}
        onSearchChange={(v) => setUrlState({ search: v })}
        searchPlaceholder="جستجو در استخرها..."
        emptyMessage="هنوز استخری تعریف نشده است"
        actions={
          canUpdate
            ? (p) => (
                <div style={{ display: 'flex', gap: 6 }}>
                  <button type="button" className="btn secondary sm" onClick={() => setMembersFor(p)}>
                    اعضا
                  </button>
                  <button
                    type="button"
                    className="btn secondary sm"
                    onClick={() => update.mutate({ uuid: p.uuid, d: { active: !p.active } })}
                  >
                    {p.active ? 'غیرفعال کردن' : 'فعال کردن'}
                  </button>
                  <button type="button" className="btn secondary sm" onClick={() => setToDelete(p)}>
                    حذف
                  </button>
                </div>
              )
            : undefined
        }
      />

      <CreatePoolModal
        open={creating}
        branches={branches}
        types={types}
        saving={create.isPending}
        onClose={() => setCreating(false)}
        onSave={(payload) => create.mutate(payload, { onSuccess: () => setCreating(false) })}
      />

      <PoolMembersModal
        pool={membersFor}
        saving={setMembers.isPending}
        onClose={() => setMembersFor(null)}
        onSave={(members) =>
          membersFor &&
          setMembers.mutate({ uuid: membersFor.uuid, members }, { onSuccess: () => setMembersFor(null) })
        }
      />

      <ConfirmDialog
        open={!!toDelete}
        title="حذف استخر"
        message={`آیا از حذف «${toDelete?.name}» مطمئن هستید؟ منابع عضو حذف نمی‌شوند.`}
        confirmLabel="حذف"
        loading={remove.isPending}
        onConfirm={() => toDelete && remove.mutate(toDelete.uuid, { onSuccess: () => setToDelete(null) })}
        onCancel={() => setToDelete(null)}
      />
    </div>
  );
}

function CreatePoolModal({
  open, branches, types, saving, onClose, onSave,
}: {
  open: boolean;
  branches: ReturnType<typeof useBranches>['branches'];
  types: ReturnType<typeof useResourceTypes>['types'];
  saving: boolean;
  onClose: () => void;
  onSave: (payload: { address_uuid: string; type_uuid: string; name: string }) => void;
}) {
  const [name, setName] = useState('');
  const [addressUuid, setAddressUuid] = useState<string | null>(null);
  const [typeUuid, setTypeUuid] = useState<string | null>(null);

  useEffect(() => {
    if (!open) return;
    setName('');
    setAddressUuid(null);
    setTypeUuid(null);
  }, [open]);

  const invalid = name.trim() === '' || !addressUuid || !typeUuid;

  return (
    <Modal open={open} onClose={onClose} title="افزودن استخر منابع">
      <div style={{ display: 'grid', gap: 14 }}>
        <div style={{ display: 'grid', gap: 6 }}>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>نام استخر</label>
          <input className="field" value={name} onChange={(e) => setName(e.target.value)} placeholder="لیزرهای آلکساندرایت" />
        </div>

        <div style={{ display: 'grid', gap: 6 }}>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>شعبه</label>
          <SearchableSelect
            options={branches.map((b) => ({ value: b.uuid, label: b.name || 'بدون نام' }))}
            value={addressUuid}
            onChange={(v) => setAddressUuid(v ? String(v) : null)}
            placeholder="شعبه را انتخاب کنید"
            height={38}
          />
        </div>

        <div style={{ display: 'grid', gap: 6 }}>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>نوع منبع</label>
          <SearchableSelect
            options={types.map((t) => ({ value: t.uuid, label: t.name }))}
            value={typeUuid}
            onChange={(v) => setTypeUuid(v ? String(v) : null)}
            placeholder="نوع را انتخاب کنید"
            height={38}
          />
        </div>

        <p style={{ fontSize: 12, color: 'var(--text-3)', margin: 0 }}>
          شعبه و نوع پس از ساخت تغییر نمی‌کنند — اعضا باید با هر دو بخوانند.
        </p>

        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button type="button" className="btn secondary" onClick={onClose}>انصراف</button>
          <button
            type="button"
            className="btn primary"
            disabled={saving || invalid}
            onClick={() => onSave({ address_uuid: addressUuid!, type_uuid: typeUuid!, name: name.trim() })}
          >
            {saving ? 'در حال ذخیره...' : 'ذخیره'}
          </button>
        </div>
      </div>
    </Modal>
  );
}

function PoolMembersModal({
  pool, saving, onClose, onSave,
}: {
  pool: ResourcePool | null;
  saving: boolean;
  onClose: () => void;
  onSave: (members: { resource_uuid: string; priority: number }[]) => void;
}) {
  const [chosen, setChosen] = useState<string[]>([]);

  // فهرست انتخاب به همان شعبه و نوعِ استخر محدود است — همان قاعده‌ای که سرور با ۴۲۲
  // اجبار می‌کند، پس کاربر اصلاً به آن خطا نمی‌خورد.
  const { resources } = useResources(
    pool ? { address_uuid: pool.address_uuid, type_uuid: pool.type_uuid } : {},
  );

  useEffect(() => {
    if (!pool) return;
    setChosen(pool.members.map((m) => m.resource_uuid));
  }, [pool]);

  const nameOf = (uuid: string) => resources.find((r) => r.uuid === uuid)?.name
    ?? pool?.members.find((m) => m.resource_uuid === uuid)?.resource_name
    ?? uuid;

  const available = resources.filter((r) => !chosen.includes(r.uuid));

  return (
    <Modal open={pool !== null} onClose={onClose} title={`اعضای ${pool?.name ?? 'استخر'}`}>
      <div style={{ display: 'grid', gap: 14 }}>
        {chosen.length === 0 ? (
          <p style={{ fontSize: 13, color: 'var(--text-3)', margin: 0 }}>
            این استخر عضوی ندارد. استخر بدون عضو معتبر است، ولی در انتخاب منبع «هیچ منبعی» دیده می‌شود.
          </p>
        ) : (
          <div style={{ display: 'grid', gap: 8 }}>
            {chosen.map((uuid, index) => (
              <div key={uuid} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <span style={{ fontSize: 12, color: 'var(--text-3)', width: 24 }}>{index + 1}</span>
                <span style={{ flex: 1, fontSize: 13, fontWeight: 600 }}>{nameOf(uuid)}</span>
                <button
                  type="button"
                  className="btn secondary sm"
                  disabled={index === 0}
                  onClick={() => setChosen((c) => {
                    const next = [...c];
                    [next[index - 1], next[index]] = [next[index], next[index - 1]];
                    return next;
                  })}
                  aria-label={`بالا بردن ${nameOf(uuid)}`}
                >
                  ↑
                </button>
                <button
                  type="button"
                  className="btn secondary sm"
                  onClick={() => setChosen((c) => c.filter((x) => x !== uuid))}
                  aria-label={`حذف ${nameOf(uuid)}`}
                >
                  ✕
                </button>
              </div>
            ))}
          </div>
        )}

        {available.length > 0 && (
          <div style={{ display: 'grid', gap: 6 }}>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>افزودن عضو</label>
            <SearchableSelect
              options={available.map((r) => ({ value: r.uuid, label: r.name }))}
              value={null}
              onChange={(v) => v && setChosen((c) => [...c, String(v)])}
              placeholder="یک منبع انتخاب کنید"
              height={38}
            />
          </div>
        )}

        <p style={{ fontSize: 12, color: 'var(--text-3)', margin: 0 }}>
          ترتیب همان اولویت انتخاب است. ذخیره کل فهرست را جایگزین می‌کند.
        </p>

        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button type="button" className="btn secondary" onClick={onClose}>انصراف</button>
          <button
            type="button"
            className="btn primary"
            disabled={saving}
            onClick={() => onSave(chosen.map((uuid, index) => ({ resource_uuid: uuid, priority: index })))}
          >
            {saving ? 'در حال ذخیره...' : 'ذخیره'}
          </button>
        </div>
      </div>
    </Modal>
  );
}
