"use client";

import { useAtomValue } from "jotai";
import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react";
import { createPortal } from "react-dom";
import { statusInboxItemsAtom } from "@/atoms/inbox/status-inbox.atom";
import { activeWorkspaceIdAtom } from "@/atoms/workspaces/workspace-query.atoms";
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import { Tabs, TabsContent } from "@/components/ui/tabs";
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import { useConnectorsSync } from "@/hooks/use-connectors-sync";
import { PICKER_CLOSE_EVENT, PICKER_OPEN_EVENT } from "@/hooks/use-google-picker";
import { useZeroDocumentTypeCounts } from "@/hooks/use-zero-document-type-counts";
import { ConnectorDialogHeader } from "./connector-popup/components/connector-dialog-header";
import { ConnectorConnectView } from "./connector-popup/connector-configs/views/connector-connect-view";
import { ConnectorEditView } from "./connector-popup/connector-configs/views/connector-edit-view";
import { IndexingConfigurationView } from "./connector-popup/connector-configs/views/indexing-configuration-view";
import {
	COMPOSIO_CONNECTORS,
	OAUTH_CONNECTORS,
} from "./connector-popup/constants/connector-constants";
import { useConnectorDialog } from "./connector-popup/hooks/use-connector-dialog";
import { useIndexingConnectors } from "./connector-popup/hooks/use-indexing-connectors";
import { ActiveConnectorsTab } from "./connector-popup/tabs/active-connectors-tab";
import { AllConnectorsTab } from "./connector-popup/tabs/all-connectors-tab";
import { ConnectorAccountsListView } from "./connector-popup/views/connector-accounts-list-view";
import { YouTubeCrawlerView } from "./connector-popup/views/youtube-crawler-view";

export interface ConnectorIndicatorHandle {
	open: () => void;
}

interface ConnectorIndicatorProps {
	showTrigger?: boolean;
}

export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, ConnectorIndicatorProps>(
	(_props, ref) => {
		const workspaceId = useAtomValue(activeWorkspaceIdAtom);

		// Real-time document type counts via Zero (updates instantly as docs are indexed)
		const documentTypeCounts = useZeroDocumentTypeCounts(workspaceId);
		// Read status inbox items from shared atom (populated by LayoutDataProvider)
		// instead of creating a duplicate useInbox("status") hook.
		const statusInboxItems = useAtomValue(statusInboxItemsAtom);
		const inboxItems = useMemo(
			() => statusInboxItems.filter((item) => item.type === "connector_indexing"),
			[statusInboxItems]
		);

		// Use the custom hook for dialog state management
		const {
			isOpen,
			activeTab,
			connectingId,
			isScrolled,
			searchQuery,
			indexingConfig,
			indexingConnector,
			indexingConnectorConfig,
			editingConnector,
			connectingConnectorType,
			isCreatingConnector,
			startDate,
			endDate,
			isStartingIndexing,
			isSaving,
			isDisconnecting,
			periodicEnabled,
			frequencyMinutes,
			enableVisionLlm,
			allConnectors,
			viewingAccountsType,
			viewingMCPList,
			isYouTubeView,
			isFromOAuth,
			setSearchQuery,
			setStartDate,
			setEndDate,
			setPeriodicEnabled,
			setFrequencyMinutes,
			setEnableVisionLlm,
			handleOpenChange,
			handleTabChange,
			handleScroll,
			handleConnectOAuth,
			handleConnectNonOAuth,
			handleCreateWebcrawler,
			handleCreateYouTubeCrawler,
			handleSubmitConnectForm,
			handleStartIndexing,
			handleSkipIndexing,
			handleStartEdit,
			handleSaveConnector,
			handleDisconnectConnector,
			handleBackFromEdit,
			handleBackFromConnect,
			handleBackFromYouTube,
			handleViewAccountsList,
			handleBackFromAccountsList,
			handleBackFromMCPList,
			handleAddNewMCPFromList,
			handleQuickIndexConnector,
			connectorConfig,
			setConnectorConfig,
			setIndexingConnectorConfig,
			setConnectorName,
		} = useConnectorDialog();

		const [pickerOpen, setPickerOpen] = useState(false);
		useEffect(() => {
			const onOpen = () => setPickerOpen(true);
			const onClose = () => setPickerOpen(false);
			window.addEventListener(PICKER_OPEN_EVENT, onOpen);
			window.addEventListener(PICKER_CLOSE_EVENT, onClose);
			return () => {
				window.removeEventListener(PICKER_OPEN_EVENT, onOpen);
				window.removeEventListener(PICKER_CLOSE_EVENT, onClose);
			};
		}, []);

		const {
			connectors: connectorsFromSync = [],
			loading: connectorsLoading,
			error: connectorsError,
			refreshConnectors: refreshConnectorsSync,
		} = useConnectorsSync(workspaceId);

		const useSyncData = connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
		const connectors = useSyncData ? connectorsFromSync : allConnectors || [];

		const refreshConnectors = async () => {
			if (useSyncData) {
				await refreshConnectorsSync();
			}
		};

		// Track indexing state locally - clears automatically when last_indexed_at changes via real-time sync
		// Also clears when failed notifications are detected
		const { indexingConnectorIds, startIndexing, stopIndexing } = useIndexingConnectors(
			connectors as SearchSourceConnector[],
			inboxItems
		);

		// Get document types that have documents in the workspace
		const activeDocumentTypes = documentTypeCounts
			? Object.entries(documentTypeCounts).filter(([, count]) => count > 0)
			: [];

		const hasConnectors = connectors.length > 0;
		const hasSources = hasConnectors || activeDocumentTypes.length > 0;
		const totalSourceCount = connectors.length + activeDocumentTypes.length;

		const activeConnectorsCount = connectors.length;

		// Check which connectors are already connected
		// Real-time connector updates via Zero sync
		const connectedTypes = new Set<string>(
			(connectors || []).map((c: SearchSourceConnector) => c.connector_type)
		);

		useImperativeHandle(ref, () => ({
			open: () => handleOpenChange(true),
		}));

		if (!workspaceId) return null;

		return (
			<Dialog open={isOpen} modal={false} onOpenChange={handleOpenChange}>
				{isOpen &&
					createPortal(
						<div
							className="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
							aria-hidden="true"
							onClick={() => {
								if (!pickerOpen) handleOpenChange(false);
							}}
						/>,
						document.body
					)}

				<DialogContent
					onFocusOutside={(e) => e.preventDefault()}
					onInteractOutside={(e) => {
						if (pickerOpen) e.preventDefault();
					}}
					onPointerDownOutside={(e) => {
						if (pickerOpen) e.preventDefault();
					}}
					className="max-w-3xl w-[95vw] sm:w-full h-[75vh] sm:h-[85vh] flex flex-col p-0 gap-0 overflow-hidden ring-0 dark:ring-0 [&>button]:right-4 sm:[&>button]:right-12 [&>button]:top-6 sm:[&>button]:top-10 [&>button]:opacity-80 [&>button]:hover:opacity-100 [&>button]:hover:bg-accent [&>button]:hover:text-accent-foreground [&>button>svg]:size-5 select-none"
				>
					<DialogTitle className="sr-only">Manage External MCP Connectors</DialogTitle>
					{/* YouTube Crawler View - shown when adding YouTube videos */}
					{isYouTubeView && workspaceId ? (
						<YouTubeCrawlerView workspaceId={workspaceId} onBack={handleBackFromYouTube} />
					) : viewingMCPList ? (
						<ConnectorAccountsListView
							connectorType="MCP_CONNECTOR"
							connectorTitle="MCP Connectors"
							connectors={(allConnectors || []) as SearchSourceConnector[]}
							indexingConnectorIds={indexingConnectorIds}
							onBack={handleBackFromMCPList}
							onManage={handleStartEdit}
							onAddAccount={handleAddNewMCPFromList}
							addButtonText="Add New MCP Server"
						/>
					) : viewingAccountsType ? (
						<ConnectorAccountsListView
							connectorType={viewingAccountsType.connectorType}
							connectorTitle={viewingAccountsType.connectorTitle}
							connectors={(connectors || []) as SearchSourceConnector[]}
							indexingConnectorIds={indexingConnectorIds}
							onBack={handleBackFromAccountsList}
							onManage={handleStartEdit}
							onAddAccount={() => {
								// Check both OAUTH_CONNECTORS and COMPOSIO_CONNECTORS
								const oauthConnector =
									OAUTH_CONNECTORS.find(
										(c) => c.connectorType === viewingAccountsType.connectorType
									) ||
									COMPOSIO_CONNECTORS.find(
										(c) => c.connectorType === viewingAccountsType.connectorType
									);
								if (oauthConnector) {
									handleConnectOAuth(oauthConnector);
								}
							}}
							isConnecting={connectingId !== null}
						/>
					) : connectingConnectorType ? (
						<ConnectorConnectView
							connectorType={connectingConnectorType}
							onSubmit={(formData) => handleSubmitConnectForm(formData, startIndexing)}
							onBack={handleBackFromConnect}
							isSubmitting={isCreatingConnector}
						/>
					) : editingConnector ? (
						<ConnectorEditView
							connector={{
								...editingConnector,
								config: connectorConfig || editingConnector.config,
								name: editingConnector.name,
								// Sync last_indexed_at with live data from real-time sync
								last_indexed_at:
									(connectors as SearchSourceConnector[]).find((c) => c.id === editingConnector.id)
										?.last_indexed_at ?? editingConnector.last_indexed_at,
							}}
							startDate={startDate}
							endDate={endDate}
							periodicEnabled={periodicEnabled}
							frequencyMinutes={frequencyMinutes}
							enableVisionLlm={enableVisionLlm}
							isSaving={isSaving}
							isDisconnecting={isDisconnecting}
							isIndexing={indexingConnectorIds.has(editingConnector.id)}
							workspaceId={workspaceId?.toString()}
							onStartDateChange={setStartDate}
							onEndDateChange={setEndDate}
							onPeriodicEnabledChange={setPeriodicEnabled}
							onFrequencyChange={setFrequencyMinutes}
							onEnableVisionLlmChange={setEnableVisionLlm}
							onSave={() => {
								startIndexing(editingConnector.id);
								handleSaveConnector(() => refreshConnectors());
							}}
							onDisconnect={() => handleDisconnectConnector(() => refreshConnectors())}
							onBack={handleBackFromEdit}
							onQuickIndex={(() => {
								const cfg = connectorConfig || editingConnector.config;
								const isDriveOrOneDrive =
									editingConnector.connector_type === "GOOGLE_DRIVE_CONNECTOR" ||
									editingConnector.connector_type === "COMPOSIO_GOOGLE_DRIVE_CONNECTOR" ||
									editingConnector.connector_type === "ONEDRIVE_CONNECTOR" ||
									editingConnector.connector_type === "DROPBOX_CONNECTOR";
								const hasDriveItems = isDriveOrOneDrive
									? ((cfg?.selected_folders as unknown[]) ?? []).length > 0 ||
										((cfg?.selected_files as unknown[]) ?? []).length > 0
									: true;
								if (!hasDriveItems) return undefined;
								return () => {
									startIndexing(editingConnector.id);
									handleQuickIndexConnector(
										editingConnector.id,
										editingConnector.connector_type,
										stopIndexing,
										startDate,
										endDate
									);
								};
							})()}
							onConfigChange={setConnectorConfig}
							onNameChange={setConnectorName}
						/>
					) : indexingConfig ? (
						<IndexingConfigurationView
							config={indexingConfig}
							connector={
								indexingConnector
									? {
											...indexingConnector,
											config: indexingConnectorConfig || indexingConnector.config,
										}
									: undefined
							}
							startDate={startDate}
							endDate={endDate}
							periodicEnabled={periodicEnabled}
							frequencyMinutes={frequencyMinutes}
							enableVisionLlm={enableVisionLlm}
							isStartingIndexing={isStartingIndexing}
							isFromOAuth={isFromOAuth}
							onStartDateChange={setStartDate}
							onEndDateChange={setEndDate}
							onPeriodicEnabledChange={setPeriodicEnabled}
							onFrequencyChange={setFrequencyMinutes}
							onEnableVisionLlmChange={setEnableVisionLlm}
							onConfigChange={setIndexingConnectorConfig}
							onStartIndexing={() => {
								if (indexingConfig.connectorId) {
									startIndexing(indexingConfig.connectorId);
								}
								handleStartIndexing(() => refreshConnectors());
							}}
							onSkip={handleSkipIndexing}
						/>
					) : (
						<Tabs
							value={activeTab}
							onValueChange={handleTabChange}
							className="flex-1 flex flex-col min-h-0"
						>
							{/* Header */}
							<ConnectorDialogHeader
								activeTab={activeTab}
								totalSourceCount={activeConnectorsCount}
								searchQuery={searchQuery}
								onTabChange={handleTabChange}
								onSearchChange={setSearchQuery}
								isScrolled={isScrolled}
							/>

							{/* Content */}
							<div className="flex-1 min-h-0 relative overflow-hidden">
								<div className="h-full overflow-y-auto" onScroll={handleScroll}>
									<div className="px-4 sm:px-12 py-4 sm:py-8 pb-12 sm:pb-16">
										<TabsContent value="all" className="m-0">
											<AllConnectorsTab
												searchQuery={searchQuery}
												workspaceId={workspaceId}
												connectedTypes={connectedTypes}
												connectingId={connectingId}
												allConnectors={connectors}
												documentTypeCounts={documentTypeCounts}
												indexingConnectorIds={indexingConnectorIds}
												onConnectOAuth={handleConnectOAuth}
												onConnectNonOAuth={handleConnectNonOAuth}
												onCreateWebcrawler={handleCreateWebcrawler}
												onCreateYouTubeCrawler={handleCreateYouTubeCrawler}
												onManage={handleStartEdit}
												onViewAccountsList={handleViewAccountsList}
											/>
										</TabsContent>

										<ActiveConnectorsTab
											searchQuery={searchQuery}
											hasSources={hasSources}
											totalSourceCount={totalSourceCount}
											activeDocumentTypes={activeDocumentTypes}
											connectors={connectors as SearchSourceConnector[]}
											indexingConnectorIds={indexingConnectorIds}
											onTabChange={handleTabChange}
											onManage={handleStartEdit}
											onViewAccountsList={handleViewAccountsList}
										/>
									</div>
								</div>
								{/* Bottom fade shadow */}
								<div className="absolute bottom-0 left-0 right-0 h-7 bg-linear-to-t from-popover via-popover/80 to-transparent pointer-events-none z-10" />
							</div>
						</Tabs>
					)}
				</DialogContent>
			</Dialog>
		);
	}
);

ConnectorIndicator.displayName = "ConnectorIndicator";
