import React, { useState, useEffect } from 'react';
import { RefreshCw, ChevronDown, ChevronUp, Terminal, Copy, Check } from 'lucide-react';
import { FrpcStatus, 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 { InstallResultMessage } from '../../settings/components/InstallResultMessage';
import { StatusBadge } from '../../settings/components/StatusBadge';
import frpcIcon from '../../assets/frpc-icon.png';

export const FrpcSetupStep: React.FC = () => {
  const { refreshStepStatus, refreshTrigger, scrollToTop, setStepWorking } = useSetupWizard();
  const [frpcStatus, setFrpcStatus] = useState<FrpcStatus>({
    installed: false,
    version: null,
    path: null,
    updateAvailable: false,
    latestVersion: null
  });
  const [installing, setInstalling] = useState(false);
  const [updating, setUpdating] = useState(false);
  const [reinstalling, setReinstalling] = useState(false);
  const [uninstalling, setUninstalling] = 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 [uninstallOutput, setUninstallOutput] = useState<string>('');
  const [showUninstallOutput, setShowUninstallOutput] = 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 status = await window.setupWizardAPI.getFrpcStatus(forceRefresh);
      setFrpcStatus(status);

      // Refresh validation status
      await refreshStepStatus('frpc-setup');
    } catch (error) {
      console.error('Failed to check FRPC 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 handleInstall = async () => {
    setStepWorking('frpc-setup', true);
    setInstalling(true);
    setInstallResult(null);
    setInstallOutput('');
    setShowInstallOutput(true);

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

    try {
      const result = await window.setupWizardAPI.installFrpc();
      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 FRPC'
      });
    } finally {
      setInstalling(false);
      setStepWorking('frpc-setup', false);
      cleanup();
    }
  };

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

    const cleanup = window.setupWizardAPI.onUpdateFrpcOutput((output) => {
      setUpdateOutput((prev) => prev + output);
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    try {
      const result = await window.setupWizardAPI.updateFrpc();
      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 FRPC'
      });
    } finally {
      setUpdating(false);
      setStepWorking('frpc-setup', false);
      cleanup();
    }
  };

  const handleReinstall = async () => {
    const confirmed = window.confirm(
      'FRPC will be uninstalled and reinstalled.\n\n' +
      'This process may take a few minutes. Continue?'
    );

    if (!confirmed) {
      return;
    }

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

    const cleanup = window.setupWizardAPI.onReinstallFrpcOutput((output) => {
      setReinstallOutput((prev) => prev + output);
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    try {
      const result = await window.setupWizardAPI.reinstallFrpc();
      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 FRPC'
      });
    } finally {
      setReinstalling(false);
      setStepWorking('frpc-setup', false);
      cleanup();
    }
  };

  const handleUninstall = async () => {
    const confirmed = window.confirm(
      'FRPC will be uninstalled from your system.\\n\\n' +
      'This will remove FRPC installed via Homebrew. Continue?'
    );

    if (!confirmed) {
      return;
    }

    setStepWorking('frpc-setup', true);
    setUninstalling(true);
    setInstallResult(null);
    setUninstallOutput('');
    setShowUninstallOutput(true);

    const cleanup = window.setupWizardAPI.onUninstallFrpcOutput((output) => {
      setUninstallOutput((prev) => prev + output);
      setTimeout(() => {
        outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 100);
    });

    try {
      const result = await window.setupWizardAPI.uninstallFrpc();
      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 uninstall FRPC'
      });
    } finally {
      setUninstalling(false);
      setStepWorking('frpc-setup', false);
      cleanup();
    }
  };

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

  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">
            Install FRPC (Fast Reverse Proxy Client)
          </p>
          <Button
            onClick={handleRefresh}
            disabled={refreshing || installing || updating || reinstalling || uninstalling}
            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 FRPC?
                </p>
                <p>
                  FRPC (Fast Reverse Proxy Client) is a tool that allows external services to access your local Canvas development environment. It creates a secure tunnel from your local machine to the internet.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Why is it needed?
                </p>
                <p>
                  Some Canvas features require external services (like LTI tools) to reach your development environment. FRPC makes your local Canvas accessible from the internet for testing these integrations.
                </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 FRPC is installed via Homebrew</li>
                  <li>Displays the installed FRPC version</li>
                  <li>Checks for available updates</li>
                  <li>Provides options to install, update, or reinstall FRPC</li>
                  <li>Verifies FRPC is working correctly</li>
                </ul>
              </div>
            </div>
          )}
        </div>
      </Card>

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

      {/* FRPC Status Card */}
      <Card className="p-5">
        <div className="flex items-center gap-3 mb-4">
          <div className="w-10 h-10 rounded-lg overflow-hidden flex-shrink-0">
            <img
              src={frpcIcon}
              alt="FRPC"
              className="w-full h-full object-cover"
            />
          </div>
          <div>
            <h3 className="text-[15px] font-semibold text-foreground">
              FRPC
            </h3>
            <StatusBadge installed={frpcStatus.installed} />
          </div>
        </div>

        {frpcStatus.installed && frpcStatus.version && (
          <div className="mb-4 text-sm">
            <span className="text-muted-foreground">Version: </span>
            <span
              className="font-medium"
              style={{
                color: frpcStatus.updateAvailable ? '#f97316' : '#10b981'
              }}
            >
              {frpcStatus.version}
              {frpcStatus.updateAvailable && frpcStatus.latestVersion
                ? ` (Latest: ${frpcStatus.latestVersion})`
                : frpcStatus.updateAvailable
                ? ' (Update available)'
                : ' (Latest)'}
            </span>
          </div>
        )}

        <div className="space-y-3">
          {!frpcStatus.installed ? (
            <Button
              onClick={handleInstall}
              disabled={installing}
              className="w-full"
            >
              {installing ? 'Installing...' : 'Install FRPC'}
            </Button>
          ) : (
            <div className="space-y-2">
              {frpcStatus.updateAvailable && (
                <Button
                  onClick={handleUpdate}
                  disabled={updating}
                  className="w-full"
                  variant="default"
                >
                  {updating ? 'Updating...' : 'Update FRPC'}
                </Button>
              )}
              <Button
                onClick={handleReinstall}
                disabled={reinstalling}
                className="w-full"
                variant="outline"
              >
                {reinstalling ? 'Reinstalling...' : 'Reinstall FRPC'}
              </Button>
              <Button
                onClick={handleUninstall}
                disabled={uninstalling}
                className="w-full"
                variant="outline"
              >
                {uninstalling ? 'Uninstalling...' : 'Uninstall FRPC'}
              </Button>
            </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">
                  About FRPC
                </p>
                <p>
                  FRPC (Fast Reverse Proxy Client) is a tool for exposing local servers behind NATs or firewalls to the internet.
                  It's commonly used for development and testing purposes.
                </p>
              </div>

              <div className="space-y-2">
                <p className="font-medium text-foreground">
                  Installing FRPC 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:
                      <div className="mt-1 flex items-center gap-2">
                        <code className="px-2 py-1 rounded text-xs bg-secondary text-foreground flex-1">
                          brew install frpc
                        </code>
                        <button
                          onClick={() => handleCopyCode('brew install frpc', 'frpc-install')}
                          className="p-1 hover:bg-secondary rounded flex-shrink-0"
                          title="Copy to clipboard"
                        >
                          {copiedCode === 'frpc-install' ? (
                            <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>
          )}
        </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>
      )}

      {showUninstallOutput && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <h4 className="text-sm font-semibold text-foreground">
              Uninstall Output
            </h4>
            <div className="flex items-center gap-1">
              <button
                onClick={() => { navigator.clipboard.writeText(uninstallOutput); setCopiedOutput('uninstall'); setTimeout(() => setCopiedOutput(null), 2000); }}
                className="p-1 hover:bg-secondary rounded"
                title="Copy output"
              >
                {copiedOutput === 'uninstall' ? <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={() => setShowUninstallOutput(false)}
                variant="ghost"
                size="sm"
                disabled={uninstalling}
              >
                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' }}
          >
            {uninstallOutput || 'Waiting for output...'}
            <div ref={outputEndRef} />
          </div>
        </Card>
      )}
    </div>
  );
};
