import { Button, Text, View } from "@tarojs/components";
import { useDidShow } from "@tarojs/taro";
import { useMemo, useState } from "react";
import {
  bootstrapOfficialSession,
  clearAgentSessionToken,
  getAgentCatalog,
  listAgentGrants,
  listAgentLogSummary,
  parseJsonLike,
  revokeAgentGrant,
  updateAgentGrantScope
} from "../../api/agent";
import { useAuthGuard } from "../../hooks/useAuthGuard";
import { useMemberGuard } from "../../hooks/useMemberGuard";
import "../ai-approvals/index.scss";
import "./index.scss";

function grantStatus(value: any) {
  const map: Record<string, string> = { active: "生效中", revoked: "已撤销", expired: "已过期" };
  return map[String(value || "")] || String(value || "-");
}

function clientName(item: any) {
  const code = String(item?.client_code || item?.clientCode || "");
  if (code === "official-ai") return "连小新";
  return String(item?.client_name || item?.clientName || code || "授权服务");
}

export default function AiGrantsPage() {
  useAuthGuard();
  useMemberGuard("连小新授权仅面向正式会员开放");

  const [grants, setGrants] = useState<any[]>([]);
  const [logs, setLogs] = useState<any[]>([]);
  const [catalog, setCatalog] = useState<Record<string, any>>({});
  const [selected, setSelected] = useState<Record<number, string[]>>({});
  const [loading, setLoading] = useState(false);
  const [busyId, setBusyId] = useState(0);
  const [error, setError] = useState("");

  const load = async () => {
    setLoading(true);
    try {
      await bootstrapOfficialSession();
      const [grantRows, logRows, catalogData] = await Promise.all([listAgentGrants(), listAgentLogSummary(), getAgentCatalog()]);
      const nextCatalog: Record<string, any> = {};
      Object.values(catalogData?.directory || {}).flat().forEach((item: any) => {
        nextCatalog[item.actionCode] = item;
      });
      const nextSelected: Record<number, string[]> = {};
      grantRows.forEach((grant: any) => {
        nextSelected[Number(grant.id)] = parseJsonLike<{ allowedActions?: string[] }>(grant.grant_scope_json || grant.grantScopeJson, {}).allowedActions || [];
      });
      setCatalog(nextCatalog);
      setSelected(nextSelected);
      setGrants(Array.isArray(grantRows) ? grantRows : []);
      setLogs(Array.isArray(logRows) ? logRows : []);
      setError("");
    } catch (e: any) {
      setError(e?.message || "授权信息加载失败");
    } finally {
      setLoading(false);
    }
  };

  useDidShow(() => {
    void load();
  });

  const catalogGroups = useMemo(() => {
    const groups = new Map<string, Array<any>>();
    Object.entries(catalog).forEach(([actionCode, item]) => {
      if ((item.implementationStatus || "active") !== "active") return;
      const moduleName = item.module || "其他";
      groups.set(moduleName, [...(groups.get(moduleName) || []), { ...item, actionCode }]);
    });
    return Array.from(groups.entries()).sort((a, b) => a[0].localeCompare(b[0], "zh-CN"));
  }, [catalog]);

  const toggle = (grantId: number, actionCode: string) => {
    setSelected((state) => {
      const list = state[grantId] || [];
      const next = list.includes(actionCode) ? list.filter((item) => item !== actionCode) : [...list, actionCode];
      return { ...state, [grantId]: next };
    });
  };

  const save = async (grantId: number) => {
    const allowedActions = selected[grantId] || [];
    if (!allowedActions.length) {
      setError("至少保留一个授权动作。");
      return;
    }
    setBusyId(grantId);
    try {
      const result = await updateAgentGrantScope(grantId, allowedActions);
      if (Array.isArray(result?.removedActions) && result.removedActions.length > 0) clearAgentSessionToken();
      await load();
    } catch (e: any) {
      setError(e?.message || "保存授权失败");
    } finally {
      setBusyId(0);
    }
  };

  const revoke = async (grantId: number) => {
    setBusyId(grantId);
    try {
      await revokeAgentGrant(grantId);
      clearAgentSessionToken();
      await load();
    } catch (e: any) {
      setError(e?.message || "撤销授权失败");
    } finally {
      setBusyId(0);
    }
  };

  return (
    <View className="ai-page">
      <View className="ai-page__body">
        {error ? <Text className="ai-state is-error">{error}</Text> : null}
        {loading ? <Text className="ai-state">加载中...</Text> : null}
        <View className="ai-summary">
          <Text className="ai-summary__label">授权服务</Text>
          <Text className="ai-summary__value">{grants.length}</Text>
          <Text className="grants-summary__sub">最近动作 {logs.length} 条</Text>
          <Button className="ai-summary__button" loading={loading} onClick={() => void load()}>刷新</Button>
        </View>
        {grants.length === 0 && !loading ? <Text className="ai-state">暂无授权记录</Text> : null}
        {grants.map((grant) => {
          const grantId = Number(grant.id);
          const chosen = selected[grantId] || [];
          const chosenSet = new Set(chosen);
          const active = String(grant.grant_status || grant.grantStatus || "") === "active";
          return (
            <View key={grantId} className="ai-card grants-card">
              <View className="ai-card__top">
                <Text className="ai-card__title">{clientName(grant)}</Text>
                <Text className="ai-card__status">{grantStatus(grant.grant_status || grant.grantStatus)}</Text>
              </View>
              <Text className="ai-card__meta">授权动作 {chosen.length} 项 · 上次使用 {grant.last_used_at || grant.lastUsedAt || "暂无"}</Text>
              {catalogGroups.map(([moduleName, actions]) => (
                <View key={moduleName} className="grants-module">
                  <Text className="grants-module__title">{moduleName}</Text>
                  <View className="grants-actions">
                    {actions.map((action: any) => {
                      const checked = chosenSet.has(action.actionCode);
                      return (
                        <View
                          key={action.actionCode}
                          className={`grants-action ${checked ? "is-checked" : ""} ${!active ? "is-disabled" : ""}`}
                          onClick={() => {
                            if (active) toggle(grantId, action.actionCode);
                          }}
                        >
                          <Text>{action.displayName || action.actionCode}</Text>
                        </View>
                      );
                    })}
                  </View>
                </View>
              ))}
              <View className="ai-card__actions grants-actions-row">
                <Button className="ai-card__btn ai-card__btn--ghost" loading={busyId === grantId} onClick={() => void revoke(grantId)}>撤销</Button>
                <Button className="ai-card__btn" disabled={!active} loading={busyId === grantId} onClick={() => void save(grantId)}>保存范围</Button>
              </View>
            </View>
          );
        })}
      </View>
    </View>
  );
}
