import React, { useState, useEffect, useRef } from 'react';
import { CheckCircle2, AlertCircle, RefreshCw, Play, Trash2, ChevronDown, ChevronUp, Terminal, Copy, Check } from 'lucide-react';
import { BuildRunStatus, 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 { Switch } from '../../components/ui/switch';
import { Label } from '../../components/ui/label';
import buildAndRunIcon from '../../assets/build-and-run.png';

export const BuildRunStep: React.FC = () => {
  const { refreshStepStatus, refreshTrigger, scrollToTop, setStepWorking } = useSetupWizard();
  const [status, setStatus] = useState<BuildRunStatus>({
    instDomain: null,
    canvasUrl: null,
    siteAccessible: false,
    configured: false,
    folderName: null
  });
  const [multiDeploy, setMultiDeploy] = useState(true);
  const [multiDeployLoaded, setMultiDeployLoaded] = useState(false);
  const [buildMode, setBuildMode] = useState<'build' | 'clean' | null>(null);
  const building = buildMode !== null;
  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 terminalRef = useRef<HTMLDivElement>(null);

  const checkStatus = async (forceRefresh = false, multiDeployOverride?: boolean) => {
    try {
      const buildRunStatus = await window.setupWizardAPI.getBuildRunStatus(multiDeployOverride ?? multiDeploy);
      setStatus(buildRunStatus);

      // Refresh validation status
      await refreshStepStatus('build-run');
    } catch (error) {
      console.error('Failed to check build and run status:', error);
    }
  };

  useEffect(() => {
    const loadInitialStatus = async () => {
      const saved = await window.setupWizardAPI.getMultiDeploy();
      setMultiDeploy(saved);
      setMultiDeployLoaded(true);
      await checkStatus(false, saved);
      setRefreshing(false);
    };
    loadInitialStatus();
  }, []);

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

  // Auto-scroll to bottom when output changes
  useEffect(() => {
    if (terminalRef.current) {
      terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
    }
  }, [terminalOutput]);

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

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

  const handleBuildAndRun = async () => {
    setStepWorking('build-run', true);
    setBuildMode('build');
    setResult(null);
    setTerminalOutput('');
    setShowTerminal(true);

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

      if (buildResult.success) {
        scrollToTop();
        setTimeout(() => { checkStatus(true); }, 5000);
      }
    } catch (error: any) {
      setResult({ success: false, message: error.message || 'Failed to build and run' });
    } finally {
      setBuildMode(null);
      setStepWorking('build-run', false);
    }
  };

  const handleCleanBuildAndRun = async () => {
    setStepWorking('build-run', true);
    setBuildMode('clean');
    setResult(null);
    setTerminalOutput('');
    setShowTerminal(true);

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

      if (buildResult.success) {
        scrollToTop();
        setTimeout(() => { checkStatus(true); }, 5000);
      }
    } catch (error: any) {
      setResult({ success: false, message: error.message || 'Failed to clean, build and run' });
    } finally {
      setBuildMode(null);
      setStepWorking('build-run', 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 and Run Canvas
          </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 does "Build and Run" do?
                </p>
                <p>
                  This step builds the Canvas application and starts all required services (web server, database, Redis, etc.) using inst-cli. It executes the full Canvas setup process.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Why is it needed?
                </p>
                <p>
                  Canvas needs its database initialized, assets compiled, and services running before you can access it in your browser. This step automates the entire process.
                </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>Verifies inst_domain is configured in inst.yml</li>
                  <li>Checks if Canvas is already running</li>
                  <li>Executes "inst canvas setup" which:
                    <ul className="list-disc list-inside ml-4 mt-1">
                      <li>Installs Ruby and Node.js dependencies</li>
                      <li>Sets up the PostgreSQL database</li>
                      <li>Runs database migrations</li>
                      <li>Compiles JavaScript and CSS assets</li>
                      <li>Starts all Docker containers</li>
                    </ul>
                  </li>
                  <li>Monitors build progress with real-time terminal output</li>
                  <li>Displays the Canvas URL when ready</li>
                  <li>Provides option to open Canvas in your browser</li>
                </ul>
              </div>
            </div>
          )}
        </div>
      </Card>

      {/* Multi Deployments Toggle */}
      <Card className="px-4 py-3">
        <div className="flex items-center justify-between">
          <div className="space-y-0.5">
            <Label htmlFor="multi-deploy-toggle" className="text-sm font-medium text-foreground cursor-pointer">
              Multi Deployments
            </Label>
            <p className="text-xs text-muted-foreground">
              {multiDeploy
                ? `Canvas URL: http://canvas-web-${status.folderName || '[folder]'}.${status.instDomain || '[domain]'}`
                : `Canvas URL: http://canvas-web.${status.instDomain || '[domain]'}`}
            </p>
          </div>
          <Switch
            id="multi-deploy-toggle"
            checked={multiDeploy}
            disabled={!multiDeployLoaded}
            onCheckedChange={(checked) => {
              setMultiDeploy(checked);
              window.setupWizardAPI.setMultiDeploy(checked);
              checkStatus(false, checked);
            }}
          />
        </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={buildAndRunIcon} alt="Build and Run" className="w-full h-full object-cover" />
            </div>
            <div>
              <h3 className="text-[15px] font-semibold text-foreground">Build and Run Canvas</h3>
              <div className="mt-1">
                {status.configured ? (
                  <Badge variant="success" className="text-xs">
                    <CheckCircle2 className="h-3.5 w-3.5 mr-1" />
                    Running
                  </Badge>
                ) : (
                  <Badge variant="warning" className="text-xs">
                    <AlertCircle className="h-3.5 w-3.5 mr-1" />
                    Not Running
                  </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>

          {/* Canvas URL and accessibility status */}
          {status.canvasUrl && (
            <div className="space-y-2">
              <h4 className="text-sm font-medium text-foreground">
                Canvas Site
              </h4>
              {status.siteAccessible ? (
                <Alert variant="success">
                  <CheckCircle2 className="h-5 w-5" />
                  <AlertDescription>
                    <p className="font-medium mb-1">Canvas is accessible</p>
                    <p className="text-xs">
                      URL: <a href={status.canvasUrl} target="_blank" rel="noopener noreferrer" className="text-green-700 dark:text-green-400 underline">{status.canvasUrl}</a>
                    </p>
                  </AlertDescription>
                </Alert>
              ) : (
                <Alert variant="warning">
                  <AlertCircle className="h-5 w-5" />
                  <AlertDescription>
                    <p className="font-medium mb-1">Canvas site not accessible</p>
                    <p className="text-xs">
                      Expected URL: <code className="bg-yellow-100 dark:bg-yellow-900/30 px-1 rounded">{status.canvasUrl}</code>
                    </p>
                  </AlertDescription>
                </Alert>
              )}
            </div>
          )}

          {/* Build and Run Buttons */}
          <div className="space-y-2">
            <h4 className="text-sm font-medium text-foreground">
              Build and Run
            </h4>
            <div className="flex gap-2">
              <Button
                onClick={handleBuildAndRun}
                disabled={building || !status.instDomain}
                className="flex-1"
                variant={status.configured ? "outline" : "default"}
              >
                {buildMode === 'build' ? (
                  <>
                    <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
                    Building...
                  </>
                ) : (
                  <>
                    <Play className="h-4 w-4 mr-2" />
                    Build and Run
                  </>
                )}
              </Button>
              <Button
                onClick={handleCleanBuildAndRun}
                disabled={building || !status.instDomain}
                className="flex-1"
                variant="outline"
              >
                {buildMode === 'clean' ? (
                  <>
                    <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
                    Cleaning...
                  </>
                ) : (
                  <>
                    <Play className="h-4 w-4 mr-2" />
                    Clean, Build and Run
                  </>
                )}
              </Button>
            </div>
            {!status.instDomain && (
              <p className="text-xs text-orange-600">
                inst_domain is required to build and run
              </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
                ref={terminalRef}
                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 builds and runs Canvas using inst-cli.
            </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>
              {multiDeploy && (
                <li>Runs <code className="bg-muted px-1 rounded">inst canvas multideploy</code> before setup</li>
              )}
              <li>Executes <code className="bg-muted px-1 rounded">inst canvas setup</code> or <code className="bg-muted px-1 rounded">inst canvas clean && inst canvas setup</code></li>
              <li>Validates by checking Canvas at <code className="bg-muted px-1 rounded">
                {multiDeploy
                  ? `http://canvas-web-${status.folderName || '[folder]'}.${status.instDomain || '[domain]'}`
                  : `http://canvas-web.${status.instDomain || '[domain]'}`}
              </code></li>
              <li>This process may take several minutes to complete</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">
                  Build fails with dependency errors
                </p>
                <p>
                  If bundle install or npm install fails:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Verify you have valid Artifactory credentials</li>
                  <li>Check your internet connection</li>
                  <li>Try clearing the build cache and rebuilding</li>
                  <li>Ensure Docker has enough resources (8GB+ memory)</li>
                </ul>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Database migration fails
                </p>
                <p>
                  If database setup or migrations fail:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Check if PostgreSQL container is running</li>
                  <li>Verify database credentials in database.yml</li>
                  <li className="flex items-start gap-2">
                    <span className="flex-1">
                      Try resetting the database:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          inst canvas db-reset
                        </code>
                        <button
                          onClick={() => handleCopyCode('inst canvas db-reset', 'db-reset')}
                          className="p-1 hover:bg-secondary rounded"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'db-reset' ? (
                            <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">
                  Port conflicts
                </p>
                <p>
                  If Canvas won't start due to port in use:
                </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 :3000
                  </code>
                  <button
                    onClick={() => handleCopyCode('lsof -i :3000', 'lsof-3000')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'lsof-3000' ? (
                      <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">
                  Stop any other services using port 3000, or configure Canvas to use a different port.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Asset compilation fails
                </p>
                <p>
                  If JavaScript/CSS compilation fails:
                </p>
                <ul className="list-disc list-inside space-y-1 ml-2">
                  <li>Ensure you have enough disk space (20GB+ free)</li>
                  <li>Increase Docker memory allocation to 10GB+</li>
                  <li className="flex items-start gap-2">
                    <span className="flex-1">
                      Try:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          inst canvas build
                        </code>
                        <button
                          onClick={() => handleCopyCode('inst canvas build', 'canvas-build')}
                          className="p-1 hover:bg-secondary rounded"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'canvas-build' ? (
                            <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 running Canvas setup
                </p>
                <p>
                  To run setup commands manually:
                </p>
                <div className="flex items-center gap-2">
                  <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                    inst canvas setup
                  </code>
                  <button
                    onClick={() => handleCopyCode('inst canvas setup', 'canvas-setup')}
                    className="p-1 hover:bg-secondary rounded"
                    title="Copy to clipboard"
                  >
                    {copiedCode === 'canvas-setup' ? (
                      <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">
                  Or individual steps: <code className="bg-secondary px-1 rounded">inst canvas build</code>, <code className="bg-secondary px-1 rounded">inst canvas db-setup</code>
                </p>
              </div>
            </div>
          )}
        </div>
      </Card>
    </div>
  );
};
