import React, { useState, useEffect } from 'react';
import { CheckCircle2, AlertCircle, RefreshCw, Plus, Play, Square , ChevronDown, ChevronUp, Terminal, Copy, Check } from 'lucide-react';
import { InstCliProxyStatus, 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';
import { Badge } from '../../components/ui/badge';
import traefikIcon from '../../assets/traefik-icon.png';

export const InstCliProxyStep: React.FC = () => {
  const { refreshStepStatus, refreshTrigger, scrollToTop, setStepWorking } = useSetupWizard();
  const [status, setStatus] = useState<InstCliProxyStatus>({
    instDomain: null,
    resolverFileExists: false,
    resolverFilePath: null,
    dockerComposeExists: false,
    dockerComposePath: '',
    traefikRunning: false,
    traefikContainerCount: 0,
    configured: false
  });
  const [creating, setCreating] = useState(false);
  const [starting, setStarting] = useState(false);
  const [stopping, setStopping] = useState(false);
  const [refreshing, setRefreshing] = useState(true);
  const [result, setResult] = useState<InstallResult | null>(null);
  const [showAboutStep, setShowAboutStep] = useState(false);
  const [showTroubleshooting, setShowTroubleshooting] = useState(false);
  const [terminalOutput, setTerminalOutput] = useState<string>('');
  const [showTerminal, setShowTerminal] = useState(false);
  const [copiedCode, setCopiedCode] = useState<string | null>(null);
  const [copiedOutput, setCopiedOutput] = useState<string | null>(null);

  const checkStatus = async (forceRefresh = false) => {
    try {
      const proxyStatus = await window.setupWizardAPI.getInstCliProxyStatus();
      setStatus(proxyStatus);

      // Refresh validation status
      await refreshStepStatus('inst-cli-proxy');
    } catch (error) {
      console.error('Failed to check inst-cli proxy status:', error);
    } finally {
    }
  };

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

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

  // Listen for start proxy output
  useEffect(() => {
    const unsubscribe = window.setupWizardAPI.onStartProxyOutput((output) => {
      setTerminalOutput((prev) => prev + output);
    });
    return unsubscribe;
  }, []);

  // Listen for stop proxy output
  useEffect(() => {
    const unsubscribe = window.setupWizardAPI.onStopProxyOutput((output) => {
      setTerminalOutput((prev) => prev + output);
    });
    return unsubscribe;
  }, []);

  const handleCreateDockerCompose = async () => {
    setStepWorking('inst-cli-proxy', true);
    setCreating(true);
    setResult(null);

    try {
      const createResult = await window.setupWizardAPI.createDockerComposeOverride();
      setResult(createResult);

      if (createResult.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setResult({
        success: false,
        message: error.message || 'Failed to create docker-compose.override.yml'
      });
    } finally {
      setCreating(false);
      setStepWorking('inst-cli-proxy', false);
    }
  };

  const handleRefresh = async () => {
    setRefreshing(true);
    setResult(null);
    await checkStatus(true);
    setRefreshing(false);
  };

  const handleStartProxy = async () => {
    setStepWorking('inst-cli-proxy', true);
    setStarting(true);
    setResult(null);
    setTerminalOutput('');
    setShowTerminal(true);

    try {
      const startResult = await window.setupWizardAPI.startProxy();
      setResult(startResult);

      if (startResult.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setResult({
        success: false,
        message: error.message || 'Failed to start proxy'
      });
    } finally {
      setStarting(false);
      setStepWorking('inst-cli-proxy', false);
    }
  };

  const handleStopProxy = async () => {
    setStepWorking('inst-cli-proxy', true);
    setStopping(true);
    setResult(null);
    setTerminalOutput('');
    setShowTerminal(true);

    try {
      const stopResult = await window.setupWizardAPI.stopProxy();
      setResult(stopResult);

      if (stopResult.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          checkStatus(true);
        }, 500);
      }
    } catch (error: any) {
      setResult({
        success: false,
        message: error.message || 'Failed to stop proxy'
      });
    } finally {
      setStopping(false);
      setStepWorking('inst-cli-proxy', false);
    }
  };

  const handleOpenTerminal = async () => {
    try {
      const result = await window.setupWizardAPI.openTerminal();
      if (!result.success) {
        setResult({
          success: false,
          message: result.message || 'Failed to open Terminal'
        });
      }
    } catch (error: any) {
      setResult({
        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">
            Configure inst-cli proxy
          </p>
          <Button
            onClick={handleRefresh}
            disabled={refreshing || creating || starting || stopping}
            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 inst-cli proxy?
                </p>
                <p>
                  The inst-cli proxy sets up Traefik reverse proxy with Dozzle for viewing Docker container logs. It configures local DNS resolution for your Canvas development domain.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Why is it needed?
                </p>
                <p>
                  Canvas needs to run on a proper domain (not localhost) for features like LTI, OAuth, and cookies to work correctly. The proxy also provides easy access to Docker logs via Dozzle.
                </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>Reads inst_domain from inst.yml configuration</li>
                  <li>Creates /etc/resolver/[domain] file for local DNS resolution</li>
                  <li>Configures Docker Compose override for Dozzle container</li>
                  <li>Checks if Traefik Docker Compose files exist</li>
                  <li>Provides buttons to start/stop the proxy</li>
                  <li>Monitors proxy status and container health</li>
                </ul>
              </div>
            </div>
          )}
        </div>
      </Card>

      {result && (
        <Alert variant={result.success ? "success" : "destructive"}>
          <AlertDescription className="text-xs">
            {result.message}
          </AlertDescription>
        </Alert>
      )}

      <Card className="p-5">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-lg overflow-hidden flex-shrink-0">
              <img src={traefikIcon} alt="Traefik Proxy" className="w-full h-full object-cover" />
            </div>
            <div>
              <h3 className="text-[15px] font-semibold text-foreground">inst-cli Proxy Configuration</h3>
              <div className="mt-1">
                {status.configured ? (
                  <Badge variant="success" className="text-xs">
                    <CheckCircle2 className="h-3.5 w-3.5 mr-1" />
                    Configured
                  </Badge>
                ) : (
                  <Badge variant="warning" className="text-xs">
                    <AlertCircle className="h-3.5 w-3.5 mr-1" />
                    Not Configured
                  </Badge>
                )}
              </div>
            </div>
          </div>
        </div>

        <div className="space-y-4">
          {/* inst_domain status */}
          <div className="space-y-2">
            <h4 className="text-sm font-medium text-foreground">
              inst_domain
            </h4>
            {status.instDomain ? (
              <Alert variant="success">
                <CheckCircle2 className="h-5 w-5" />
                <AlertDescription>
                  <p className="font-medium mb-1">Found: {status.instDomain}</p>
                  <p className="text-xs">
                    Read from <code className="bg-green-100 dark:bg-green-900/30 px-1 rounded">~/.inst-cli/inst.yml</code>
                  </p>
                </AlertDescription>
              </Alert>
            ) : (
              <Alert variant="warning">
                <AlertCircle className="h-5 w-5" />
                <AlertDescription>
                  <p className="font-medium mb-1">inst_domain not found</p>
                  <p className="text-xs">
                    Please configure <code className="bg-yellow-100 dark:bg-yellow-900/30 px-1 rounded">~/.inst-cli/inst.yml</code> first
                  </p>
                </AlertDescription>
              </Alert>
            )}
          </div>

          {/* Resolver file status */}
          {status.instDomain && (
            <div className="space-y-2">
              <h4 className="text-sm font-medium text-foreground">
                Resolver File
              </h4>
              {status.resolverFileExists ? (
                <Alert variant="success">
                  <CheckCircle2 className="h-5 w-5" />
                  <AlertDescription>
                    <p className="font-medium mb-1">Resolver file exists</p>
                    <p className="text-xs">
                      File location: <code className="bg-green-100 dark:bg-green-900/30 px-1 rounded">{status.resolverFilePath}</code>
                    </p>
                  </AlertDescription>
                </Alert>
              ) : (
                <Alert variant="warning">
                  <AlertCircle className="h-5 w-5" />
                  <AlertDescription>
                    <p className="font-medium mb-1">Resolver file not found</p>
                    <p className="text-xs">
                      Expected at: <code className="bg-yellow-100 dark:bg-yellow-900/30 px-1 rounded">{status.resolverFilePath}</code>
                    </p>
                  </AlertDescription>
                </Alert>
              )}
            </div>
          )}

          {/* Docker compose override status */}
          <div className="space-y-2">
            <h4 className="text-sm font-medium text-foreground">
              Docker Compose Override
            </h4>
            {status.dockerComposeExists ? (
              <Alert variant="success">
                <CheckCircle2 className="h-5 w-5" />
                <AlertDescription>
                  <p className="font-medium mb-1">docker-compose.override.yml exists</p>
                  <p className="text-xs">
                    File location: <code className="bg-green-100 dark:bg-green-900/30 px-1 rounded">{status.dockerComposePath}</code>
                  </p>
                </AlertDescription>
              </Alert>
            ) : (
              <>
                <Alert variant="warning">
                  <AlertCircle className="h-5 w-5" />
                  <AlertDescription>
                    <p className="font-medium mb-1">docker-compose.override.yml not found</p>
                    <p className="text-xs">
                      Expected at: <code className="bg-yellow-100 dark:bg-yellow-900/30 px-1 rounded">{status.dockerComposePath}</code>
                    </p>
                  </AlertDescription>
                </Alert>
                <Button
                  onClick={handleCreateDockerCompose}
                  disabled={creating}
                  className="w-full"
                >
                  {creating ? (
                    <>
                      <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
                      Creating...
                    </>
                  ) : (
                    <>
                      <Plus className="h-4 w-4 mr-2" />
                      Create docker-compose.override.yml
                    </>
                  )}
                </Button>
              </>
            )}
          </div>

          {/* Traefik Docker Compose status */}
          <div className="space-y-2">
            <h4 className="text-sm font-medium text-foreground">
              Traefik Docker Compose
            </h4>
            {status.traefikRunning && status.traefikContainerCount === 3 ? (
              <Alert variant="success">
                <CheckCircle2 className="h-5 w-5" />
                <AlertDescription>
                  <p className="font-medium mb-1">Traefik is running with {status.traefikContainerCount} containers</p>
                  <p className="text-xs">
                    Status: <code className="bg-green-100 dark:bg-green-900/30 px-1 rounded">running({status.traefikContainerCount})</code>
                  </p>
                </AlertDescription>
              </Alert>
            ) : (
              <Alert variant="warning">
                <AlertCircle className="h-5 w-5" />
                <AlertDescription>
                  <p className="font-medium mb-1">
                    {status.traefikRunning
                      ? `Traefik is running but has ${status.traefikContainerCount} container(s) (expected 3)`
                      : 'Traefik docker compose is not running'}
                  </p>
                  <p className="text-xs">
                    Run <code className="bg-yellow-100 dark:bg-yellow-900/30 px-1 rounded">inst proxy start</code>
                  </p>
                </AlertDescription>
              </Alert>
            )}
          </div>

          {/* Proxy Control Buttons */}
          <div className="space-y-2">
            <h4 className="text-sm font-medium text-foreground">
              Proxy Control
            </h4>
            <div className="flex gap-2">
              <Button
                onClick={handleStartProxy}
                disabled={starting || stopping || creating || !status.instDomain}
                className="flex-1"
                variant={status.configured ? "outline" : "default"}
              >
                {starting ? (
                  <>
                    <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
                    Starting...
                  </>
                ) : (
                  <>
                    <Play className="h-4 w-4 mr-2" />
                    Start Proxy
                  </>
                )}
              </Button>
              <Button
                onClick={handleStopProxy}
                disabled={stopping || starting || creating || !status.instDomain}
                className="flex-1"
                variant="destructive"
              >
                {stopping ? (
                  <>
                    <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
                    Stopping...
                  </>
                ) : (
                  <>
                    <Square className="h-4 w-4 mr-2" />
                    Stop Proxy
                  </>
                )}
              </Button>
            </div>
            {!status.instDomain && (
              <p className="text-xs text-orange-600">
                inst_domain is required to start/stop the proxy
              </p>
            )}
          </div>

          {/* Terminal Output */}
          {showTerminal && (
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <h4 className="text-sm font-medium text-foreground">
                  Terminal Output
                </h4>
                <button
                  onClick={() => { navigator.clipboard.writeText(terminalOutput); setCopiedOutput('terminal'); setTimeout(() => setCopiedOutput(null), 2000); }}
                  className="p-1 hover:bg-secondary rounded"
                  title="Copy output"
                >
                  {copiedOutput === 'terminal' ? <Check className="h-3.5 w-3.5 text-green-600" /> : <Copy className="h-3.5 w-3.5 text-muted-foreground" />}
                </button>
              </div>
              <div
                className="bg-black text-green-400 p-4 rounded font-mono text-xs overflow-auto max-h-96"
                style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
              >
                {terminalOutput || 'Waiting for output...'}
              </div>
            </div>
          )}

          <div className="pt-3 border-t border-border">
            <p className="text-xs mb-2 text-muted-foreground">
              <strong>Note:</strong> This step configures the inst-cli proxy with Dozzle for Docker log viewing.
            </p>
            <ul className="text-xs space-y-1 list-disc list-inside text-muted-foreground">
              <li>Requires <code className="bg-muted px-1 rounded">inst_domain</code> from inst.yml</li>
              <li>Resolver file at <code className="bg-muted px-1 rounded">/etc/resolver/[domain]</code></li>
              <li>Docker Compose override for Dozzle container</li>
              <li>Traefik must be running with 3 containers</li>
              <li><strong>Start Proxy:</strong> Creates resolver file and starts traefik containers</li>
              <li><strong>Stop Proxy:</strong> Runs <code className="bg-muted px-1 rounded">inst proxy stop</code></li>
            </ul>
          </div>
        </div>
      </Card>

      <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">
                  Proxy fails to start
                </p>
                <p>
                  If the proxy won't start:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Check if Docker is running</li>
                  <li>Verify ports 80 and 443 are not in use by other services</li>
                  <li>Try stopping and starting the proxy again</li>
                  <li>Check Docker logs for error messages</li>
                </ul>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Port conflicts
                </p>
                <p>
                  If you see "port already in use" errors:
                </p>
                <div className="flex items-center gap-2">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    lsof -i :80
                  </code>
                  <button
                    onClick={() => handleCopyCode('lsof -i :80', 'lsof-80')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'lsof-80' ? (
                      <Check className="h-3.5 w-3.5 text-green-600" />
                    ) : (
                      <Copy className="h-3.5 w-3.5 text-muted-foreground" />
                    )}
                  </button>
                </div>
                <div className="flex items-center gap-2 mt-1">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    lsof -i :443
                  </code>
                  <button
                    onClick={() => handleCopyCode('lsof -i :443', 'lsof-443')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'lsof-443' ? (
                      <Check className="h-3.5 w-3.5 text-green-600" />
                    ) : (
                      <Copy className="h-3.5 w-3.5 text-muted-foreground" />
                    )}
                  </button>
                </div>
                <p className="text-xs mt-2">
                  These commands show what's using ports 80 and 443. You may need to stop other web servers.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  DNS resolution not working
                </p>
                <p>
                  If your Canvas domain doesn't resolve:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Check that <code className="bg-secondary px-1 rounded">/etc/resolver/[domain]</code> file exists</li>
                  <li>Verify the file contains: <code className="bg-secondary px-1 rounded">nameserver 127.0.0.1</code></li>
                  <li className="flex items-start gap-2">
                    <span className="flex-1">
                      Try flushing DNS cache:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          sudo dscacheutil -flushcache
                        </code>
                        <button
                          onClick={() => handleCopyCode('sudo dscacheutil -flushcache', 'flush-dns')}
                          className="p-1 hover:bg-secondary rounded flex-shrink-0"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'flush-dns' ? (
                            <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>
                </ul>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Manually starting/stopping proxy
                </p>
                <p>
                  To manage the proxy via command line:
                </p>
                <div className="flex items-center gap-2">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    inst proxy start
                  </code>
                  <button
                    onClick={() => handleCopyCode('inst proxy start', 'inst-proxy-start')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'inst-proxy-start' ? (
                      <Check className="h-3.5 w-3.5 text-green-600" />
                    ) : (
                      <Copy className="h-3.5 w-3.5 text-muted-foreground" />
                    )}
                  </button>
                </div>
                <div className="flex items-center gap-2 mt-1">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    inst proxy stop
                  </code>
                  <button
                    onClick={() => handleCopyCode('inst proxy stop', 'inst-proxy-stop')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'inst-proxy-stop' ? (
                      <Check className="h-3.5 w-3.5 text-green-600" />
                    ) : (
                      <Copy className="h-3.5 w-3.5 text-muted-foreground" />
                    )}
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </Card>
    </div>
  );
};
