/**
 * ApprovalsPanel - ZCLAW Execution Approvals UI
 *
 * Displays pending, approved, and rejected approval requests
 * for Hand executions that require human approval.
 *
 * Design based on ZCLAW Dashboard v0.4.0
 */

import { useState, useEffect, useCallback } from 'react';
import { useHandStore } from '../store/handStore';
import type { Approval, ApprovalStatus } from '../store/handStore';
import {
  CheckCircle,
  XCircle,
  Clock,
  RefreshCw,
  AlertCircle,
  Loader2,
} from 'lucide-react';

// === Status Badge Component ===

type FilterStatus = 'all' | ApprovalStatus;

interface StatusFilterConfig {
  label: string;
  className: string;
}

const STATUS_FILTER_CONFIG: Record<FilterStatus, StatusFilterConfig> = {
  all: {
    label: '全部',
    className:
      'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300',
  },
  pending: {
    label: '待审批',
    className:
      'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',
  },
  approved: {
    label: '已批准',
    className:
      'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
  },
  rejected: {
    label: '已拒绝',
    className:
      'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',
  },
  expired: {
    label: '已过期',
    className:
      'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400',
  },
};

function StatusFilterButton({
  status,
  isActive,
  count,
  onClick,
}: {
  status: FilterStatus;
  isActive: boolean;
  count?: number;
  onClick: () => void;
}) {
  const config = STATUS_FILTER_CONFIG[status];
  return (
    <button
      onClick={onClick}
      className={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${
        isActive
          ? config.className
          : 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800'
      }`}
    >
      {config.label}
      {count !== undefined && count > 0 && (
        <span className="ml-1.5 text-xs opacity-75">({count})</span>
      )}
    </button>
  );
}

// === Approval Status Icon ===

function ApprovalStatusIcon({ status }: { status: ApprovalStatus }) {
  switch (status) {
    case 'pending':
      return <Clock className="w-4 h-4 text-yellow-500" />;
    case 'approved':
      return <CheckCircle className="w-4 h-4 text-green-500" />;
    case 'rejected':
      return <XCircle className="w-4 h-4 text-red-500" />;
    case 'expired':
      return <AlertCircle className="w-4 h-4 text-gray-400" />;
    default:
      return null;
  }
}

// === Approval Card Component ===

interface ApprovalCardProps {
  approval: Approval;
  onApprove: (id: string) => void;
  onReject: (id: string, reason: string) => void;
  isProcessing: boolean;
}

function ApprovalCard({
  approval,
  onApprove,
  onReject,
  isProcessing,
}: ApprovalCardProps) {
  const [showRejectInput, setShowRejectInput] = useState(false);
  const [rejectReason, setRejectReason] = useState('');
  const isPending = approval.status === 'pending';

  const handleReject = () => {
    if (showRejectInput && rejectReason.trim()) {
      onReject(approval.id, rejectReason.trim());
      setRejectReason('');
      setShowRejectInput(false);
    } else {
      setShowRejectInput(true);
    }
  };

  const handleCancelReject = () => {
    setShowRejectInput(false);
    setRejectReason('');
  };

  return (
    <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4 shadow-sm">
      {/* Header */}
      <div className="flex items-start justify-between gap-3 mb-3">
        <div className="flex items-center gap-2 min-w-0">
          <ApprovalStatusIcon status={approval.status} />
          <div className="min-w-0">
            <h3 className="font-medium text-gray-900 dark:text-white truncate">
              {approval.handName}
            </h3>
            <p className="text-xs text-gray-500 dark:text-gray-400">
              {approval.action || '执行'} •{' '}
              {new Date(approval.requestedAt).toLocaleString()}
            </p>
          </div>
        </div>
        <span
          className={`flex-shrink-0 px-2 py-0.5 rounded text-xs font-medium ${
            STATUS_FILTER_CONFIG[approval.status]?.className ||
            STATUS_FILTER_CONFIG.pending.className
          }`}
        >
          {approval.status}
        </span>
      </div>

      {/* Reason */}
      {approval.reason && (
        <p className="text-sm text-gray-600 dark:text-gray-400 mb-3">
          {approval.reason}
        </p>
      )}

      {/* Params Preview */}
      {approval.params && Object.keys(approval.params).length > 0 && (
        <div className="mb-3 p-2 bg-gray-50 dark:bg-gray-900 rounded text-xs font-mono text-gray-600 dark:text-gray-400 overflow-x-auto">
          <pre>{JSON.stringify(approval.params, null, 2)}</pre>
        </div>
      )}

      {/* Response Info (if responded) */}
      {approval.status !== 'pending' && approval.respondedAt && (
        <div className="mb-3 text-xs text-gray-500 dark:text-gray-400">
          <p>
            响应时间: {new Date(approval.respondedAt).toLocaleString()}
            {approval.respondedBy && ` 由 ${approval.respondedBy}`}
          </p>
          {approval.responseReason && (
            <p className="mt-1 italic">"{approval.responseReason}"</p>
          )}
        </div>
      )}

      {/* Reject Input */}
      {showRejectInput && (
        <div className="mb-3 space-y-2">
          <textarea
            value={rejectReason}
            onChange={(e) => setRejectReason(e.target.value)}
            placeholder="请输入拒绝原因..."
            className="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-md bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-red-500"
            rows={2}
            autoFocus
          />
          <div className="flex gap-2">
            <button
              onClick={handleCancelReject}
              className="px-3 py-1 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200"
            >
              取消
            </button>
            <button
              onClick={handleReject}
              disabled={!rejectReason.trim() || isProcessing}
              className="px-3 py-1 text-sm bg-red-600 text-white rounded-md hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed"
            >
              确认拒绝
            </button>
          </div>
        </div>
      )}

      {/* Actions */}
      {isPending && !showRejectInput && (
        <div className="flex items-center gap-2">
          <button
            onClick={() => onApprove(approval.id)}
            disabled={isProcessing}
            className="px-3 py-1.5 text-sm bg-green-600 text-white rounded-md hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1"
          >
            {isProcessing ? (
              <Loader2 className="w-3.5 h-3.5 animate-spin" />
            ) : (
              <CheckCircle className="w-3.5 h-3.5" />
            )}
            批准
          </button>
          <button
            onClick={handleReject}
            disabled={isProcessing}
            className="px-3 py-1.5 text-sm border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 rounded-md hover:bg-red-50 dark:hover:bg-red-900/20 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1"
          >
            <XCircle className="w-3.5 h-3.5" />
            拒绝
          </button>
        </div>
      )}
    </div>
  );
}

// === Empty State Component ===

function EmptyState({ filter }: { filter: FilterStatus }) {
  const messages: Record<FilterStatus, { title: string; description: string }> = {
    all: {
      title: '暂无审批请求',
      description:
        '当代理请求执行敏感操作时，审批请求将显示在这里。',
    },
    pending: {
      title: '暂无待审批请求',
      description: '所有审批请求已处理完成。',
    },
    approved: {
      title: '暂无已批准请求',
      description: '还没有批准任何请求。',
    },
    rejected: {
      title: '暂无已拒绝请求',
      description: '还没有拒绝任何请求。',
    },
    expired: {
      title: '暂无已过期请求',
      description: '没有过期的审批请求。',
    },
  };

  const { title, description } = messages[filter];

  return (
    <div className="text-center py-12">
      <div className="w-16 h-16 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center mx-auto mb-4">
        <AlertCircle className="w-8 h-8 text-gray-400" />
      </div>
      <p className="text-sm font-medium text-gray-900 dark:text-white mb-1">
        {title}
      </p>
      <p className="text-xs text-gray-500 dark:text-gray-400 max-w-sm mx-auto">
        {description}
      </p>
    </div>
  );
}

// === Main ApprovalsPanel Component ===

export function ApprovalsPanel() {
  const approvals = useHandStore((s) => s.approvals);
  const loadApprovals = useHandStore((s) => s.loadApprovals);
  const respondToApproval = useHandStore((s) => s.respondToApproval);
  const isLoading = useHandStore((s) => s.isLoading);
  const [filter, setFilter] = useState<FilterStatus>('all');
  const [processingId, setProcessingId] = useState<string | null>(null);

  useEffect(() => {
    loadApprovals();
  }, [loadApprovals]);

  const handleApprove = useCallback(
    async (id: string) => {
      setProcessingId(id);
      try {
        await respondToApproval(id, true);
      } finally {
        setProcessingId(null);
      }
    },
    [respondToApproval]
  );

  const handleReject = useCallback(
    async (id: string, reason: string) => {
      setProcessingId(id);
      try {
        await respondToApproval(id, false, reason);
      } finally {
        setProcessingId(null);
      }
    },
    [respondToApproval]
  );

  // Filter approvals
  const filteredApprovals =
    filter === 'all'
      ? approvals
      : approvals.filter((a) => a.status === filter);

  // Count by status
  const counts = {
    all: approvals.length,
    pending: approvals.filter((a) => a.status === 'pending').length,
    approved: approvals.filter((a) => a.status === 'approved').length,
    rejected: approvals.filter((a) => a.status === 'rejected').length,
    expired: approvals.filter((a) => a.status === 'expired').length,
  };

  if (isLoading && approvals.length === 0) {
    return (
      <div className="p-4 text-center">
        <Loader2 className="w-6 h-6 animate-spin mx-auto text-gray-400 mb-2" />
        <p className="text-sm text-gray-500 dark:text-gray-400">
          加载审批列表中...
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
            执行审批
          </h2>
          <p className="text-xs text-gray-500 dark:text-gray-400">
            审核并批准 Hand 执行请求
          </p>
        </div>
        <button
          onClick={() => loadApprovals()}
          disabled={isLoading}
          className="text-sm text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1 disabled:opacity-50"
        >
          {isLoading ? (
            <Loader2 className="w-3.5 h-3.5 animate-spin" />
          ) : (
            <RefreshCw className="w-3.5 h-3.5" />
          )}
          刷新
        </button>
      </div>

      {/* Filters */}
      <div className="flex items-center gap-1 p-1 bg-gray-100 dark:bg-gray-800 rounded-lg">
        {(Object.keys(STATUS_FILTER_CONFIG) as FilterStatus[]).map((status) => (
          <StatusFilterButton
            key={status}
            status={status}
            isActive={filter === status}
            count={counts[status]}
            onClick={() => setFilter(status)}
          />
        ))}
      </div>

      {/* Approvals List */}
      {filteredApprovals.length === 0 ? (
        <EmptyState filter={filter} />
      ) : (
        <div className="space-y-3">
          {filteredApprovals.map((approval) => (
            <ApprovalCard
              key={approval.id}
              approval={approval}
              onApprove={handleApprove}
              onReject={handleReject}
              isProcessing={processingId === approval.id}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export default ApprovalsPanel;
