import { useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import * as permApi from '../../api/permission';
import type { PermissionNode, Role } from '../../api/permission';
import { ApiError } from '../../api/http';

/** 可勾選的權限節點（有實際 API path 的葉節點） */
function leafPermissions(nodes: PermissionNode[]): PermissionNode[] {
  return nodes.filter((n) => n.http_path);
}

function groupByParent(leaves: PermissionNode[]) {
  const groups = new Map<string, PermissionNode[]>();
  for (const p of leaves) {
    const key = p.parent || '(root)';
    const arr = groups.get(key) ?? [];
    arr.push(p);
    groups.set(key, arr);
  }
  return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b));
}

export function RolePermissionsPage() {
  const [searchParams] = useSearchParams();
  const presetRole = searchParams.get('role') ?? '';
  const [roles, setRoles] = useState<Role[]>([]);
  const [roleId, setRoleId] = useState(presetRole);
  const [catalog, setCatalog] = useState<PermissionNode[]>([]);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [error, setError] = useState('');
  const [msg, setMsg] = useState('');
  const [loading, setLoading] = useState(false);

  const leaves = useMemo(() => leafPermissions(catalog), [catalog]);
  const groups = useMemo(() => groupByParent(leaves), [leaves]);
  const selectedRole = roles.find((r) => r.id === roleId);

  useEffect(() => {
    if (presetRole) setRoleId(presetRole);
  }, [presetRole]);

  useEffect(() => {
    permApi
      .listRoles()
      .then((r) => setRoles(r.roles ?? []))
      .catch((e) => setError(e instanceof ApiError ? e.message : '載入角色失敗'));
    permApi
      .getPermissionCatalog({ type: 'backend_user' })
      .then((c) => setCatalog(c.list ?? []))
      .catch((e) => setError(e instanceof ApiError ? e.message : '載入權限目錄失敗'));
  }, []);

  useEffect(() => {
    if (!roleId) {
      setSelected(new Set());
      return;
    }
    setError('');
    permApi
      .getRolePermissions(roleId)
      .then((r) => {
        const ids = new Set((r.permissions ?? []).map((p) => p.id));
        setSelected(ids);
      })
      .catch((e) => {
        setError(e instanceof ApiError ? e.message : '載入角色權限失敗');
        setSelected(new Set());
      });
  }, [roleId]);

  const toggle = (id: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const save = async () => {
    if (!roleId) return;
    setLoading(true);
    setError('');
    setMsg('');
    try {
      // 只送葉節點 ID；後端會自動補齊父權限
      const leafIds = leaves.filter((l) => selected.has(l.id)).map((l) => l.id);
      await permApi.replaceRolePermissions(roleId, leafIds);
      const tenant = localStorage.getItem('tenant_slug') ?? 'k6-tenant';
      await permApi.reloadPolicy(tenant);
      setMsg('已儲存並重載 Casbin policy');
      const r = await permApi.getRolePermissions(roleId);
      setSelected(new Set((r.permissions ?? []).map((p) => p.id)));
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '儲存失敗');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h1>角色權限設定</h1>
      <p className="hint">
        為自訂角色勾選 API 權限。儲存後會自動重載 policy。系統內建角色（tenant_admin
        等）權限由種子資料定義，建議只調整非系統角色。
      </p>

      {error && <p className="form-error">{error}</p>}
      {msg && <p className="form-ok">{msg}</p>}

      <div className="form-inline-block admin-toolbar">
        <label>
          選擇角色
          <select value={roleId} onChange={(e) => setRoleId(e.target.value)}>
            <option value="">— 請選擇 —</option>
            {roles.map((r) => (
              <option key={r.id} value={r.id} disabled={r.is_system}>
                {r.display_name} ({r.key}){r.is_system ? ' · 系統' : ''}
              </option>
            ))}
          </select>
        </label>
        {roleId && (
          <button
            type="button"
            className="btn-primary"
            onClick={save}
            disabled={loading || selectedRole?.is_system}
          >
            {loading ? '儲存中…' : '儲存權限'}
          </button>
        )}
      </div>

      {selectedRole?.is_system && (
        <p className="hint">系統角色不建議在此修改；請建立自訂角色（如 support）再指派權限。</p>
      )}

      {roleId && !selectedRole?.is_system && (
        <div className="perm-grid">
          {groups.map(([parent, items]) => (
            <section key={parent} className="perm-group">
              <h3>
                <code>{parent}</code>
              </h3>
              <ul className="perm-check-list">
                {items.map((p) => (
                  <li key={p.id}>
                    <label>
                      <input
                        type="checkbox"
                        checked={selected.has(p.id)}
                        onChange={() => toggle(p.id)}
                      />
                      <span className="perm-label">
                        <strong>{p.name}</strong>
                        {p.http_methods && p.http_path && (
                          <span className="perm-api">
                            {p.http_methods} {p.http_path}
                          </span>
                        )}
                      </span>
                    </label>
                  </li>
                ))}
              </ul>
            </section>
          ))}
        </div>
      )}
    </div>
  );
}
