/**
 * Sync Control Panel Component
 * Controls for triggering sync operations
 */

'use client';

import { useState } from 'react';
import { EntityType, SyncType } from '@/lib/types/sync';
import EntitySelector from './EntitySelector';
import ChunkedSyncProgress from './ChunkedSyncProgress';
import EntitySyncProgress from './EntitySyncProgress';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { toast } from 'sonner';
import { Loader2, RefreshCw, PlayCircle, Zap, Calendar, Layers } from 'lucide-react';

interface SyncControlPanelProps {
  selectedEntities: EntityType[];
  onSelectedEntitiesChange: (entities: EntityType[]) => void;
  onSyncStart: () => void;
  onSyncComplete: () => void;
  isSyncing: boolean;
}

export default function SyncControlPanel({
  selectedEntities,
  onSelectedEntitiesChange,
  onSyncStart,
  onSyncComplete,
  isSyncing,
}: SyncControlPanelProps) {
  const [showConfirmDialog, setShowConfirmDialog] = useState(false);
  const [pendingSyncType, setPendingSyncType] = useState<'full' | 'incremental' | 'entity' | 'chunked' | null>(null);
  const [yearsBack, setYearsBack] = useState<number>(0.019); // Default to 7 days
  
  // Chunked sync progress state
  const [isChunkedSyncing, setIsChunkedSyncing] = useState(false);
  const [chunkedProgress, setChunkedProgress] = useState({
    completedChunks: 0,
    totalChunks: 0,
    totalRecords: 0,
    currentChunk: undefined as any,
    failedChunks: [] as string[],
  });
  
  // Entity sync progress tracking
  const [activeSyncEntity, setActiveSyncEntity] = useState<EntityType | null>(null);
  const [syncId, setSyncId] = useState<string | null>(null);

  const handleSync = async (syncType: 'full' | 'incremental' | 'entity' | 'chunked') => {
    if (syncType === 'entity' && selectedEntities.length === 0) {
      toast.error('Please select at least one entity to sync');
      return;
    }

    if (syncType === 'full') {
      setPendingSyncType('full');
      setShowConfirmDialog(true);
      return;
    }

    if (syncType === 'chunked') {
      await executeChunkedSync();
      return;
    }

    await executeSyncRequest(syncType);
  };

  const executeChunkedSync = async () => {
    try {
      const estimatedChunks = Math.ceil(yearsBack * 12); // Monthly chunks
      
      setIsChunkedSyncing(true);
      setChunkedProgress({
        completedChunks: 0,
        totalChunks: estimatedChunks,
        totalRecords: 0,
        currentChunk: {
          index: 1,
          total: estimatedChunks,
          description: 'Starting chunked sync...',
          recordsProcessed: 0,
          status: 'in_progress' as const,
        },
        failedChunks: [],
      });
      onSyncStart();

      const response = await fetch('/api/sync/tickets-chunked', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
          yearsBack,
          triggeredBy: 'admin-ui',
        }),
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || 'Chunked sync failed');
      }

      const result = await response.json();
      toast.success(result.message || 'Chunked ticket sync started successfully');

      // Use the estimated chunks from above
      let currentPollChunk = 0;
      
      // Poll for sync completion by checking sync history
      // The sync runs in background, so we check periodically for updates
      const pollInterval = setInterval(async () => {
        try {
          const historyResponse = await fetch('/api/sync/history?limit=1&entity=tickets');
          if (historyResponse.ok) {
            const historyData = await historyResponse.json();
            const latestSync = historyData.history?.[0];
            
            // Update progress estimate based on time elapsed
            currentPollChunk = Math.min(currentPollChunk + 1, estimatedChunks);
            setChunkedProgress(prev => ({
              ...prev,
              completedChunks: currentPollChunk,
              totalChunks: estimatedChunks,
              totalRecords: latestSync?.records_added + latestSync?.records_updated || prev.totalRecords,
              currentChunk: {
                index: currentPollChunk,
                total: estimatedChunks,
                description: `Processing... (${currentPollChunk}/${estimatedChunks})`,
                recordsProcessed: latestSync?.records_added + latestSync?.records_updated || 0,
                status: 'in_progress' as const,
              },
            }));
            
            // Check if the latest sync is completed or failed
            if (latestSync && (latestSync.status === 'completed' || latestSync.status === 'failed')) {
              clearInterval(pollInterval);
              setIsChunkedSyncing(false);
              setChunkedProgress(prev => ({
                ...prev,
                completedChunks: estimatedChunks,
                currentChunk: undefined,
              }));
              onSyncComplete();
              
              if (latestSync.status === 'completed') {
                toast.success(`Chunked sync completed! ${latestSync.records_added + latestSync.records_updated} records processed`);
              } else {
                toast.error('Chunked sync failed. Check logs for details.');
              }
            }
          }
        } catch (pollError) {
          console.error('Error polling sync status:', pollError);
        }
      }, 5000); // Poll every 5 seconds

      // Fallback: Stop polling after 30 minutes
      setTimeout(() => {
        clearInterval(pollInterval);
        setIsChunkedSyncing(false);
        onSyncComplete();
        toast.info('Sync is still running. Check sync history for final status.');
      }, 30 * 60 * 1000);

    } catch (error) {
      console.error('Chunked sync error:', error);
      toast.error(error instanceof Error ? error.message : 'Failed to start chunked sync');
      setIsChunkedSyncing(false);
      onSyncComplete();
    }
  };

  const executeSyncRequest = async (syncType: 'full' | 'incremental' | 'entity') => {
    try {
      onSyncStart();
      
      // Track entity sync if it's a single entity
      if (syncType === 'entity' && selectedEntities.length === 1) {
        setActiveSyncEntity(selectedEntities[0]);
        setSyncId(`${selectedEntities[0]}_${Date.now()}`);
      }

      let endpoint = '/api/sync/full';
      let body: any = { triggeredBy: 'admin-ui' };

      if (syncType === 'incremental') {
        endpoint = '/api/sync/incremental';
      } else if (syncType === 'entity') {
        endpoint = '/api/sync/entity';
        body.entities = selectedEntities;
        body.syncType = SyncType.ENTITY_SPECIFIC;
      }

      const response = await fetch(endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...body, yearsBack }),
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || 'Sync failed');
      }

      const result = await response.json();
      toast.success(result.message || 'Sync started successfully');

      // Note: Sync runs in background. Dashboard will auto-refresh to show progress.
      // onSyncComplete will be called when user manually refreshes or after checking status
    } catch (error) {
      console.error('Sync error:', error);
      toast.error(error instanceof Error ? error.message : 'Failed to start sync');
      onSyncComplete();
    }
  };

  const confirmFullSync = async () => {
    setShowConfirmDialog(false);
    if (pendingSyncType && pendingSyncType !== 'chunked') {
      await executeSyncRequest(pendingSyncType);
      setPendingSyncType(null);
    }
  };

  return (
    <>
      {/* Entity Sync Progress */}
      {activeSyncEntity && syncId && (
        <EntitySyncProgress
          entityType={activeSyncEntity}
          syncId={syncId}
          onComplete={() => {
            setActiveSyncEntity(null);
            setSyncId(null);
            onSyncComplete();
          }}
          onError={(error) => {
            toast.error(error);
            setActiveSyncEntity(null);
            setSyncId(null);
            onSyncComplete();
          }}
        />
      )}
      
      {/* Chunked Sync Progress */}
      {(isChunkedSyncing || chunkedProgress.totalChunks > 0) && (
        <ChunkedSyncProgress
          isActive={isChunkedSyncing}
          currentChunk={chunkedProgress.currentChunk}
          completedChunks={chunkedProgress.completedChunks}
          totalChunks={chunkedProgress.totalChunks}
          totalRecords={chunkedProgress.totalRecords}
          failedChunks={chunkedProgress.failedChunks}
        />
      )}

      <Card>
        <CardHeader>
          <CardTitle>Sync Controls</CardTitle>
          <CardDescription>
            Trigger manual sync operations to update PostgreSQL database from Autotask
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* Entity Selector */}
          <EntitySelector
            selectedEntities={selectedEntities}
            onChange={onSelectedEntitiesChange}
            disabled={isSyncing}
          />

          {/* Date Range Selector for Time-Based Entities */}
          <div className="space-y-2">
            <Label htmlFor="years-back" className="flex items-center gap-2">
              <Calendar className="w-4 h-4" />
              Date Range for Tickets/Tasks
            </Label>
            <Select
              value={yearsBack.toString()}
              onValueChange={(value) => setYearsBack(parseFloat(value))}
              disabled={isSyncing}
            >
              <SelectTrigger id="years-back" className="w-full sm:w-64">
                <SelectValue placeholder="Select date range" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="0.019">Last 7 Days</SelectItem>
                <SelectItem value="0.082">Last 30 Days</SelectItem>
                <SelectItem value="0.25">Last 90 Days</SelectItem>
                <SelectItem value="1">Last 1 Year</SelectItem>
                <SelectItem value="2">Last 2 Years (Recommended)</SelectItem>
                <SelectItem value="3">Last 3 Years</SelectItem>
                <SelectItem value="5">Last 5 Years</SelectItem>
                <SelectItem value="10">Last 10 Years</SelectItem>
                <SelectItem value="999">All Time (Slow)</SelectItem>
              </SelectContent>
            </Select>
            <p className="text-xs text-muted-foreground">
              Limits tickets, tasks, and projects to reduce sync time and API usage. 
              Use "All Time" during off-hours for historical data.
            </p>
            <p className="text-xs text-amber-500/80">
              <strong>Note:</strong> Configuration Items, Companies, Contacts, Resources, and Contracts ignore this range — they always sync all active records regardless of date.
            </p>
          </div>

          {/* Sync Buttons */}
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
            <Button
              onClick={() => handleSync('full')}
              disabled={isSyncing || isChunkedSyncing}
              size="lg"
              variant="default"
              className="w-full"
            >
              {isSyncing ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <RefreshCw className="mr-2 h-4 w-4" />
              )}
              Full Sync
            </Button>

            <Button
              onClick={() => handleSync('incremental')}
              disabled={isSyncing || isChunkedSyncing}
              size="lg"
              variant="secondary"
              className="w-full"
            >
              {isSyncing ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Zap className="mr-2 h-4 w-4" />
              )}
              Incremental Sync
            </Button>

            <Button
              onClick={() => handleSync('chunked')}
              disabled={isSyncing || isChunkedSyncing}
              size="lg"
              variant="default"
              className="w-full bg-blue-600 hover:bg-blue-700"
            >
              {isChunkedSyncing ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Layers className="mr-2 h-4 w-4" />
              )}
              Chunked Tickets
            </Button>

            <Button
              onClick={() => handleSync('entity')}
              disabled={isSyncing || isChunkedSyncing || selectedEntities.length === 0}
              size="lg"
              variant="outline"
              className="w-full"
            >
              {isSyncing ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <PlayCircle className="mr-2 h-4 w-4" />
              )}
              Sync Selected ({selectedEntities.length})
            </Button>
          </div>

          <div className="text-sm text-muted-foreground space-y-1">
            <p><strong>Full Sync:</strong> Syncs all entities and soft-deletes missing records</p>
            <p><strong>Incremental Sync:</strong> Only syncs records modified since last sync</p>
            <p><strong>Chunked Tickets:</strong> Syncs tickets in monthly chunks to prevent timeouts (recommended for large date ranges)</p>
            <p><strong>Sync Selected:</strong> Syncs only the selected entities</p>
          </div>
        </CardContent>
      </Card>

      {/* Confirmation Dialog */}
      <AlertDialog open={showConfirmDialog} onOpenChange={setShowConfirmDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Confirm Full Sync</AlertDialogTitle>
            <AlertDialogDescription>
              This will sync all entities from Autotask and may take several minutes.
              Records not found in Autotask will be soft-deleted. Are you sure you want to continue?
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={confirmFullSync}>
              Start Full Sync
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}
