import React, { useState, useEffect } from 'react';
import { RefreshCw, ChevronDown, ChevronUp, Terminal, Copy, Check } from 'lucide-react';
import { DockerStatusCard } from '../../settings/components/DockerStatusCard';
import { InstallResultMessage } from '../../settings/components/InstallResultMessage';
import { DockerStatus, DockerVersion, InstallResult } from '../../types';
import { useSetupWizard } from '../SetupWizardContext';
import { Card } from '../../components/ui/card';
import { Button } from '../../components/ui/button';
import { Alert, AlertDescription } from '../../components/ui/alert';

export const DockerSetupStep: React.FC = () => {
  const { refreshStepStatus, refreshTrigger, scrollToTop, setStepWorking } = useSetupWizard();
  const [dockerStatus, setDockerStatus] = useState<DockerStatus>({
    installed: false,
    version: null,
    dockerDesktopVersion: null,
    updateAvailable: false,
    latestVersion: null,
    daemonRunning: false,
    composeInstalled: false,
    composeVersion: null
  });
  const [homebrewInstalled, setHomebrewInstalled] = useState(false);
  const [installing, setInstalling] = useState(false);
  const [updating, setUpdating] = useState(false);
  const [reinstalling, setReinstalling] = useState(false);
  const [refreshing, setRefreshing] = useState(true);
  const [installResult, setInstallResult] = useState<InstallResult | null>(null);
  const [showAboutStep, setShowAboutStep] = useState(false);
  const [showTroubleshooting, setShowTroubleshooting] = useState(false);
  const [installOutput, setInstallOutput] = useState<string>('');
  const [showInstallOutput, setShowInstallOutput] = useState(false);
  const [updateOutput, setUpdateOutput] = useState<string>('');
  const [showUpdateOutput, setShowUpdateOutput] = useState(false);
  const [reinstallOutput, setReinstallOutput] = useState<string>('');
  const [showReinstallOutput, setShowReinstallOutput] = useState(false);
  const [copiedCode, setCopiedCode] = useState<string | null>(null);
  const [copiedOutput, setCopiedOutput] = useState<string | null>(null);
  const [availableVersions, setAvailableVersions] = useState<DockerVersion[]>([]);
  const [selectedReinstallVersion, setSelectedReinstallVersion] = useState<string>('latest');
  const outputEndRef = React.useRef<HTMLDivElement>(null);

  const checkStatus = async (forceRefresh = false) => {
    try {
      const status = await window.setupWizardAPI.getDockerStatus(forceRefresh);
      setDockerStatus(status);

      // Check if homebrew is installed by checking if Docker install would work
      // This is a simple heuristic - if Docker is not installed, we assume Homebrew is available
      setHomebrewInstalled(true);

      // Refresh validation status
      await refreshStepStatus('docker-setup');
    } catch (error) {
      console.error('Failed to check Docker status:', error);
    } finally {
    }
  };

  useEffect(() => {
    const loadInitialStatus = async () => {
      await checkStatus();
      setRefreshing(false);
    };
    loadInitialStatus();

    // Load available versions for reinstall selector
    window.setupWizardAPI.getDockerVersions().then((versions) => {
      if (versions.length > 0) setAvailableVersions(versions);
    }).catch(() => {});
  }, []);

  // Listen to refresh trigger from context
  useEffect(() => {
    if (refreshTrigger > 0) {
      handleRefresh();
    }
  }, [refreshTrigger]);

  const handleInstall = async () => {
    setStepWorking('docker-setup', true);
    setInstalling(true);
    setInstallResult(null);
    setInstallOutput('');
    setShowInstallOutput(true);

    // Set up listener for install output
    const cleanup = window.setupWizardAPI.onInstallOutput((output) => {
      setInstallOutput((prev) => prev + output);
      // Auto-scroll to bottom
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    try {
      const result = await window.setupWizardAPI.installDocker();
      setInstallResult(result);

      if (result.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setInstallResult({
        success: false,
        message: error.message || 'Failed to install Docker'
      });
    } finally {
      setInstalling(false);
      setStepWorking('docker-setup', false);
      // Clean up listener
      cleanup();
    }
  };

  const handleUpdate = async () => {
    setStepWorking('docker-setup', true);
    setUpdating(true);
    setInstallResult(null);
    setUpdateOutput('');
    setShowUpdateOutput(true);

    // Set up listener for update output
    const cleanup = window.setupWizardAPI.onUpdateOutput((output) => {
      setUpdateOutput((prev) => prev + output);
      // Auto-scroll to bottom
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    try {
      const result = await window.setupWizardAPI.updateDocker();
      setInstallResult(result);

      if (result.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setInstallResult({
        success: false,
        message: error.message || 'Failed to update Docker'
      });
    } finally {
      setUpdating(false);
      setStepWorking('docker-setup', false);
      // Clean up listener
      cleanup();
    }
  };

  const handleReinstall = async () => {
    // Show confirmation dialog
    const versionLabel = selectedReinstallVersion === 'latest'
      ? 'the latest version'
      : `version ${selectedReinstallVersion}`;
    const confirmed = window.confirm(
      `Docker Desktop will be uninstalled and ${versionLabel} will be installed.\n\n` +
      'Important: You will be prompted to authenticate using Touch ID (if available) or your macOS password to authorize the uninstallation.\n\n' +
      'This process may take a few minutes. Continue?'
    );

    if (!confirmed) {
      return;
    }

    setStepWorking('docker-setup', true);
    setReinstalling(true);
    setInstallResult(null);
    setReinstallOutput('');
    setShowReinstallOutput(true);

    // Show info message about authentication
    setInstallResult({
      success: true,
      message: 'Starting reinstall... You will be prompted to authenticate using Touch ID or your password.'
    });

    // Set up listener for reinstall output
    const cleanup = window.setupWizardAPI.onReinstallOutput((output) => {
      setReinstallOutput((prev) => prev + output);
      // Auto-scroll to bottom
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    // Resolve which version to install (undefined = latest via Homebrew)
    const versionToInstall = selectedReinstallVersion === 'latest'
      ? undefined
      : availableVersions.find((v) => v.version === selectedReinstallVersion);

    try {
      const result = await window.setupWizardAPI.reinstallDocker(versionToInstall);
      setInstallResult(result);

      if (result.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setInstallResult({
        success: false,
        message: error.message || 'Failed to reinstall Docker'
      });
    } finally {
      setReinstalling(false);
      setStepWorking('docker-setup', false);
      // Clean up listener
      cleanup();
    }
  };

  const handleRefresh = async () => {
    setRefreshing(true);
    setInstallResult(null);
    await checkStatus(true); // Force refresh
    setRefreshing(false);
  };

  const handleOpenDocker = async () => {
    try {
      const result = await window.setupWizardAPI.openDocker();
      if (!result.success) {
        setInstallResult({
          success: false,
          message: result.message || 'Failed to open Docker Desktop'
        });
      }
    } catch (error: any) {
      setInstallResult({
        success: false,
        message: error.message || 'Failed to open Docker Desktop'
      });
    }
  };

  const handleOpenTerminal = async () => {
    try {
      const result = await window.setupWizardAPI.openTerminal();
      if (!result.success) {
        setInstallResult({
          success: false,
          message: result.message || 'Failed to open Terminal'
        });
      }
    } catch (error: any) {
      setInstallResult({
        success: false,
        message: error.message || 'Failed to open Terminal'
      });
    }
  };

  const handleCopyCode = async (code: string, id: string) => {
    try {
      await navigator.clipboard.writeText(code);
      setCopiedCode(id);
      setTimeout(() => setCopiedCode(null), 2000);
    } catch (error) {
      console.error('Failed to copy code:', error);
    }
  };

  return (
    <div className="space-y-4">
      <Card className="px-4 py-3">
        <div className="flex items-center justify-between">
          <p className="text-sm font-medium text-foreground">Ensure Docker is installed and running</p>
          <Button
            onClick={handleRefresh}
            disabled={refreshing || installing || updating || reinstalling}
            variant="ghost"
            size="sm"
          >
            <RefreshCw className={`h-4 w-4 mr-2 ${refreshing ? 'animate-spin' : ''}`} />
            {refreshing ? 'Refreshing...' : 'Refresh Status'}
          </Button>
        </div>
      </Card>

      {/* About This Step Section */}
      <Card className="p-5">
        <div className="space-y-3">
          <button
            onClick={() => setShowAboutStep(!showAboutStep)}
            className="flex items-center gap-2 text-sm w-full text-foreground hover:opacity-80"
          >
            {showAboutStep ? (
              <ChevronUp className="h-4 w-4" />
            ) : (
              <ChevronDown className="h-4 w-4" />
            )}
            About This Step
          </button>

          {showAboutStep && (
            <div className="p-4 rounded-lg text-sm space-y-4 bg-muted text-muted-foreground">
              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  What is Docker Desktop?
                </p>
                <p>
                  Docker Desktop is a container platform that allows applications to run in isolated environments.
                  For Canvas development, Docker provides a consistent development environment regardless of your host operating system.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Why is it needed?
                </p>
                <p>
                  Canvas uses Docker to containerize its application and services (database, Redis, etc.).
                  This ensures all developers work in identical environments and simplifies dependency management.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  What actions does this step perform?
                </p>
                <ul className="list-disc list-inside space-y-1">
                  <li>Checks if Docker Desktop is installed on your Mac</li>
                  <li>Detects the installed version and verifies Docker daemon is running</li>
                  <li>Checks for available updates</li>
                  <li>Provides options to install, update, or reinstall Docker Desktop</li>
                  <li>Monitors Docker service status and resource usage</li>
                </ul>
              </div>
            </div>
          )}
        </div>
      </Card>

      {installResult && (
        <InstallResultMessage
          result={installResult}
          onDismiss={() => setInstallResult(null)}
        />
      )}

      <DockerStatusCard
        status={dockerStatus}
        installing={installing}
        updating={updating}
        reinstalling={reinstalling}
        homebrewInstalled={homebrewInstalled}
        availableVersions={availableVersions}
        selectedReinstallVersion={selectedReinstallVersion}
        onVersionChange={setSelectedReinstallVersion}
        onInstall={handleInstall}
        onUpdate={handleUpdate}
        onReinstall={handleReinstall}
        onOpenDocker={handleOpenDocker}
      />

      {dockerStatus.installed && !dockerStatus.daemonRunning && (
        <Alert variant="warning">
          <AlertDescription>
            <p className="font-medium mb-1">Note:</p>
            <p className="text-xs">
              Docker is installed but the daemon is not running.
              Please start Docker Desktop from your Applications folder, then click the
              "Refresh Status" button above.
            </p>
          </AlertDescription>
        </Alert>
      )}

      <Card className="p-5">
        <div className="space-y-3">
          <div className="flex items-center justify-between">
            <button
              onClick={() => setShowTroubleshooting(!showTroubleshooting)}
              className="flex items-center gap-2 text-sm text-foreground hover:opacity-80"
            >
              {showTroubleshooting ? (
                <ChevronUp className="h-4 w-4" />
              ) : (
                <ChevronDown className="h-4 w-4" />
              )}
              Troubleshooting
            </button>
            {showTroubleshooting && (
              <Button
                onClick={handleOpenTerminal}
                variant="outline"
                size="sm"
                className="h-8 text-xs"
              >
                <Terminal className="h-3.5 w-3.5 mr-1.5" />
                Open Terminal
              </Button>
            )}
          </div>

          {showTroubleshooting && (
            <div className="p-4 rounded-lg text-sm space-y-4 bg-muted text-muted-foreground">
              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Uninstalling Docker Desktop Manually
                </p>
                <ol className="list-decimal list-inside space-y-2">
                  <li>Open your terminal</li>
                  <li className="flex items-start gap-2">
                    <span className="flex-1">
                      Run the following command:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          /Applications/Docker.app/Contents/MacOS/uninstall
                        </code>
                        <button
                          onClick={() => handleCopyCode('/Applications/Docker.app/Contents/MacOS/uninstall', 'docker-uninstall')}
                          className="p-1 hover:bg-secondary rounded flex-shrink-0"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'docker-uninstall' ? (
                            <Check className="h-3.5 w-3.5 text-green-600" />
                          ) : (
                            <Copy className="h-3.5 w-3.5 text-muted-foreground" />
                          )}
                        </button>
                      </div>
                    </span>
                  </li>
                </ol>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Installing Docker Desktop Manually
                </p>
                <ol className="list-decimal list-inside space-y-1">
                  <li>
                    Open{' '}
                    <a
                      href="https://docs.docker.com/desktop/setup/install/mac-install/"
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 dark:text-blue-400 underline hover:text-blue-700 dark:hover:text-blue-300"
                    >
                      https://docs.docker.com/desktop/setup/install/mac-install/
                    </a>{' '}
                    and follow the instructions
                  </li>
                </ol>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Configure Docker Desktop to optimize your Canvas development experience
                </p>
                <ol className="list-decimal list-inside space-y-2">
                  <li>Click the Preferences (Settings) icon in the top right corner</li>
                  <li>
                    Below lists a recommended range to configure your resources in the Resources &gt; Advanced tab:
                    <ul className="list-disc list-inside ml-6 mt-2 space-y-1">
                      <li>CPUs: 10 (recommended), can range from 5 - 10</li>
                      <li>Memory: 30 GB (recommended)</li>
                      <li>Swap: 2.5 GB (recommended)</li>
                      <li>Disk image size: 200 GB</li>
                    </ul>
                  </li>
                  <li>In the bottom right corner, click Apply &amp; Restart</li>
                </ol>
              </div>
            </div>
          )}
        </div>
      </Card>

      {showInstallOutput && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <h4 className="text-sm font-semibold text-foreground">Install Output</h4>
            <div className="flex items-center gap-1">
              <button
                onClick={() => { navigator.clipboard.writeText(installOutput); setCopiedOutput('install'); setTimeout(() => setCopiedOutput(null), 2000); }}
                className="p-1 hover:bg-secondary rounded"
                title="Copy output"
              >
                {copiedOutput === 'install' ? <Check className="h-3.5 w-3.5 text-green-600" /> : <Copy className="h-3.5 w-3.5 text-muted-foreground" />}
              </button>
              <Button
                onClick={() => setShowInstallOutput(false)}
                variant="ghost"
                size="sm"
                disabled={installing}
              >
                Hide
              </Button>
            </div>
          </div>
          <div
            className="bg-[#1a1a1a] text-[#00ff00] font-mono text-xs p-4 rounded-md overflow-auto max-h-96"
            style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}
          >
            {installOutput || 'Waiting for output...'}
            <div ref={outputEndRef} />
          </div>
        </Card>
      )}

      {showUpdateOutput && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <h4 className="text-sm font-semibold text-foreground">Update Output</h4>
            <div className="flex items-center gap-1">
              <button
                onClick={() => { navigator.clipboard.writeText(updateOutput); setCopiedOutput('update'); setTimeout(() => setCopiedOutput(null), 2000); }}
                className="p-1 hover:bg-secondary rounded"
                title="Copy output"
              >
                {copiedOutput === 'update' ? <Check className="h-3.5 w-3.5 text-green-600" /> : <Copy className="h-3.5 w-3.5 text-muted-foreground" />}
              </button>
              <Button
                onClick={() => setShowUpdateOutput(false)}
                variant="ghost"
                size="sm"
                disabled={updating}
              >
                Hide
              </Button>
            </div>
          </div>
          <div
            className="bg-[#1a1a1a] text-[#00ff00] font-mono text-xs p-4 rounded-md overflow-auto max-h-96"
            style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}
          >
            {updateOutput || 'Waiting for output...'}
            <div ref={outputEndRef} />
          </div>
        </Card>
      )}

      {showReinstallOutput && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <h4 className="text-sm font-semibold text-foreground">Reinstall Output</h4>
            <div className="flex items-center gap-1">
              <button
                onClick={() => { navigator.clipboard.writeText(reinstallOutput); setCopiedOutput('reinstall'); setTimeout(() => setCopiedOutput(null), 2000); }}
                className="p-1 hover:bg-secondary rounded"
                title="Copy output"
              >
                {copiedOutput === 'reinstall' ? <Check className="h-3.5 w-3.5 text-green-600" /> : <Copy className="h-3.5 w-3.5 text-muted-foreground" />}
              </button>
              <Button
                onClick={() => setShowReinstallOutput(false)}
                variant="ghost"
                size="sm"
                disabled={reinstalling}
              >
                Hide
              </Button>
            </div>
          </div>
          <div
            className="bg-[#1a1a1a] text-[#00ff00] font-mono text-xs p-4 rounded-md overflow-auto max-h-96"
            style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}
          >
            {reinstallOutput || 'Waiting for output...'}
            <div ref={outputEndRef} />
          </div>
        </Card>
      )}
    </div>
  );
};
