import { useState, useEffect } from "react";
import { invoke } from "@tauri-apps/api/core";
import { open } from "@tauri-apps/plugin-dialog";
import { listen, UnlistenFn } from "@tauri-apps/api/event";
import "./App.css";

type ServerType =
  | 'Paper'
  | 'Spigot'
  | 'Bukkit'
  | 'Vanilla'
  | 'Forge'
  | 'Fabric'
  | 'Velocity'
  | 'BungeeCord'
  | 'Waterfall'
  | 'Unknown';

interface ServerInfo {
  server_type: ServerType;
  minecraft_version?: string;
  plugins_directory: string;
  plugins_count: number;
}

interface Plugin {
  name: string;
  version: string;
  latest_version?: string;
  description?: string;
  authors: string[];
  has_update: boolean;
  api_version?: string;
  main_class?: string;
  depend?: string[] | null;
  soft_depend?: string[] | null;
  load_before?: string[] | null;
  commands?: any;
  permissions?: any;
  file_path: string;
  file_hash: string;
}

interface ScanResult {
  server_info: ServerInfo;
  plugins: Plugin[];
}

interface ScanProgress {
  processed: number;
  total: number;
  current_file: string;
}

interface PluginDetailsProps {
  plugin: Plugin;
  onClose: () => void;
}

// Get server type icon
function getServerTypeIcon(serverType: ServerType): string {
  switch (serverType) {
    case 'Paper':
      return '📄';
    case 'Spigot':
      return '🔌';
    case 'Bukkit':
      return '🪣';
    case 'Vanilla':
      return '🧊';
    case 'Forge':
      return '🔨';
    case 'Fabric':
      return '🧵';
    case 'Velocity':
      return '⚡';
    case 'BungeeCord':
      return '🔗';
    case 'Waterfall':
      return '🌊';
    default:
      return '❓';
  }
}

// Get a formatted server type name for display
function getServerTypeName(serverType: ServerType): string {
  return serverType === 'Unknown' ? 'Unknown Server' : serverType;
}

function PluginDetails({ plugin, onClose }: PluginDetailsProps) {
  return (
    <div className="plugin-details-modal">
      <div className="plugin-details-content">
        <button className="close-button" onClick={onClose}>&times;</button>
        <h2>{plugin.name}</h2>
        <div className="plugin-version-display">Version: {plugin.version}</div>

        {plugin.description && (
          <div className="plugin-description">{plugin.description}</div>
        )}

        {plugin.authors && plugin.authors.length > 0 && (
          <div className="plugin-authors">
            <div className="section-label">Authors:</div>
            <div>{plugin.authors.join(", ")}</div>
          </div>
        )}

        {plugin.depend && plugin.depend.length > 0 && (
          <div className="plugin-dependencies">
            <div className="section-label">Dependencies:</div>
            <div>{plugin.depend.join(", ")}</div>
          </div>
        )}

        {plugin.soft_depend && plugin.soft_depend.length > 0 && (
          <div className="plugin-soft-dependencies">
            <div className="section-label">Soft Dependencies:</div>
            <div>{plugin.soft_depend.join(", ")}</div>
          </div>
        )}

        <div className="plugin-file-info">
          <div className="section-label">File Path:</div>
          <div className="file-path">{plugin.file_path}</div>

          <div className="section-label">File Hash (SHA-256):</div>
          <div className="file-hash">{plugin.file_hash}</div>
        </div>
      </div>
    </div>
  );
}

// Add this component after the PluginDetails component and before the App component
function ServerInfoDisplay({ serverInfo }: { serverInfo: ServerInfo | null }) {
  if (!serverInfo) return null;

  return (
    <div className="server-info">
      <h2>Server Information</h2>
      <div className="server-type">
        <span className="server-icon">{getServerTypeIcon(serverInfo.server_type)}</span>
        <span className="server-type-name">{getServerTypeName(serverInfo.server_type)}</span>
      </div>
      <div className="minecraft-version">
        <span className="version-label">Minecraft Version</span>
        <span className="version-value">{serverInfo.minecraft_version || "Unknown"}</span>
      </div>
      <div className="plugins-path">
        <span className="path-label">Plugins Directory</span>
        <span className="path-value">{serverInfo.plugins_directory || "Unknown"}</span>
      </div>
      <div className="plugins-count">
        <b>{serverInfo.plugins_count}</b> plugins found
      </div>
    </div>
  );
}

function App() {
  const [serverPath, setServerPath] = useState("");
  const [serverInfo, setServerInfo] = useState<ServerInfo | null>(null);
  const [plugins, setPlugins] = useState<Plugin[]>([]);
  const [isScanning, setIsScanning] = useState(false);
  const [scanComplete, setScanComplete] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedPlugin, setSelectedPlugin] = useState<Plugin | null>(null);
  const [scanProgress, setScanProgress] = useState<ScanProgress | null>(null);

  useEffect(() => {
    let unlistenProgress: UnlistenFn | undefined;
    let unlistenComplete: UnlistenFn | undefined;
    let unlistenError: UnlistenFn | undefined;

    const setupListeners = async () => {
      unlistenProgress = await listen<ScanProgress>("scan_progress", (event) => {
        setScanProgress(event.payload);
        setError(null);
      });

      unlistenComplete = await listen<ScanResult>("scan_complete", (event) => {
        setServerInfo(event.payload.server_info);
        setPlugins(event.payload.plugins);
        setIsScanning(false);
        setScanComplete(true);
        setScanProgress(null);
        setError(null);
      });

      unlistenError = await listen<string>("scan_error", (event) => {
        console.error("Scan Error:", event.payload);
        setError(event.payload);
        setIsScanning(false);
        setScanProgress(null);
        setScanComplete(false);
      });
    };

    setupListeners();

    return () => {
      unlistenProgress?.();
      unlistenComplete?.();
      unlistenError?.();
    };
  }, []);

  async function selectDirectory() {
    try {
      const selected = await open({
        directory: true,
        multiple: false,
        title: 'Select Minecraft Server Directory'
      });

      if (selected !== null) {
        if (typeof selected === 'string') {
          setServerPath(selected);
          setError(null);
        } else if (Array.isArray(selected)) {
          const selectedArr = selected as string[];
          if (selectedArr.length > 0) {
            setServerPath(selectedArr[0]);
            setError(null);
          }
        }
      }
    } catch (err) {
      console.error('Failed to open directory:', err);
      setError("Failed to open directory selector. Please enter path manually.");
    }
  }

  async function scanForPlugins() {
    if (!serverPath || isScanning) return;

    try {
      setIsScanning(true);
      setScanComplete(false);
      setPlugins([]);
      setServerInfo(null);
      setScanProgress(null);
      setError(null);

      await invoke("scan_server_directory", { path: serverPath });

    } catch (err) {
      console.error("Error invoking scan command:", err);
      setError(`Failed to start scan: ${err as string}`);
      setIsScanning(false);
    }
  }

  const showPluginDetails = (plugin: Plugin) => {
    setSelectedPlugin(plugin);
  };

  const closePluginDetails = () => {
    setSelectedPlugin(null);
  };

  return (
    <div className="app-container">
      <header className="app-header">
        <h1>🔧 PlugSnatcher</h1>
        <p>Minecraft Plugin Manager</p>
      </header>

      <main className="app-content">
        <section className="server-selector">
          <h2>Select Server Directory</h2>
          <div className="input-group">
            <input
              type="text"
              value={serverPath}
              onChange={(e) => setServerPath(e.target.value)}
              placeholder="Enter server directory path..."
            />
            <button onClick={selectDirectory}>Browse</button>
          </div>
          <button
            className="scan-button"
            onClick={scanForPlugins}
            disabled={isScanning || !serverPath}
          >
            {isScanning ? "Scanning..." : "Scan for Plugins"}
          </button>

          {isScanning && scanProgress && (
            <div className="scan-progress">
              <p>Scanning: {scanProgress.current_file}</p>
              <progress value={scanProgress.processed} max={scanProgress.total}></progress>
              <span>{scanProgress.processed} / {scanProgress.total}</span>
            </div>
          )}

          {error && (
            <div className="error-message">
              {error}
            </div>
          )}
        </section>

        {scanComplete && serverInfo && (
          <ServerInfoDisplay serverInfo={serverInfo} />
        )}

        {scanComplete && (
          <section className="plugins-list">
            <h2>Installed Plugins ({plugins.length})</h2>
            {plugins.length > 0 ? (
              <>
                <div className="plugins-header">
                  <span>Name</span>
                  <span>Current Version</span>
                  <span>Latest Version</span>
                  <span>Actions</span>
                </div>
                {plugins.map((plugin, index) => (
                  <div key={index} className={`plugin-item ${plugin.has_update ? 'has-update' : ''}`}>
                    <div className="plugin-name">{plugin.name}</div>
                    <div className="plugin-version">{plugin.version}</div>
                    <div className="plugin-latest-version">{plugin.latest_version || 'Unknown'}</div>
                    <div className="plugin-actions">
                      {plugin.has_update && (
                        <button className="update-button">Update</button>
                      )}
                      <button className="info-button" onClick={() => showPluginDetails(plugin)}>Info</button>
                    </div>
                  </div>
                ))}
              </>
            ) : (
              <p>No plugins found in this directory.</p>
            )}
          </section>
        )}

        {selectedPlugin && (
          <PluginDetails plugin={selectedPlugin} onClose={closePluginDetails} />
        )}
      </main>

      <footer className="app-footer">
        <p>PlugSnatcher v0.1.0 - Developed with 💻 and ☕</p>
      </footer>
    </div>
  );
}

export default App;
