/**
 * AutonomyConfig - Configuration UI for L4 self-evolution authorization
 *
 * Allows users to configure:
 * - Autonomy level (supervised/assisted/autonomous)
 * - Individual action permissions
 * - Approval thresholds
 * - Audit log viewing
 *
 * Part of ZCLAW L4 Self-Evolution capability.
 */

import { useState, useCallback, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  Shield,
  ShieldAlert,
  ShieldCheck,
  ShieldQuestion,
  Settings,
  AlertTriangle,
  CheckCircle,
  Clock,
  RotateCcw,
  Info,
  ChevronDown,
  ChevronRight,
  Trash2,
} from 'lucide-react';
import {
  getAutonomyManager,
  DEFAULT_AUTONOMY_CONFIGS,
  type AutonomyConfig,
  type AutonomyLevel,
  type AuditLogEntry,
  type ActionType,
} from '../lib/autonomy-manager';

// === Types ===

interface AutonomyConfigProps {
  className?: string;
  onConfigChange?: (config: AutonomyConfig) => void;
}

// === Autonomy Level Config ===

const LEVEL_CONFIG: Record<AutonomyLevel, {
  label: string;
  description: string;
  icon: typeof Shield;
  color: string;
}> = {
  supervised: {
    label: '监督模式',
    description: '所有操作都需要用户确认',
    icon: ShieldQuestion,
    color: 'text-yellow-500',
  },
  assisted: {
    label: '辅助模式',
    description: '低风险操作自动执行，高风险需确认',
    icon: ShieldAlert,
    color: 'text-blue-500',
  },
  autonomous: {
    label: '自主模式',
    description: 'Agent 自主决策，仅高影响操作通知',
    icon: ShieldCheck,
    color: 'text-green-500',
  },
};

const ACTION_LABELS: Record<ActionType, string> = {
  memory_save: '自动保存记忆',
  memory_delete: '删除记忆',
  identity_update: '更新身份文件',
  identity_rollback: '回滚身份',
  skill_install: '安装技能',
  skill_uninstall: '卸载技能',
  config_change: '修改配置',
  workflow_trigger: '触发工作流',
  hand_trigger: '触发 Hand',
  llm_call: '调用 LLM',
  reflection_run: '运行反思',
  compaction_run: '运行压缩',
};

// === Components ===

function LevelSelector({
  value,
  onChange,
}: {
  value: AutonomyLevel;
  onChange: (level: AutonomyLevel) => void;
}) {
  return (
    <div className="space-y-2">
      {(Object.keys(LEVEL_CONFIG) as AutonomyLevel[]).map((level) => {
        const config = LEVEL_CONFIG[level];
        const Icon = config.icon;
        const isSelected = value === level;

        return (
          <button
            key={level}
            onClick={() => onChange(level)}
            className={`w-full flex items-start gap-3 p-3 rounded-lg border transition-all text-left ${
              isSelected
                ? 'border-purple-500 bg-purple-50 dark:bg-purple-900/30'
                : 'border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'
            }`}
          >
            <Icon className={`w-5 h-5 mt-0.5 flex-shrink-0 ${config.color}`} />
            <div className="flex-1 min-w-0">
              <div className={`text-sm font-medium ${
                isSelected ? 'text-purple-700 dark:text-purple-400' : 'text-gray-700 dark:text-gray-300'
              }`}>
                {config.label}
              </div>
              <div className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
                {config.description}
              </div>
            </div>
            {isSelected && (
              <CheckCircle className="w-4 h-4 text-purple-500 flex-shrink-0" />
            )}
          </button>
        );
      })}
    </div>
  );
}

function ActionToggle({
  label,
  enabled,
  onChange,
  disabled,
}: {
  label: string;
  enabled: boolean;
  onChange: (enabled: boolean) => void;
  disabled?: boolean;
}) {
  return (
    <div className={`flex items-center justify-between py-2 ${disabled ? 'opacity-50' : ''}`}>
      <span className="text-sm text-gray-700 dark:text-gray-300">{label}</span>
      <button
        onClick={() => !disabled && onChange(!enabled)}
        disabled={disabled}
        className={`relative w-9 h-5 rounded-full transition-colors ${
          enabled ? 'bg-green-500' : 'bg-gray-300 dark:bg-gray-600'
        } ${disabled ? 'cursor-not-allowed' : ''}`}
      >
        <motion.div
          animate={{ x: enabled ? 18 : 0 }}
          className="absolute top-0.5 left-0.5 w-4 h-4 bg-white rounded-full shadow"
        />
      </button>
    </div>
  );
}

function AuditLogEntryItem({
  entry,
  onRollback,
}: {
  entry: AuditLogEntry;
  onRollback?: (id: string) => void;
}) {
  const [expanded, setExpanded] = useState(false);

  const outcomeColors = {
    success: 'text-green-500',
    failed: 'text-red-500',
    rolled_back: 'text-yellow-500',
  };

  const outcomeLabels = {
    success: '成功',
    failed: '失败',
    rolled_back: '已回滚',
  };

  const time = new Date(entry.timestamp).toLocaleString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });

  return (
    <div className="border-b border-gray-100 dark:border-gray-800 last:border-b-0">
      <button
        onClick={() => setExpanded(!expanded)}
        className="w-full flex items-center gap-2 py-2 px-1 hover:bg-gray-50 dark:hover:bg-gray-800/30 transition-colors"
      >
        {expanded ? (
          <ChevronDown className="w-3 h-3 text-gray-400" />
        ) : (
          <ChevronRight className="w-3 h-3 text-gray-400" />
        )}
        <span className="text-xs text-gray-400">{time}</span>
        <span className="text-sm text-gray-700 dark:text-gray-300 flex-1 text-left truncate">
          {ACTION_LABELS[entry.action] || entry.action}
        </span>
        <span className={`text-xs ${outcomeColors[entry.outcome]}`}>
          {outcomeLabels[entry.outcome]}
        </span>
      </button>

      <AnimatePresence>
        {expanded && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            className="px-6 pb-2 space-y-1"
          >
            <div className="text-xs text-gray-500 dark:text-gray-400">
              风险: {entry.decision.riskLevel} · 重要性: {entry.decision.importance}
            </div>
            <div className="text-xs text-gray-500 dark:text-gray-400">
              原因: {entry.decision.reason}
            </div>
            {entry.outcome !== 'rolled_back' && entry.decision.riskLevel !== 'low' && (
              <button
                onClick={() => onRollback?.(entry.id)}
                className="flex items-center gap-1 text-xs text-yellow-600 dark:text-yellow-400 hover:underline mt-1"
              >
                <RotateCcw className="w-3 h-3" />
                回滚此操作
              </button>
            )}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

// === Main Component ===

export function AutonomyConfig({ className = '', onConfigChange }: AutonomyConfigProps) {
  const [manager] = useState(() => getAutonomyManager());
  const [config, setConfig] = useState<AutonomyConfig>(manager.getConfig());
  const [auditLog, setAuditLog] = useState<AuditLogEntry[]>([]);
  const [hasChanges, setHasChanges] = useState(false);

  // Load audit log
  useEffect(() => {
    setAuditLog(manager.getAuditLog(50));
  }, [manager]);

  const updateConfig = useCallback(
    (updates: Partial<AutonomyConfig>) => {
      setConfig((prev) => {
        const next = { ...prev, ...updates };
        setHasChanges(true);
        onConfigChange?.(next);
        return next;
      });
    },
    [onConfigChange]
  );

  const handleLevelChange = useCallback((level: AutonomyLevel) => {
    const newConfig = DEFAULT_AUTONOMY_CONFIGS[level];
    setConfig(newConfig);
    setHasChanges(true);
    onConfigChange?.(newConfig);
  }, [onConfigChange]);

  const handleSave = useCallback(() => {
    manager.updateConfig(config);
    setHasChanges(false);
  }, [manager, config]);

  const handleRollback = useCallback((auditId: string) => {
    if (manager.rollback(auditId)) {
      setAuditLog(manager.getAuditLog(50));
    }
  }, [manager]);

  const handleClearLog = useCallback(() => {
    manager.clearAuditLog();
    setAuditLog([]);
  }, [manager]);

  return (
    <div className={`flex flex-col h-full ${className}`}>
      {/* Header */}
      <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center gap-2">
          <Shield className="w-5 h-5 text-purple-500" />
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">自主授权</h2>
        </div>
        <button
          onClick={handleSave}
          disabled={!hasChanges}
          className="px-3 py-1.5 text-sm bg-purple-500 hover:bg-purple-600 disabled:bg-gray-300 disabled:cursor-not-allowed text-white rounded-lg transition-colors"
        >
          保存
        </button>
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto p-4 space-y-6">
        {/* Autonomy Level */}
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <ShieldAlert className="w-4 h-4 text-gray-500" />
            <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
              自主级别
            </span>
          </div>
          <LevelSelector value={config.level} onChange={handleLevelChange} />
        </div>

        {/* Allowed Actions */}
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <Settings className="w-4 h-4 text-gray-500" />
            <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
              允许的操作
            </span>
          </div>
          <div className="pl-6 space-y-1 border-l-2 border-gray-200 dark:border-gray-700">
            <ActionToggle
              label="自动保存记忆"
              enabled={config.allowedActions.memoryAutoSave}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, memoryAutoSave: enabled },
                })
              }
            />
            <ActionToggle
              label="自动更新身份文件"
              enabled={config.allowedActions.identityAutoUpdate}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, identityAutoUpdate: enabled },
                })
              }
            />
            <ActionToggle
              label="自动安装技能"
              enabled={config.allowedActions.skillAutoInstall}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, skillAutoInstall: enabled },
                })
              }
            />
            <ActionToggle
              label="自我修改行为"
              enabled={config.allowedActions.selfModification}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, selfModification: enabled },
                })
              }
            />
            <ActionToggle
              label="自动上下文压缩"
              enabled={config.allowedActions.autoCompaction}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, autoCompaction: enabled },
                })
              }
            />
            <ActionToggle
              label="自动反思"
              enabled={config.allowedActions.autoReflection}
              onChange={(enabled) =>
                updateConfig({
                  allowedActions: { ...config.allowedActions, autoReflection: enabled },
                })
              }
            />
          </div>
        </div>

        {/* Approval Thresholds */}
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <AlertTriangle className="w-4 h-4 text-gray-500" />
            <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
              审批阈值
            </span>
          </div>
          <div className="pl-6 space-y-3">
            <div className="flex items-center justify-between">
              <span className="text-sm text-gray-600 dark:text-gray-400">
                重要性上限
              </span>
              <input
                type="range"
                min="0"
                max="10"
                value={config.approvalThreshold.importanceMax}
                onChange={(e) =>
                  updateConfig({
                    approvalThreshold: {
                      ...config.approvalThreshold,
                      importanceMax: parseInt(e.target.value),
                    },
                  })
                }
                className="w-24 h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-purple-500"
              />
              <span className="text-sm font-medium text-gray-900 dark:text-gray-100 w-6 text-right">
                {config.approvalThreshold.importanceMax}
              </span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-sm text-gray-600 dark:text-gray-400">
                风险等级上限
              </span>
              <select
                value={config.approvalThreshold.riskMax}
                onChange={(e) =>
                  updateConfig({
                    approvalThreshold: {
                      ...config.approvalThreshold,
                      riskMax: e.target.value as 'low' | 'medium' | 'high',
                    },
                  })
                }
                className="px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
              >
                <option value="low">低风险</option>
                <option value="medium">中风险</option>
                <option value="high">高风险</option>
              </select>
            </div>
          </div>
        </div>

        {/* Audit Log */}
        <div className="space-y-2">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <Clock className="w-4 h-4 text-gray-500" />
              <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
                审计日志
              </span>
              <span className="text-xs text-gray-400">({auditLog.length} 条)</span>
            </div>
            <button
              onClick={handleClearLog}
              className="p-1 text-gray-400 hover:text-red-500 transition-colors"
              title="清除日志"
            >
              <Trash2 className="w-4 h-4" />
            </button>
          </div>

          {auditLog.length > 0 ? (
            <div className="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden max-h-64 overflow-y-auto">
              {auditLog
                .slice()
                .reverse()
                .map((entry) => (
                  <AuditLogEntryItem
                    key={entry.id}
                    entry={entry}
                    onRollback={handleRollback}
                  />
                ))}
            </div>
          ) : (
            <div className="text-center py-8 text-gray-400 dark:text-gray-500 text-sm">
              暂无审计日志
            </div>
          )}
        </div>

        {/* Info */}
        <div className="flex items-start gap-2 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg text-xs text-yellow-600 dark:text-yellow-400">
          <Info className="w-4 h-4 flex-shrink-0 mt-0.5" />
          <p>
            高风险操作（删除记忆、修改身份文件）始终需要用户确认，无论自主级别如何设置。
            所有自主操作都会记录在审计日志中，支持一键回滚。
          </p>
        </div>
      </div>
    </div>
  );
}

export default AutonomyConfig;
