'use client'

import { useState, useRef, useCallback, useEffect, useMemo, memo } from 'react'
import { useDeploymentMilestones } from '@/lib/hooks/useInfrastructureData'
import { useMutation } from '@apollo/client'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
} from '@dnd-kit/core'
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { RegionSelector } from './RegionSelector'
import { EntitySelector } from './EntitySelector'
import { EditModeToggle } from './EditModeToggle'
import { EditMilestoneForm } from './forms/EditMilestoneForm'
import { Download, Plus, GripVertical, HelpCircle } from 'lucide-react'
import { EmptyState } from './EmptyState'
import { KeyboardShortcuts, useKeyboardShortcuts } from './KeyboardShortcuts'
import { useToast } from '@/components/ui/use-toast'
import ReactECharts from 'echarts-for-react'
import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'
import { UPDATE_DEPLOYMENT_MILESTONE } from '@/lib/graphql/queries/infrastructure'
import type { DeploymentMilestone } from '@/lib/types/infrastructure'

const priorityColors: Record<string, string> = {
  Critical: 'bg-red-500/20 text-red-400',
  High: 'bg-orange-500/20 text-orange-400',
  Medium: 'bg-yellow-500/20 text-yellow-400',
  Low: 'bg-blue-500/20 text-blue-400',
}

const statusColors: Record<string, string> = {
  Planned: 'bg-gray-500/20 text-gray-400',
  'In Progress': 'bg-blue-500/20 text-blue-400',
  Complete: 'bg-green-500/20 text-green-400',
  Blocked: 'bg-red-500/20 text-red-400',
}

// Sortable milestone item component
function SortableMilestoneItem({
  milestone,
  editMode,
  onEdit,
}: {
  milestone: DeploymentMilestone
  editMode: boolean
  onEdit: () => void
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: milestone.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      className="border border-studio-medium rounded-lg p-4 hover:border-studio-light transition-colors"
    >
      <div className="flex items-start justify-between">
        <div className="flex-1">
          {editMode && (
            <button
              {...attributes}
              {...listeners}
              className="mr-2 cursor-grab active:cursor-grabbing text-studio-medium hover:text-studio-light"
            >
              <GripVertical className="h-5 w-5" />
            </button>
          )}
          <h3 className="font-semibold text-studio-light inline">{milestone.title}</h3>
          <p className="text-sm text-studio-medium mt-1">{milestone.description}</p>
          <div className="flex items-center gap-4 mt-2">
            <Badge className={priorityColors[milestone.priority] || ''}>
              {milestone.priority}
            </Badge>
            <Badge className={statusColors[milestone.status] || ''}>
              {milestone.status}
            </Badge>
            <span className="text-sm text-studio-medium">
              {milestone.region} • {milestone.entity}
            </span>
          </div>
        </div>
        <div className="text-right">
          <div className="text-sm text-studio-medium">
            {new Date(milestone.startDate).toLocaleDateString()} -{' '}
            {new Date(milestone.endDate).toLocaleDateString()}
          </div>
          {milestone.cost && (
            <div className="text-sm font-semibold text-studio-light mt-1">
              ${(milestone.cost / 1000).toFixed(0)}K
            </div>
          )}
        </div>
        {editMode && (
          <div className="ml-4">
            <Button size="sm" variant="outline" onClick={onEdit}>
              Edit
            </Button>
          </div>
        )}
      </div>
    </div>
  )
}

function generateGanttData(milestones: DeploymentMilestone[]) {
  const data = milestones.map((m) => ({
    name: m.title,
    value: [
      m.startDate,
      m.endDate,
      m.status,
      m.priority,
      m.region,
    ],
  }))

  return {
    tooltip: {
      formatter: (params: any) => {
        const [start, end, status, priority, region] = params.value
        return `
          <div>
            <strong>${params.name}</strong><br/>
            Region: ${region}<br/>
            Priority: ${priority}<br/>
            Status: ${status}<br/>
            Start: ${new Date(start).toLocaleDateString()}<br/>
            End: ${new Date(end).toLocaleDateString()}
          </div>
        `
      },
    },
    grid: {
      left: '10%',
      right: '10%',
      top: '10%',
      bottom: '10%',
    },
    xAxis: {
      type: 'time',
    },
    yAxis: {
      type: 'category',
      data: milestones.map((m) => m.title),
      inverse: true,
    },
    series: [
      {
        type: 'custom',
        renderItem: (params: any, api: any) => {
          const categoryIndex = api.value(4)
          const start = api.coord([api.value(0), categoryIndex])
          const end = api.coord([api.value(1), categoryIndex])
          const height = api.size([0, 1])[1] * 0.6

          return {
            type: 'rect',
            shape: {
              x: start[0],
              y: start[1] - height / 2,
              width: end[0] - start[0],
              height: height,
            },
            style: {
              fill: statusColors[api.value(2)]?.split(' ')[0] || '#6b7280',
            },
          }
        },
        data: data,
      },
    ],
  }
}

export function DeploymentTimeline() {
  const [selectedRegion, setSelectedRegion] = useState<string>('All')
  const [selectedEntity, setSelectedEntity] = useState<string>('All')
  const [selectedStatus, setSelectedStatus] = useState<string>('All')
  const [editMode, setEditMode] = useState(false)
  const [exporting, setExporting] = useState(false)
  const [editingMilestone, setEditingMilestone] = useState<DeploymentMilestone | null>(null)
  const [dialogOpen, setDialogOpen] = useState(false)
  const [createDialogOpen, setCreateDialogOpen] = useState(false)
  const [localMilestones, setLocalMilestones] = useState<DeploymentMilestone[]>([])
  const [shortcutsOpen, setShortcutsOpen] = useState(false)
  const ganttChartRef = useRef<HTMLDivElement>(null)
  const { toast } = useToast()

  // Keyboard shortcuts
  useKeyboardShortcuts([
    {
      keys: ['Ctrl', 'e'],
      handler: () => setEditMode(!editMode),
      description: 'Toggle edit mode',
    },
    {
      keys: ['Ctrl', 'n'],
      handler: () => {
        if (editMode) {
          setCreateDialogOpen(true)
        }
      },
      description: 'Create milestone',
    },
    {
      keys: ['Escape'],
      handler: () => {
        setEditMode(false)
        setDialogOpen(false)
        setCreateDialogOpen(false)
      },
      description: 'Cancel/Exit',
    },
    {
      keys: ['Ctrl', '/'],
      handler: () => setShortcutsOpen(true),
      description: 'Show shortcuts',
    },
  ])

  const [updateMilestone, { loading: updating }] = useMutation(UPDATE_DEPLOYMENT_MILESTONE, {
    refetchQueries: ['GetDeploymentMilestones'],
  })

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  )

  // Sync local milestones with fetched data
  useEffect(() => {
    if (milestones.length > 0) {
      setLocalMilestones(milestones)
    }
  }, [milestones])

  const filter = {
    region: selectedRegion === 'All' ? undefined : selectedRegion,
    entity: selectedEntity === 'All' ? undefined : selectedEntity,
    status: selectedStatus === 'All' ? undefined : selectedStatus,
  }

  const { milestones, loading, error } = useDeploymentMilestones(filter)

  const handleDragEnd = useCallback(async (event: DragEndEvent) => {
    const { active, over } = event

    if (!over || active.id === over.id) return

    const oldIndex = localMilestones.findIndex((m) => m.id === active.id)
    const newIndex = localMilestones.findIndex((m) => m.id === over.id)

    if (oldIndex === -1 || newIndex === -1) return

    // Calculate new dates based on position
    const movedMilestone = localMilestones[oldIndex]
    const referenceMilestone = localMilestones[newIndex]

    // Calculate duration
    const duration = new Date(movedMilestone.endDate).getTime() - new Date(movedMilestone.startDate).getTime()

    // Set new dates based on reference milestone
    let newStartDate: Date
    let newEndDate: Date

    if (newIndex > oldIndex) {
      // Moving down - start after reference end date
      newStartDate = new Date(referenceMilestone.endDate)
      newStartDate.setDate(newStartDate.getDate() + 1) // Add 1 day gap
    } else {
      // Moving up - start before reference start date
      newStartDate = new Date(referenceMilestone.startDate)
      newStartDate.setDate(newStartDate.getDate() - Math.ceil(duration / (1000 * 60 * 60 * 24)) - 1) // Subtract duration + 1 day gap
    }

    newEndDate = new Date(newStartDate.getTime() + duration)

    // Validate dates
    if (newStartDate < new Date()) {
      toast({
        title: 'Invalid date',
        description: 'Cannot move milestone to the past',
        variant: 'error',
      })
      return
    }

    // Update milestone dates
    try {
      await updateMilestone({
        variables: {
          id: movedMilestone.id,
          input: {
            startDate: newStartDate.toISOString(),
            endDate: newEndDate.toISOString(),
          },
        },
      })

      // Update local state
      const reordered = arrayMove(localMilestones, oldIndex, newIndex)
      const updated = reordered.map((m) =>
        m.id === movedMilestone.id
          ? {
              ...m,
              startDate: newStartDate.toISOString(),
              endDate: newEndDate.toISOString(),
            }
          : m
      )
      setLocalMilestones(updated)

      toast({
        title: 'Milestone rescheduled',
        description: 'Dates updated successfully',
        variant: 'success',
      })
    } catch (error) {
      toast({
        title: 'Update failed',
        description: error instanceof Error ? error.message : 'Failed to update milestone dates',
        variant: 'error',
      })
    }
  }, [localMilestones, updateMilestone, toast])

  const displayMilestones = localMilestones.length > 0 ? localMilestones : milestones

  const handleExportPDF = async () => {
    if (!ganttChartRef.current || milestones.length === 0) {
      toast({
        title: 'Export failed',
        description: 'No data to export',
        variant: 'error',
      })
      return
    }

    setExporting(true)
    try {
      const pdf = new jsPDF('landscape', 'mm', 'a4')
      const pageWidth = pdf.internal.pageSize.getWidth()
      const pageHeight = pdf.internal.pageSize.getHeight()

      // Page 1: Title and metadata
      pdf.setFontSize(20)
      pdf.text('Deployment Timeline', 20, 20)
      pdf.setFontSize(12)
      pdf.text(`Region: ${selectedRegion}`, 20, 30)
      pdf.text(`Entity: ${selectedEntity}`, 20, 35)
      pdf.text(`Status: ${selectedStatus}`, 20, 40)
      pdf.text(`Export Date: ${new Date().toLocaleDateString()}`, 20, 45)
      pdf.text(`Total Milestones: ${milestones.length}`, 20, 50)

      // Page 2: Gantt chart
      const chartElement = ganttChartRef.current.querySelector('.echarts-for-react')
      if (chartElement) {
        const canvas = await html2canvas(chartElement as HTMLElement, {
          backgroundColor: '#000000',
          scale: 2,
          logging: false,
        })
        const imgData = canvas.toDataURL('image/png')
        pdf.addPage()
        const imgWidth = pageWidth - 20
        const imgHeight = (canvas.height * imgWidth) / canvas.width
        pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, Math.min(imgHeight, pageHeight - 20))
      }

      // Page 3: Milestone list
      pdf.addPage()
      pdf.setFontSize(16)
      pdf.text('Milestone List', 20, 20)

      let y = 30
      milestones.forEach((milestone, index) => {
        if (y > pageHeight - 30) {
          pdf.addPage()
          y = 20
        }

        pdf.setFontSize(12)
        pdf.text(`${index + 1}. ${milestone.title}`, 20, y)
        pdf.setFontSize(10)
        pdf.text(
          `Status: ${milestone.status} | Priority: ${milestone.priority} | Region: ${milestone.region}`,
          20,
          y + 5
        )
        pdf.text(
          `Dates: ${new Date(milestone.startDate).toLocaleDateString()} - ${new Date(
            milestone.endDate
          ).toLocaleDateString()}`,
          20,
          y + 10
        )
        if (milestone.cost) {
          pdf.text(`Cost: $${(milestone.cost / 1000).toFixed(0)}K`, 20, y + 15)
          y += 20
        } else {
          y += 15
        }
      })

      // Save PDF
      pdf.save(`deployment-timeline-${selectedRegion}-${selectedEntity}-${Date.now()}.pdf`)

      toast({
        title: 'Export successful',
        description: 'Timeline exported as PDF',
      })
    } catch (error) {
      toast({
        title: 'Export failed',
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: 'error',
      })
    } finally {
      setExporting(false)
    }
  }

  if (loading) {
    return (
      <div className="space-y-6">
        <div>
          <h1 className="text-3xl font-bold text-studio-light">Deployment Timeline</h1>
          <p className="text-studio-medium mt-2">
            Manage infrastructure deployment milestones and schedules
          </p>
        </div>
        <Card>
          <CardContent>
            <div className="h-[600px] flex items-center justify-center">
              <div className="text-studio-medium">Loading timeline...</div>
            </div>
          </CardContent>
        </Card>
      </div>
    )
  }

  if (error) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>Error Loading Timeline</CardTitle>
          <CardDescription>{error.message}</CardDescription>
        </CardHeader>
      </Card>
    )
  }

  const ganttOptions = generateGanttData(displayMilestones)

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold text-studio-light">Deployment Timeline</h1>
          <p className="text-studio-medium mt-2">
            Manage infrastructure deployment milestones and schedules
          </p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" onClick={handleExportPDF} disabled={exporting || !milestones.length}>
            <Download className="h-4 w-4 mr-2" />
            {exporting ? 'Exporting...' : 'Export PDF'}
          </Button>
          <Button variant="outline" onClick={() => setShortcutsOpen(true)}>
            <HelpCircle className="h-4 w-4 mr-2" />
            Shortcuts
          </Button>
          {editMode && (
            <Button onClick={() => setCreateDialogOpen(true)}>
              <Plus className="h-4 w-4 mr-2" />
              Add Milestone
            </Button>
          )}
        </div>
      </div>

      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div>
              <CardTitle>Gantt Chart</CardTitle>
              <CardDescription>
                {milestones.length} milestone{milestones.length !== 1 ? 's' : ''} found
              </CardDescription>
            </div>
            <div className="flex items-center gap-4">
              <RegionSelector
                value={selectedRegion}
                onChange={setSelectedRegion}
                className="w-48"
              />
              <EntitySelector
                value={selectedEntity}
                onChange={setSelectedEntity}
                className="w-64"
              />
              <select
                value={selectedStatus}
                onChange={(e) => setSelectedStatus(e.target.value)}
                className="h-10 rounded-md border border-studio-medium bg-studio-dark px-3 text-sm"
              >
                <option value="All">All Status</option>
                <option value="Planned">Planned</option>
                <option value="In Progress">In Progress</option>
                <option value="Complete">Complete</option>
                <option value="Blocked">Blocked</option>
              </select>
              <EditModeToggle enabled={editMode} onToggle={setEditMode} />
            </div>
          </div>
        </CardHeader>
        <CardContent>
          <div ref={ganttChartRef} id="gantt-chart">
            {displayMilestones.length > 0 ? (
              <ReactECharts option={ganttOptions} style={{ height: '600px' }} />
            ) : (
              <EmptyState
                title="No milestones found"
                description="No milestones match your current filters."
                action={
                  editMode
                    ? {
                        label: 'Create Milestone',
                        onClick: () => setCreateDialogOpen(true),
                      }
                    : undefined
                }
              />
            )}
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Milestone List</CardTitle>
          {editMode && (
            <CardDescription>
              Drag milestones to reschedule. Dates will be automatically updated.
            </CardDescription>
          )}
        </CardHeader>
        <CardContent>
          {editMode ? (
            <DndContext
              sensors={sensors}
              collisionDetection={closestCenter}
              onDragEnd={handleDragEnd}
            >
              <SortableContext
                items={displayMilestones.map((m) => m.id)}
                strategy={verticalListSortingStrategy}
              >
                <div className="space-y-4">
                  {displayMilestones.map((milestone) => (
                    <SortableMilestoneItem
                      key={milestone.id}
                      milestone={milestone}
                      editMode={editMode}
                      onEdit={() => {
                        setEditingMilestone(milestone)
                        setDialogOpen(true)
                      }}
                    />
                  ))}
                </div>
              </SortableContext>
            </DndContext>
          ) : (
            <div className="space-y-4">
              {displayMilestones.map((milestone) => (
                <div
                  key={milestone.id}
                  className="border border-studio-medium rounded-lg p-4 hover:border-studio-light transition-colors"
                >
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <h3 className="font-semibold text-studio-light">{milestone.title}</h3>
                      <p className="text-sm text-studio-medium mt-1">{milestone.description}</p>
                      <div className="flex items-center gap-4 mt-2">
                        <Badge className={priorityColors[milestone.priority] || ''}>
                          {milestone.priority}
                        </Badge>
                        <Badge className={statusColors[milestone.status] || ''}>
                          {milestone.status}
                        </Badge>
                        <span className="text-sm text-studio-medium">
                          {milestone.region} • {milestone.entity}
                        </span>
                      </div>
                    </div>
                    <div className="text-right">
                      <div className="text-sm text-studio-medium">
                        {new Date(milestone.startDate).toLocaleDateString()} -{' '}
                        {new Date(milestone.endDate).toLocaleDateString()}
                      </div>
                      {milestone.cost && (
                        <div className="text-sm font-semibold text-studio-light mt-1">
                          ${(milestone.cost / 1000).toFixed(0)}K
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {editingMilestone && (
        <EditMilestoneForm
          open={dialogOpen}
          onOpenChange={(open) => {
            setDialogOpen(open)
            if (!open) setEditingMilestone(null)
          }}
          milestone={editingMilestone}
          onSuccess={() => {
            setEditingMilestone(null)
          }}
        />
      )}

      <EditMilestoneForm
        open={createDialogOpen}
        onOpenChange={(open) => {
          setCreateDialogOpen(open)
        }}
          onSuccess={() => {
            setCreateDialogOpen(false)
          }}
        />

        <KeyboardShortcuts
          open={shortcutsOpen}
          onOpenChange={setShortcutsOpen}
          shortcuts={[
            { keys: ['Ctrl', 'E'], description: 'Toggle edit mode', category: 'General' },
            { keys: ['Ctrl', 'N'], description: 'Create milestone', category: 'General' },
            { keys: ['Escape'], description: 'Cancel/Exit', category: 'General' },
            { keys: ['Ctrl', '/'], description: 'Show shortcuts', category: 'General' },
          ]}
        />
      </div>
    )
  }

