import React, { useState, useEffect } from 'react';
import { CheckCircle2, AlertCircle, Loader2, RefreshCw , ChevronDown, ChevronUp, Terminal, Copy, Check } from 'lucide-react';
import { InstCliStatus, 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 terminalIcon from '../../assets/terminal-icon.png';

export const InstallInstCliStep: React.FC = () => {
  const { refreshStepStatus, refreshTrigger, triggerRefresh, scrollToTop, setStepWorking } = useSetupWizard();
  const [status, setStatus] = useState<InstCliStatus>({
    imageExists: false
  });
  const [building, setBuilding] = 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 [buildOutput, setBuildOutput] = useState<string>('');
  const [showOutput, setShowOutput] = useState(false);
  const [copiedCode, setCopiedCode] = useState<string | null>(null);
  const [copiedOutput, setCopiedOutput] = useState<string | null>(null);
  const outputEndRef = React.useRef<HTMLDivElement>(null);

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

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

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

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

  const handleBuild = async () => {
    setStepWorking('inst-cli-install', true);
    setBuilding(true);
    setResult(null);
    setBuildOutput('');
    setShowOutput(true);

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

    try {
      const buildResult = await window.setupWizardAPI.buildInstCli();
      setResult(buildResult);

      if (buildResult.success) {
        // Wait for UI to update before scrolling and refreshing
        setTimeout(() => {
          scrollToTop();
          triggerRefresh();
        }, 500);
      }
    } catch (error: any) {
      setResult({
        success: false,
        message: error.message || 'Failed to build inst-cli image'
      });
    } finally {
      setBuilding(false);
      setStepWorking('inst-cli-install', false);
      // Clean up listener
      cleanup();
    }
  };

  const handleRefresh = async () => {
    setRefreshing(true);
    setResult(null);
    await checkStatus(true); // Force refresh
    setRefreshing(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">Build the inst-cli Docker image</p>
          <Button
            onClick={handleRefresh}
            disabled={refreshing || building}
            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?
                </p>
                <p>
                  inst-cli is Instructure's command-line tool that provides a Docker-based development environment for Canvas. It encapsulates all the tools and dependencies needed for Canvas development in a container.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Why is it needed?
                </p>
                <p>
                  Canvas has complex dependencies (Ruby, Node.js, etc.). inst-cli packages everything in a Docker image, ensuring consistent environments and simplifying setup.
                </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 the inst-cli Docker image exists locally</li>
                  <li>Reads version information from the image if it exists</li>
                  <li>Provides option to build the inst-cli image</li>
                  <li>Monitors build progress with real-time output</li>
                  <li>Verifies the image was built successfully</li>
                  <li>Displays installed tool versions (Ruby, Node.js, etc.)</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={terminalIcon} alt="Terminal" className="w-full h-full object-cover" />
            </div>
            <div>
              <h3 className="text-[15px] font-semibold text-foreground">inst-cli</h3>
              <div className="mt-1">
                {status.imageExists ? (
                  <Badge variant="success" className="text-xs">
                    <CheckCircle2 className="h-3.5 w-3.5 mr-1" />
                    Image Built
                  </Badge>
                ) : (
                  <Badge variant="secondary" className="text-xs">
                    <AlertCircle className="h-3.5 w-3.5 mr-1" />
                    Not Built
                  </Badge>
                )}
              </div>
            </div>
          </div>
        </div>

        {status.imageExists ? (
          <div className="space-y-4">
            <Alert variant={status.updateAvailable ? "warning" : "success"}>
              {status.updateAvailable ? <AlertCircle className="h-5 w-5" /> : <CheckCircle2 className="h-5 w-5" />}
              <AlertDescription>
                <p className="font-medium mb-1">
                  {status.updateAvailable ? 'inst-cli image is ready (Updates available)' : 'inst-cli image is ready'}
                </p>
                <p className="text-xs">
                  The Docker image <code className={status.updateAvailable ? "bg-orange-100 dark:bg-orange-900/30 px-1 rounded" : "bg-green-100 dark:bg-green-900/30 px-1 rounded"}>inst-cli</code> has been built successfully.
                </p>
                {status.imageCreated && (
                  <p className="text-xs mt-2">
                    Created: {status.imageCreated}
                  </p>
                )}
                {status.versions && (status.versions.inst || status.versions.instCliQuizzes || status.versions.ruby || status.versions.pnpm || status.versions.instFunctions || status.versions.claude) && (
                  <div className={`mt-3 pt-3 border-t ${status.updateAvailable ? 'border-orange-400' : 'border-green-400'}`}>
                    <p className="font-medium text-xs mb-2">Versions:</p>
                    <div className="space-y-1 text-xs font-mono">
                      {status.versions.inst && (
                        <div className="flex items-center gap-2">
                          <span>inst: <span className={status.instUpdateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.inst}</span></span>
                          {status.instUpdateAvailable && status.latestVersions?.inst ? (
                            <span className="text-orange-700 dark:text-orange-400 text-[10px]">(Latest: {status.latestVersions.inst})</span>
                          ) : !status.instUpdateAvailable ? (
                            <span className="text-green-700 dark:text-green-400 text-[10px]">(Latest)</span>
                          ) : null}
                        </div>
                      )}
                      {status.versions.instCliQuizzes && (
                        <div className="flex items-center gap-2">
                          <span>inst-cli-quizzes: <span className={status.instCliQuizzesUpdateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.instCliQuizzes}</span></span>
                          {status.instCliQuizzesUpdateAvailable && status.latestVersions?.instCliQuizzes ? (
                            <span className="text-orange-700 dark:text-orange-400 text-[10px]">(Latest: {status.latestVersions.instCliQuizzes})</span>
                          ) : !status.instCliQuizzesUpdateAvailable ? (
                            <span className="text-green-700 dark:text-green-400 text-[10px]">(Latest)</span>
                          ) : null}
                        </div>
                      )}
                      {status.versions.ruby && (
                        <div>ruby: <span className={status.updateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.ruby}</span></div>
                      )}
                      {status.versions.pnpm && (
                        <div>pnpm: <span className={status.updateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.pnpm}</span></div>
                      )}
                      {status.versions.instFunctions && (
                        <div>inst-functions: <span className={status.updateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.instFunctions}</span></div>
                      )}
                      {status.versions.claude && (
                        <div className="flex items-center gap-2">
                          <span>claude: <span className={status.claudeUpdateAvailable ? "text-orange-700 dark:text-orange-400" : "text-green-800 dark:text-green-400"}>{status.versions.claude}</span></span>
                          {status.claudeUpdateAvailable && status.latestVersions?.claude ? (
                            <span className="text-orange-700 dark:text-orange-400 text-[10px]">(Latest: {status.latestVersions.claude})</span>
                          ) : !status.claudeUpdateAvailable ? (
                            <span className="text-green-700 dark:text-green-400 text-[10px]">(Latest)</span>
                          ) : null}
                        </div>
                      )}
                    </div>
                  </div>
                )}
                {status.updateAvailable && (
                  <p className="text-xs mt-3 font-medium">
                    Rebuild the image to get the latest versions.
                  </p>
                )}
              </AlertDescription>
            </Alert>

            <div className="flex gap-2">
              <Button
                onClick={handleBuild}
                disabled={building}
                variant="outline"
                className="flex-1 border-border"
              >
                {building ? (
                  <>
                    <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                    Rebuilding...
                  </>
                ) : (
                  'Rebuild Image'
                )}
              </Button>
              {buildOutput && !showOutput && (
                <Button
                  onClick={() => setShowOutput(true)}
                  variant="ghost"
                >
                  Show Output
                </Button>
              )}
            </div>
          </div>
        ) : (
          <div className="space-y-4">
            <p className="text-[13px] text-muted-foreground">
              The inst-cli tool is required for Canvas development. This will build a Docker image
              containing all necessary tools and dependencies.
            </p>

            <Alert>
              <AlertCircle className="h-5 w-5" />
              <AlertDescription>
                <p className="font-medium mb-1">Build Requirements</p>
                <ul className="text-xs space-y-1 list-disc list-inside">
                  <li>Docker must be running</li>
                  <li>Artifactory credentials must be configured</li>
                  <li>Build process may take a few minutes</li>
                </ul>
              </AlertDescription>
            </Alert>

            <div className="space-y-2">
              <Button
                onClick={handleBuild}
                disabled={building}
                className="w-full bg-[#007AFF] hover:bg-[#0066DD]"
              >
                {building ? (
                  <>
                    <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                    Building Image...
                  </>
                ) : (
                  'Build inst-cli Image'
                )}
              </Button>
              {buildOutput && !showOutput && (
                <Button
                  onClick={() => setShowOutput(true)}
                  variant="ghost"
                  className="w-full"
                >
                  Show Build Output
                </Button>
              )}
            </div>
          </div>
        )}
      </Card>

      {showOutput && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <h4 className="text-sm font-semibold text-foreground">Build Output</h4>
            <div className="flex items-center gap-1">
              <button
                onClick={() => { navigator.clipboard.writeText(buildOutput); setCopiedOutput('build'); setTimeout(() => setCopiedOutput(null), 2000); }}
                className="p-1 hover:bg-secondary rounded"
                title="Copy output"
              >
                {copiedOutput === 'build' ? <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={() => setShowOutput(false)}
                variant="ghost"
                size="sm"
                disabled={building}
              >
                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' }}
          >
            {buildOutput || 'Waiting for output...'}
            <div ref={outputEndRef} />
          </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">
                  Build fails with disk space error
                </p>
                <p>
                  If the build fails due to insufficient disk space:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Free up disk space (at least 20GB recommended)</li>
                  <li className="flex items-start gap-2">
                    <span className="flex-1">
                      Clean up unused Docker images:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          docker system prune -a
                        </code>
                        <button
                          onClick={() => handleCopyCode('docker system prune -a', 'docker-prune')}
                          className="p-1 hover:bg-secondary rounded"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'docker-prune' ? (
                            <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>
                  <li>Increase Docker Desktop disk image size in Settings</li>
                </ul>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Build is very slow or times out
                </p>
                <p>
                  The inst-cli build can take 15-30 minutes depending on your system:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Ensure Docker Desktop has sufficient resources (CPU: 4+, Memory: 8GB+)</li>
                  <li>Check your network connection for downloading dependencies</li>
                  <li>Let the build complete - it may appear stuck but is working</li>
                </ul>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Clearing old inst-cli images
                </p>
                <p>
                  To remove old inst-cli images and rebuild:
                </p>
                <div className="flex items-center gap-2">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    docker rmi inst-cli
                  </code>
                  <button
                    onClick={() => handleCopyCode('docker rmi inst-cli', 'docker-rmi')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'docker-rmi' ? (
                      <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">
                  Then click the "Build inst-cli" button again.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Checking if inst-cli image exists
                </p>
                <p>
                  To manually verify the inst-cli image:
                </p>
                <div className="flex items-center gap-2">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    docker images | grep inst-cli
                  </code>
                  <button
                    onClick={() => handleCopyCode('docker images | grep inst-cli', 'docker-images-grep')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'docker-images-grep' ? (
                      <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>
  );
};
