import React, { useState, useEffect } from 'react';
import { Box, IconButton, Spinner, Text, Menu, PopOut, Button, config } from 'folds';
import * as css from './UpdateNotification.css';

interface UpdateInfo {
  version: string;
  releaseNotes?: string;
  releaseDate?: string;
}

interface DownloadProgress {
  percent: number;
  transferred: number;
  total: number;
}

export function UpdateNotification() {
  const [updateAvailable, setUpdateAvailable] = useState(false);
  const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);
  const [downloading, setDownloading] = useState(false);
  const [downloadProgress, setDownloadProgress] = useState(0);
  const [updateReady, setUpdateReady] = useState(false);
  const [checking, setChecking] = useState(false);
  const [menuAnchor, setMenuAnchor] = useState<{ x: number; y: number; width: number; height: number } | undefined>(undefined);

  useEffect(() => {
    // Check if we're in Electron environment
    if (typeof window === 'undefined' || !(window as any).electron?.updater) {
      return;
    }

    const { updater } = (window as any).electron;

    // Listen for update available
    updater.onUpdateAvailable((info: UpdateInfo) => {
      console.log('Update available:', info.version);
      setUpdateAvailable(true);
      setUpdateInfo(info);
      setDownloading(false);
      setUpdateReady(false);
      setChecking(false);
    });

    // Listen for download progress
    updater.onUpdateDownloadProgress((progress: DownloadProgress) => {
      setDownloadProgress(Math.round(progress.percent));
    });

    // Listen for update downloaded
    updater.onUpdateDownloaded((info: UpdateInfo) => {
      console.log('Update downloaded:', info.version);
      setDownloading(false);
      setUpdateReady(true);
    });

    // Cleanup - IPC listeners don't need manual cleanup in this case
  }, []);

  const handleCheckForUpdates = async () => {
    setChecking(true);
    try {
      const result = await (window as any).electron.updater.checkForUpdates();
      console.log('Update check result:', result);
      // If no update found, show feedback
      setTimeout(() => {
        if (!updateAvailable) {
          setChecking(false);
        }
      }, 2000);
    } catch (error) {
      console.error('Failed to check for updates:', error);
      setChecking(false);
    }
  };

  const handleDownload = async () => {
    setDownloading(true);
    setDownloadProgress(0);
    try {
      await (window as any).electron.updater.downloadUpdate();
    } catch (error) {
      console.error('Failed to download update:', error);
      setDownloading(false);
    }
    setMenuAnchor(undefined);
  };

  const handleInstall = async () => {
    try {
      await (window as any).electron.updater.installUpdate();
    } catch (error) {
      console.error('Failed to install update:', error);
    }
  };

  const handleMenuToggle = (event: React.MouseEvent<HTMLButtonElement>) => {
    if (menuAnchor) {
      setMenuAnchor(undefined);
    } else {
      const rect = event.currentTarget.getBoundingClientRect();
      setMenuAnchor({ x: rect.x, y: rect.y, width: rect.width, height: rect.height });
    }
  };

  // Don't render anything if not in Electron
  if (typeof window === 'undefined' || !(window as any).electron?.updater) {
    return null;
  }

  // Show check button if no update status
  if (!updateAvailable && !updateReady && !checking) {
    return (
      <Box gap="100" alignItems="Center">
        <button
          className={css.CheckButton}
          onClick={handleCheckForUpdates}
          aria-label="Check for updates"
          title="Check for updates"
          type="button"
        >
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
            <path
              d="M8 2V10M8 10L5 7M8 10L11 7"
              stroke="currentColor"
              strokeWidth="1.5"
              strokeLinecap="round"
              strokeLinejoin="round"
            />
            <path
              d="M3 14H13"
              stroke="currentColor"
              strokeWidth="1.5"
              strokeLinecap="round"
            />
          </svg>
        </button>
      </Box>
    );
  }

  // Show checking state
  if (checking) {
    return (
      <Box gap="100" alignItems="Center">
        <button className={css.UpdateButton} disabled type="button">
          <Spinner variant="Secondary" size="50" />
        </button>
      </Box>
    );
  }

  // Show update available/ready state
  if (!updateAvailable && !updateReady) {
    return null;
  }

  return (
    <Box gap="100" alignItems="Center">
      <button
        className={css.UpdateButton}
        onClick={handleMenuToggle}
        aria-label={updateReady ? 'Update ready' : 'Update available'}
        title={updateReady ? 'Update downloaded - click to install' : 'New version available'}
        type="button"
      >
        {downloading ? (
          <Box alignItems="Center" gap="100">
            <Spinner variant="Secondary" size="50" />
            {downloadProgress > 0 && (
              <Text size="T200" className={css.ProgressText}>
                {downloadProgress}%
              </Text>
            )}
          </Box>
        ) : (
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
            <path
              d="M8 2V10M8 10L5 7M8 10L11 7"
              stroke="currentColor"
              strokeWidth="1.5"
              strokeLinecap="round"
              strokeLinejoin="round"
            />
            <path
              d="M3 14H13"
              stroke="currentColor"
              strokeWidth="1.5"
              strokeLinecap="round"
            />
          </svg>
        )}
      </button>

      <PopOut
        anchor={menuAnchor}
        position="Bottom"
        align="End"
        offset={8}
        content={
          <Menu className={css.UpdateMenu}>
            <Box direction="Column" gap="200" style={{ padding: config.space.S300 }}>
              <Box direction="Column" gap="100">
                <Text size="H5" priority="400">
                  {updateReady ? 'Update Ready' : 'Update Available'}
                </Text>
                {updateInfo && (
                  <Text size="T200" priority="300">
                    Version {updateInfo.version}
                  </Text>
                )}
              </Box>
              
              {updateReady ? (
                <Button
                  variant="Primary"
                  size="400"
                  onClick={handleInstall}
                  fill="Solid"
                >
                  <Text size="B400">Install and Restart</Text>
                </Button>
              ) : (
                <Button
                  variant="Primary"
                  size="400"
                  onClick={handleDownload}
                  disabled={downloading}
                  fill="Solid"
                >
                  <Text size="B400">
                    {downloading ? `Downloading ${downloadProgress}%` : 'Download Update'}
                  </Text>
                </Button>
              )}
            </Box>
          </Menu>
        }
      >
        {null}
      </PopOut>
    </Box>
  );
}
