import { useState } from 'react';
import {
  X,
  Download,
  CheckCircle,
  AlertCircle,
  RefreshCw,
  Info,
  Users,
  Package,
  Hash,
} from 'lucide-react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { agentApi, updateApi } from '@/lib/api';
import toast from 'react-hot-toast';
import { cn } from '@/lib/utils';
import { Agent } from '@/types';

interface AgentUpdatesModalProps {
  isOpen: boolean;
  onClose: () => void;
  selectedAgentIds: string[];
  onAgentsUpdated: () => void;
}

export function AgentUpdatesModal({
  isOpen,
  onClose,
  selectedAgentIds,
  onAgentsUpdated,
}: AgentUpdatesModalProps) {
  const [selectedVersion, setSelectedVersion] = useState('');
  const [selectedPlatform, setSelectedPlatform] = useState('');
  const [isUpdating, setIsUpdating] = useState(false);

  // Fetch selected agents details
  const { data: agents = [] } = useQuery<Agent[]>({
    queryKey: ['agents-details', selectedAgentIds],
    queryFn: async (): Promise<Agent[]> => {
      const promises = selectedAgentIds.map(id => agentApi.getAgent(id));
      const results = await Promise.all(promises);
      return results;
    },
    enabled: isOpen && selectedAgentIds.length > 0,
  });

  // Fetch available update packages
  const { data: packagesResponse, isLoading: packagesLoading } = useQuery({
    queryKey: ['update-packages'],
    queryFn: () => updateApi.getPackages(),
    enabled: isOpen,
  });

  const packages = packagesResponse?.packages || [];

  // Group packages by version
  const versions = [...new Set(packages.map(pkg => pkg.version))].sort((a, b) => b.localeCompare(a));
  const platforms = [...new Set(packages.map(pkg => pkg.platform))].sort();

  // Filter packages based on selection
  const availablePackages = packages.filter(
    pkg => (!selectedVersion || pkg.version === selectedVersion) &&
           (!selectedPlatform || pkg.platform === selectedPlatform)
  );

  // Get unique platform for selected agents (simplified - assumes all agents same platform)
  const agentPlatform = agents[0]?.os_type || 'linux';
  const agentArchitecture = agents[0]?.os_architecture || 'amd64';

  // Update agents mutation
  const updateAgentsMutation = useMutation({
    mutationFn: async (packageId: string) => {
      const pkg = packages.find(p => p.id === packageId);
      if (!pkg) throw new Error('Package not found');

      // For single agent updates, use individual update with nonce for security
      if (selectedAgentIds.length === 1) {
        const agentId = selectedAgentIds[0];

        // Generate nonce for security
        const nonceData = await agentApi.generateUpdateNonce(agentId, pkg.version);
        console.log('[UI] Update nonce generated for single agent:', nonceData);

        // Use individual update endpoint with nonce
        return agentApi.updateAgent(agentId, {
          version: pkg.version,
          platform: pkg.platform,
          nonce: nonceData.update_nonce
        });
      }

      // For multiple agents, generate nonces for each then bulk update
      const noncePromises = selectedAgentIds.map(async (agentId) => {
        try {
          const nonceData = await agentApi.generateUpdateNonce(agentId, pkg.version);
          return { agentId, nonce: nonceData.update_nonce };
        } catch {
          return null;
        }
      });
      const nonceResults = (await Promise.all(noncePromises)).filter(Boolean) as { agentId: string; nonce: string }[];

      if (nonceResults.length === 0) {
        throw new Error('Failed to generate nonces for any agents');
      }

      return agentApi.updateMultipleAgents({
        agent_ids: nonceResults.map(n => n.agentId),
        version: pkg.version,
        platform: pkg.platform,
        nonces: nonceResults.map(n => n.nonce),
      });
    },
    onSuccess: () => {
      const count = selectedAgentIds.length;
      const message = count === 1 ? 'Update initiated for agent' : `Update initiated for ${count} agents`;
      toast.success(message);
      setIsUpdating(false);
      onAgentsUpdated();
      onClose();
    },
    onError: (error: any) => {
      toast.error(`Failed to update agents: ${error.message}`);
      setIsUpdating(false);
    },
  });

  const handleUpdateAgents = async (packageId: string) => {
    setIsUpdating(true);
    updateAgentsMutation.mutate(packageId);
  };

  const canUpdate = selectedAgentIds.length > 0 && availablePackages.length > 0 && !isUpdating;
  const hasUpdatingAgents = agents.some(agent => agent.is_updating);

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 overflow-y-auto">
      <div className="flex min-h-full items-center justify-center p-4 text-center">
        <div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" onClick={onClose} />

        <div className="relative w-full max-w-4xl transform overflow-hidden rounded-lg bg-white p-6 text-left shadow-xl transition-all">
          {/* Header */}
          <div className="flex items-center justify-between pb-4 border-b">
            <div className="flex items-center space-x-3">
              <Download className="h-6 w-6 text-primary-600" />
              <div>
                <h3 className="text-lg font-semibold text-gray-900">Agent Updates</h3>
                <p className="text-sm text-gray-500">
                  Update {selectedAgentIds.length} agent{selectedAgentIds.length !== 1 ? 's' : ''}
                </p>
              </div>
            </div>
            <button
              onClick={onClose}
              className="rounded-md p-2 text-gray-400 hover:text-gray-500"
            >
              <X className="h-5 w-5" />
            </button>
          </div>

          {/* Content */}
          <div className="py-4">
            {/* Selected Agents */}
            <div className="mb-6">
              <h4 className="text-sm font-medium text-gray-900 mb-3 flex items-center">
                <Users className="h-4 w-4 mr-2" />
                Selected Agents
              </h4>
              <div className="max-h-32 overflow-y-auto space-y-2">
                {agents.map((agent) => (
                  <div key={agent.id} className="flex items-center justify-between p-2 bg-gray-50 rounded">
                    <div className="flex items-center space-x-3">
                      <CheckCircle className={cn(
                        "h-4 w-4",
                        agent.status === 'online' ? "text-green-500" : "text-gray-400"
                      )} />
                      <div>
                        <div className="text-sm font-medium text-gray-900">{agent.hostname}</div>
                        <div className="text-xs text-gray-500">
                          {agent.os_type}/{agent.os_architecture} • Current: {agent.current_version || 'Unknown'}
                        </div>
                      </div>
                    </div>
                    {agent.is_updating && (
                      <div className="flex items-center text-amber-600 text-xs">
                        <RefreshCw className="h-3 w-3 mr-1 animate-spin" />
                        Updating to {agent.updating_to_version}
                      </div>
                    )}
                  </div>
                ))}
              </div>
              {hasUpdatingAgents && (
                <div className="mt-2 text-xs text-amber-600 flex items-center">
                  <AlertCircle className="h-3 w-3 mr-1" />
                  Some agents are currently updating
                </div>
              )}
            </div>

            {/* Package Selection */}
            <div className="mb-6">
              <h4 className="text-sm font-medium text-gray-900 mb-3 flex items-center">
                <Package className="h-4 w-4 mr-2" />
                Update Package Selection
              </h4>

              {/* Filters */}
              <div className="grid grid-cols-2 gap-4 mb-4">
                <div>
                  <label className="block text-xs font-medium text-gray-700 mb-1">Version</label>
                  <select
                    value={selectedVersion}
                    onChange={(e) => setSelectedVersion(e.target.value)}
                    className="w-full rounded-md border-gray-300 shadow-sm text-sm"
                  >
                    <option value="">All Versions</option>
                    {versions.map(version => (
                      <option key={version} value={version}>{version}</option>
                    ))}
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-medium text-gray-700 mb-1">Platform</label>
                  <select
                    value={selectedPlatform}
                    onChange={(e) => setSelectedPlatform(e.target.value)}
                    className="w-full rounded-md border-gray-300 shadow-sm text-sm"
                  >
                    <option value="">All Platforms</option>
                    {platforms.map(platform => (
                      <option key={platform} value={platform}>{platform}</option>
                    ))}
                  </select>
                </div>
              </div>

              {/* Available Packages */}
              <div className="space-y-2 max-h-48 overflow-y-auto">
                {packagesLoading ? (
                  <div className="text-center py-4 text-sm text-gray-500">
                    Loading packages...
                  </div>
                ) : availablePackages.length === 0 ? (
                  <div className="text-center py-4 text-sm text-gray-500">
                    No packages available for the selected criteria
                  </div>
                ) : (
                  availablePackages.map((pkg) => (
                    <div
                      key={pkg.id}
                      className={cn(
                        "flex items-center justify-between p-3 border rounded-lg cursor-pointer transition-colors",
                        "hover:bg-gray-50 border-gray-200"
                      )}
                      onClick={() => handleUpdateAgents(pkg.id)}
                    >
                      <div className="flex items-center space-x-3">
                        <Package className="h-4 w-4 text-primary-600" />
                        <div>
                          <div className="text-sm font-medium text-gray-900">
                            Version {pkg.version}
                          </div>
                          <div className="text-xs text-gray-500">
                            {pkg.platform} • {(pkg.file_size / 1024 / 1024).toFixed(1)} MB
                          </div>
                        </div>
                      </div>
                      <div className="flex items-center space-x-2">
                        <div className="text-xs text-gray-400">
                          <Hash className="h-3 w-3 inline mr-1" />
                          {pkg.checksum.slice(0, 8)}...
                        </div>
                        <button
                          disabled={!canUpdate}
                          className={cn(
                            "px-3 py-1 text-xs rounded-md font-medium transition-colors",
                            canUpdate
                              ? "bg-primary-600 text-white hover:bg-primary-700"
                              : "bg-gray-100 text-gray-400 cursor-not-allowed"
                          )}
                        >
                          {isUpdating ? (
                            <RefreshCw className="h-3 w-3 animate-spin" />
                          ) : (
                            'Update'
                          )}
                        </button>
                      </div>
                    </div>
                  ))
                )}
              </div>
            </div>

            {/* Platform Compatibility Info */}
            <div className="text-xs text-gray-500 flex items-start">
              <Info className="h-3 w-3 mr-1 mt-0.5 flex-shrink-0" />
              <span>
                Detected platform: <strong>{agentPlatform}/{agentArchitecture}</strong>.
                Only compatible packages will be shown.
              </span>
            </div>
          </div>

          {/* Footer */}
          <div className="flex justify-end space-x-3 pt-4 border-t">
            <button
              onClick={onClose}
              disabled={isUpdating}
              className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50"
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}