import { useCallback, useEffect, useState } from 'react';
import {
  clearUserPolicyOverrides,
  getRolePolicies,
  getUserPolicies,
  listPolicyCatalog,
  updateRolePolicies,
  updateUserPolicies,
} from '../api/client';
import type { AdminUserRow, PolicyDefinition, PolicyMap } from '../types';

const RISK_LABEL: Record<string, string> = {
  low: '低',
  medium: '中',
  high: '高',
};

function PolicyGrid({
  catalog,
  values,
  disabled,
  onChange,
}: {
  catalog: PolicyDefinition[];
  values: PolicyMap;
  disabled?: boolean;
  onChange: (key: string, value: PolicyMap[string]) => void;
}) {
  const grouped = catalog.reduce<Record<string, PolicyDefinition[]>>((acc, item) => {
    acc[item.category] ??= [];
    acc[item.category].push(item);
    return acc;
  }, {});

  return (
    <div className="capability-grid">
      {Object.entries(grouped).map(([category, items]) => (
        <div key={category} className="capability-group">
          <h3>{category}</h3>
          <ul>
            {items.map((item) => (
              <li key={item.key}>
                <label>
                  {item.type === 'boolean' ? (
                    <input
                      type="checkbox"
                      checked={Boolean(values[item.key])}
                      disabled={disabled}
                      onChange={(e) => onChange(item.key, e.target.checked)}
                    />
                  ) : (
                    <select
                      value={String(values[item.key] ?? item.defaultValue)}
                      disabled={disabled}
                      onChange={(e) => onChange(item.key, e.target.value)}
                    >
                      {(item.options ?? []).map((opt) => (
                        <option key={opt.value} value={opt.value}>
                          {opt.label}
                        </option>
                      ))}
                    </select>
                  )}
                  <span className="capability-label">
                    {item.label}
                    <span className={`risk-pill risk-${item.risk}`}>
                      风险 {RISK_LABEL[item.risk] ?? item.risk}
                    </span>
                  </span>
                  <span className="muted capability-desc">{item.description}</span>
                </label>
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

export function PolicySettings({
  users,
  userId,
  userOnly = false,
}: {
  users: AdminUserRow[];
  userId?: string;
  userOnly?: boolean;
}) {
  const [catalog, setCatalog] = useState<PolicyDefinition[]>([]);
  const [rolePolicies, setRolePolicies] = useState<PolicyMap>({});
  const [selectedUserId, setSelectedUserId] = useState(userId ?? '');
  const [userPolicies, setUserPolicies] = useState<PolicyMap>({});
  const [userOverrides, setUserOverrides] = useState<PolicyMap>({});
  const [userUnrestricted, setUserUnrestricted] = useState(false);
  const [loading, setLoading] = useState(true);
  const [message, setMessage] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [catalogItems, roleState] = await Promise.all([
        listPolicyCatalog(),
        getRolePolicies('user'),
      ]);
      setCatalog(catalogItems);
      setRolePolicies(roleState.policies);
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载安全策略失败');
    } finally {
      setLoading(false);
    }
  }, []);

  const loadUserPolicies = useCallback(async (userId: string) => {
    if (!userId) {
      setUserPolicies({});
      setUserOverrides({});
      setUserUnrestricted(false);
      return;
    }
    try {
      const state = await getUserPolicies(userId);
      setUserPolicies(state.policies);
      setUserOverrides(state.overrides);
      setUserUnrestricted(state.unrestricted);
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载用户策略失败');
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  useEffect(() => {
    void loadUserPolicies(selectedUserId);
  }, [loadUserPolicies, selectedUserId]);

  useEffect(() => {
    if (userId) {
      setSelectedUserId(userId);
    }
  }, [userId]);

  const saveRoleDefaults = async () => {
    setMessage(null);
    setError(null);
    try {
      const result = await updateRolePolicies('user', rolePolicies);
      setRolePolicies(result.policies);
      setMessage('普通用户默认安全策略已保存');
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存失败');
    }
  };

  const saveUserOverrides = async () => {
    if (!selectedUserId) return;
    setMessage(null);
    setError(null);
    try {
      const result = await updateUserPolicies(selectedUserId, userPolicies);
      setUserPolicies(result.policies);
      await loadUserPolicies(selectedUserId);
      setMessage('用户单独策略已保存');
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存失败');
    }
  };

  const resetUserOverrides = async () => {
    if (!selectedUserId) return;
    setMessage(null);
    setError(null);
    try {
      await clearUserPolicyOverrides(selectedUserId);
      await loadUserPolicies(selectedUserId);
      setMessage('已恢复为角色默认策略');
    } catch (err) {
      setError(err instanceof Error ? err.message : '重置失败');
    }
  };

  const regularUsers = users.filter((user) => user.role === 'user');

  return (
    <section className="admin-card">
      <div className="admin-card-head">
        <h2>安全策略</h2>
        <button type="button" className="ghost-btn" onClick={() => void load()}>
          刷新
        </button>
      </div>
      <p className="muted capability-intro">
        控制 TKMind 模式、工作区只读、网络出站与 API 代理锁定。与上方「能力权限」叠加生效（策略会进一步收紧高风险能力）。
      </p>
      {error && <p className="banner banner-error">{error}</p>}
      {message && <p className="banner banner-info">{message}</p>}
      {loading ? (
        <p className="muted">加载中…</p>
      ) : (
        <>
          {!userOnly && (
            <>
              <h3 className="capability-section-title">普通用户默认策略</h3>
              <PolicyGrid
                catalog={catalog}
                values={rolePolicies}
                onChange={(key, value) => setRolePolicies((prev) => ({ ...prev, [key]: value }))}
              />
              <div className="capability-actions">
                <button type="button" className="send-btn" onClick={() => void saveRoleDefaults()}>
                  保存默认策略
                </button>
              </div>
            </>
          )}

          {!userOnly && <h3 className="capability-section-title">单用户策略覆盖</h3>}
          {!userOnly && (
            <div className="admin-form capability-user-picker">
              <select
                value={selectedUserId}
                onChange={(e) => setSelectedUserId(e.target.value)}
              >
                <option value="">选择用户（可选）</option>
                {regularUsers.map((user) => (
                  <option key={user.id} value={user.id}>
                    {user.displayName} (@{user.username})
                  </option>
                ))}
              </select>
            </div>
          )}
          {selectedUserId && (
            <>
              {userUnrestricted ? (
                <p className="muted">该用户为管理员，不受策略限制。</p>
              ) : (
                <>
                  {Object.keys(userOverrides).length > 0 && (
                    <p className="muted">
                      已设置 {Object.keys(userOverrides).length} 项单独覆盖。
                    </p>
                  )}
                  <PolicyGrid
                    catalog={catalog}
                    values={userPolicies}
                    onChange={(key, value) =>
                      setUserPolicies((prev) => ({ ...prev, [key]: value }))
                    }
                  />
                  <div className="capability-actions">
                    <button
                      type="button"
                      className="send-btn"
                      onClick={() => void saveUserOverrides()}
                    >
                      保存用户策略
                    </button>
                    <button
                      type="button"
                      className="ghost-btn"
                      onClick={() => void resetUserOverrides()}
                    >
                      恢复角色默认
                    </button>
                  </div>
                </>
              )}
            </>
          )}
        </>
      )}
    </section>
  );
}
