import { useState, useEffect, useCallback, useMemo } from 'react';
import { Alert, AlertDescription, AlertTitle } from './ui/alert';
import { AlertCircle, Loader2, Search } from 'lucide-react';
import { PackageCard } from './PackageCard';
import { PackageFilters } from './PackageFilters';
import { DeactivateWarningDialog } from './DeactivateWarningDialog';
import type { DeactivateWarning } from './DeactivateWarningDialog';
import {
  getAvailablePackages,
  installPackage,
  updatePackage,
  uninstallPackage,
  activatePackage,
  deactivatePackage,
} from '../services/packages';
import { getIntegrations } from '../services/integrations';
import { ConnectionManagerDialog } from './ConnectionManagerDialog';
import type { PackageWithStatus } from '../types/package';
import type { Integration } from '../types/integration';
import { ApiRequestError } from '../types/api';
import { __ } from '@/lib/i18n';
import { useCapabilities } from '@/hooks/useCapabilities';

export default function ProIntegrations() {
  const [packages, setPackages] = useState<PackageWithStatus[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [categoryFilter, setCategoryFilter] = useState('all');
  const [statusFilter, setStatusFilter] = useState('all');
  const [actionInProgress, setActionInProgress] = useState<string | null>(null);
  const [actionType, setActionType] = useState<'update' | 'activate' | 'deactivate' | 'install' | 'uninstall' | null>(null);
  const [deactivateWarning, setDeactivateWarning] = useState<DeactivateWarning | null>(null);

  // Integrations (for connection status)
  const [integrations, setIntegrations] = useState<Integration[]>([]);
  const [connectionDialogOpen, setConnectionDialogOpen] = useState(false);
  const [connectionDialogIntegration, setConnectionDialogIntegration] = useState<Integration | null>(null);

  const { licenseActive } = useCapabilities();

  const fetchPackages = useCallback(async () => {
    try {
      setError(null);
      const pkgs = await getAvailablePackages();
      setPackages(pkgs);
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to load packages'));
    } finally {
      setLoading(false);
    }
  }, []);

  const fetchIntegrations = useCallback(async () => {
    try {
      const data = await getIntegrations();
      setIntegrations(data);
    } catch {
      // Non-critical — Connect buttons just won't appear
    }
  }, []);

  useEffect(() => {
    fetchPackages();
    fetchIntegrations();
  }, [fetchPackages, fetchIntegrations]);

  // Map integrations by slug for quick lookup
  const integrationMap = useMemo(() => {
    const map = new Map<string, Integration>();
    for (const i of integrations) {
      map.set(i.slug, i);
    }
    return map;
  }, [integrations]);

  // Extract unique sorted categories from package data
  const categories = useMemo(
    () => [...new Set(packages.map((p) => p.category))].sort(),
    [packages],
  );

  // Derive status counts from package data
  const statusCounts = useMemo(
    () => ({
      all: packages.length,
      installed: packages.filter((p) => p.status !== 'not_installed').length,
      active: packages.filter((p) => p.is_active).length,
      updates: packages.filter((p) => p.status === 'update_available').length,
    }),
    [packages],
  );

  // Filter packages by search query, category, and status
  const filteredPackages = useMemo(() => {
    return packages.filter((pkg) => {
      // Search filter
      const query = searchQuery.toLowerCase();
      const matchesSearch =
        !searchQuery ||
        pkg.name.toLowerCase().includes(query) ||
        pkg.description.toLowerCase().includes(query) ||
        pkg.category.toLowerCase().includes(query);

      // Category filter
      const matchesCategory = categoryFilter === 'all' || pkg.category === categoryFilter;

      // Status filter
      let matchesStatus = true;
      if (statusFilter === 'installed') {
        matchesStatus = pkg.status !== 'not_installed';
      } else if (statusFilter === 'active') {
        matchesStatus = pkg.is_active === true;
      } else if (statusFilter === 'updates') {
        matchesStatus = pkg.status === 'update_available';
      }

      return matchesSearch && matchesCategory && matchesStatus;
    });
  }, [packages, searchQuery, categoryFilter, statusFilter]);

  function hasCredentials(integration: Integration): boolean {
    return Object.keys(integration.credentials ?? {}).length > 0;
  }

  function handleConnect(slug: string) {
    const integration = integrationMap.get(slug);
    if (integration) {
      setConnectionDialogIntegration(integration);
      setConnectionDialogOpen(true);
    }
  }

  async function handleInstall(slug: string) {
    try {
      setActionInProgress(slug);
      setActionType('install');
      setError(null);
      await installPackage(slug);
      await Promise.all([fetchPackages(), fetchIntegrations()]);
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to install package'));
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  async function handleActivate(slug: string) {
    try {
      setActionInProgress(slug);
      setActionType('activate');
      setError(null);
      await activatePackage(slug);
      await Promise.all([fetchPackages(), fetchIntegrations()]);
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to activate package'));
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  async function handleDeactivate(slug: string) {
    try {
      setActionInProgress(slug);
      setActionType('deactivate');
      setError(null);
      await deactivatePackage(slug);
      await Promise.all([fetchPackages(), fetchIntegrations()]);
    } catch (err) {
      if (
        err instanceof ApiRequestError &&
        err.code === 'workflows_affected' &&
        err.data?.affected_workflows
      ) {
        const pkg = packages.find((p) => p.slug === slug);
        setDeactivateWarning({
          slug,
          packageName: pkg?.name ?? slug,
          workflows: err.data.affected_workflows as Array<{ id: number; name: string }>,
          message: err.message,
        });
      } else {
        setError(err instanceof Error ? err.message : __('Failed to deactivate package'));
      }
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  async function handleConfirmDeactivate() {
    if (!deactivateWarning) return;
    const { slug } = deactivateWarning;
    setDeactivateWarning(null);
    try {
      setActionInProgress(slug);
      setActionType('deactivate');
      setError(null);
      await deactivatePackage(slug, { confirmDeactivateWorkflows: true });
      await Promise.all([fetchPackages(), fetchIntegrations()]);
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to deactivate package'));
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  async function handleUninstall(slug: string) {
    try {
      setActionInProgress(slug);
      setActionType('uninstall');
      setError(null);
      await uninstallPackage(slug);
      // Update local state instead of re-fetching from API.
      // A full re-fetch may lose the card if the marketplace API
      // doesn't return this package (dev packages, API downtime).
      setPackages((prev) =>
        prev.map((pkg) =>
          pkg.slug === slug
            ? { ...pkg, status: 'not_installed' as const, installed_version: undefined, is_active: null }
            : pkg,
        ),
      );
      await fetchIntegrations();
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to uninstall package'));
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  async function handleUpdate(slug: string) {
    try {
      setActionInProgress(slug);
      setActionType('update');
      setError(null);
      await updatePackage(slug);
      await Promise.all([fetchPackages(), fetchIntegrations()]);
    } catch (err) {
      setError(err instanceof Error ? err.message : __('Failed to update package'));
    } finally {
      setActionInProgress(null);
      setActionType(null);
    }
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center py-12">
        <Loader2 className="h-8 w-8 animate-spin text-cyan-600" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h1 className="seq-page-title">{__('Integrations')}</h1>
        <p className="seq-body mt-1">
          {__('Browse and manage integration packages from the marketplace.')}
        </p>
      </div>

      {/* Error */}
      {error && (
        <Alert className="bg-error-muted border-error">
          <AlertCircle className="h-4 w-4 text-error" />
          <AlertTitle className="text-slate-900">{__('Error')}</AlertTitle>
          <AlertDescription className="text-slate-500">{error}</AlertDescription>
        </Alert>
      )}

      {/* Search, Status and Category Filters */}
      <PackageFilters
        searchQuery={searchQuery}
        onSearchChange={setSearchQuery}
        categories={categories}
        categoryFilter={categoryFilter}
        onCategoryChange={setCategoryFilter}
        statusFilter={statusFilter}
        onStatusChange={setStatusFilter}
        statusOptions={[
          { value: 'all', label: __('All'), count: statusCounts.all },
          { value: 'installed', label: __('Installed'), count: statusCounts.installed },
          { value: 'active', label: __('Active'), count: statusCounts.active },
          { value: 'updates', label: __('Updates Available'), count: statusCounts.updates },
        ]}
      />

      {/* Package Grid */}
      {filteredPackages.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-16">
          <div className="w-14 h-14 rounded-2xl bg-slate-100 flex items-center justify-center mb-4">
            <Search className="h-6 w-6 text-slate-400" />
          </div>
          <p className="text-slate-600 font-medium">{__('No packages found')}</p>
          <p className="text-sm text-slate-400 mt-1">
            {__('Try adjusting your search or filters')}
          </p>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {filteredPackages.map((pkg) => {
            const integration = integrationMap.get(pkg.slug);
            const showConnect = integration && hasCredentials(integration);
            return (
              <PackageCard
                key={pkg.slug}
                package={pkg}
                showInstall
                showUninstall
                onActivate={handleActivate}
                onDeactivate={handleDeactivate}
                onInstall={handleInstall}
                onUninstall={handleUninstall}
                onUpdate={handleUpdate}
                onConnect={showConnect ? handleConnect : undefined}
                connectionStatus={integration?.connected ? 'connected' : 'not_connected'}
                actionInProgress={actionInProgress}
                actionTypeInProgress={actionType}
                installDisabled={!licenseActive}
                installDisabledReason={__('Active license required')}
              />
            );
          })}
        </div>
      )}

      {/* Deactivation Warning Dialog */}
      <DeactivateWarningDialog
        warning={deactivateWarning}
        onConfirm={handleConfirmDeactivate}
        onCancel={() => setDeactivateWarning(null)}
      />

      {/* Connection Manager Dialog */}
      <ConnectionManagerDialog
        open={connectionDialogOpen}
        onOpenChange={setConnectionDialogOpen}
        integration={connectionDialogIntegration}
        onConnectionsChange={fetchIntegrations}
      />
    </div>
  );
}
