import { useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import { useSSE } from '../hooks/useSSE'
import ChecklistItem from '../components/ChecklistItem'
import { EditableTitle } from '../components/EditableTitle'
import { exportChecklistToJSON } from '../hooks/useLocalStorage'
import type { ChecklistItem as ChecklistItemType } from '../types'
import { Flex, Box, Text, Button, TextField, Heading, Badge, Card, IconButton } from '@radix-ui/themes'
import { ArrowLeftIcon, DownloadIcon, ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons'

interface ItemGroup {
  title: string
  items: ChecklistItemType[]
  isCollapsible?: boolean
  isCollapsed?: boolean
  onToggleCollapse?: () => void
}

export default function Checklist() {
  const { uuid } = useParams<{ uuid: string }>()
  const { items, checkListName, isConnected, error } = useSSE(uuid || '')
  const [newItemContent, setNewItemContent] = useState('')
  const [isAddingItem, setIsAddingItem] = useState(false)
  const [completedItemsCollapsed, setCompletedItemsCollapsed] = useState(false)
  const [isExporting, setIsExporting] = useState(false)


  const buildItemTree = (items: ChecklistItemType[]): ChecklistItemType[] => {
    const itemMap = new Map<number, ChecklistItemType>()
    const rootItems: ChecklistItemType[] = []

    // Create a map of all items
    items.forEach(item => {
      itemMap.set(item.id, { ...item, children: [] })
    })

    // Build the tree structure
    items.forEach(item => {
      if (item.parent_id === null) {
        rootItems.push(itemMap.get(item.id)!)
      } else {
        const parent = itemMap.get(item.parent_id)
        if (parent) {
          if (!parent.children) parent.children = []
          parent.children.push(itemMap.get(item.id)!)
        }
      }
    })

    return rootItems
  }

  const categorizeItems = (items: ChecklistItemType[]): ItemGroup[] => {
    const now = new Date()
    
    // Helper function to check if an item can be completed
    const canComplete = (item: ChecklistItemType): boolean => {
      // Check dependencies
      const dependenciesCompleted = item.dependencies?.every(depId => {
        const depItem = items.find(i => i.id === depId)
        return depItem?.checked
      }) ?? true

      // Check date constraints
      const notBeforeDate = item.not_before ? new Date(item.not_before) : null
      const notAfterDate = item.not_after ? new Date(item.not_after) : null
      const dateConstraintsMet = (!notBeforeDate || now >= notBeforeDate) && (!notAfterDate || now <= notAfterDate)

      return dependenciesCompleted && dateConstraintsMet
    }

    // Helper function to check if an item is locked by constraints
    const isLockedByConstraints = (item: ChecklistItemType): boolean => {
      if (item.checked) return false
      
      // Check dependencies
      const dependenciesCompleted = item.dependencies?.every(depId => {
        const depItem = items.find(i => i.id === depId)
        return depItem?.checked
      }) ?? true

      // Check date constraints
      const notBeforeDate = item.not_before ? new Date(item.not_before) : null
      const notAfterDate = item.not_after ? new Date(item.not_after) : null
      const dateConstraintsMet = (!notBeforeDate || now >= notBeforeDate) && (!notAfterDate || now <= notAfterDate)

      return !dependenciesCompleted || !dateConstraintsMet
    }

    const completedItems = items.filter(item => item.checked)
    const availableItems = items.filter(item => !item.checked && canComplete(item))
    const lockedItems = items.filter(item => !item.checked && isLockedByConstraints(item))

    const groups: ItemGroup[] = []

    // Completed items (collapsible)
    if (completedItems.length > 0) {
      groups.push({
        title: `Completed (${completedItems.length})`,
        items: completedItems,
        isCollapsible: true,
        isCollapsed: completedItemsCollapsed,
        onToggleCollapse: () => setCompletedItemsCollapsed(!completedItemsCollapsed)
      })
    }

    // Available items (can be completed)
    if (availableItems.length > 0) {
      groups.push({
        title: `Available (${availableItems.length})`,
        items: availableItems
      })
    }

    // Locked items (cannot be completed due to constraints)
    if (lockedItems.length > 0) {
      groups.push({
        title: `Locked by Constraints (${lockedItems.length})`,
        items: lockedItems
      })
    }

    return groups
  }

  const addItem = async (content: string, parentId?: number) => {
    if (!content.trim() || !uuid) return

    setIsAddingItem(true)
    try {
      const response = await fetch(`/api/checklists/${uuid}/items`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ 
          content: content.trim(),
          parent_id: parentId || null
        }),
      })

      if (!response.ok) {
        throw new Error('Failed to add item')
      }
    } catch (error) {
      console.error('Error adding item:', error)
      alert('Failed to add item')
    } finally {
      setIsAddingItem(false)
    }
  }

  const updateItem = async (id: number, updates: Partial<ChecklistItemType>) => {
    if (!uuid) return

    try {
      const response = await fetch(`/api/checklists/${uuid}/items/${id}`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(updates),
      })

      if (!response.ok) {
        throw new Error('Failed to update item')
      }
    } catch (error) {
      console.error('Error updating item:', error)
      throw error
    }
  }

  const deleteItem = async (id: number) => {
    if (!uuid) return

    try {
      const response = await fetch(`/api/checklists/${uuid}/items/${id}`, {
        method: 'DELETE',
      })

      if (!response.ok) {
        throw new Error('Failed to delete item')
      }
    } catch (error) {
      console.error('Error deleting item:', error)
      throw error
    }
  }

  const lockItem = async (id: number, user: string) => {
    if (!uuid) return

    try {
      const response = await fetch(`/api/checklists/${uuid}/items/${id}/lock`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ user }),
      })

      if (!response.ok) {
        throw new Error('Failed to lock item')
      }
    } catch (error) {
      console.error('Error locking item:', error)
      throw error
    }
  }

  const updateChecklistName = async (newName: string) => {
    if (!uuid) throw new Error('No checklist UUID')

    const response = await fetch(`/api/checklists/${uuid}/name`, {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ name: newName }),
    })

    if (!response.ok) {
      throw new Error('Failed to update checklist name')
    }
  }

  const handleAddItem = async () => {
    await addItem(newItemContent)
    setNewItemContent('')
  }

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      handleAddItem()
    }
  }

  const handleExportChecklist = async () => {
    if (!uuid || !checkListName) return
    
    setIsExporting(true)
    try {
      await exportChecklistToJSON(uuid, checkListName)
    } catch {
      alert('Failed to export checklist')
    } finally {
      setIsExporting(false)
    }
  }



  const renderGroupedItems = (allItems: ChecklistItemType[]) => {
    const itemTree = buildItemTree(allItems)
    
    if (itemTree.length === 0) {
      return (
        <Flex direction="column" align="center" justify="center" py="9">
          <Text size="9" color="gray" mb="3">📝</Text>
          <Text size="3" weight="medium" color="gray">No items yet</Text>
          <Text size="2" color="gray" mt="1">Add your first item above to get started!</Text>
        </Flex>
      )
    }

    const groups = categorizeItems(allItems)
    
    return (
      <Flex direction="column" gap="5">
        {groups.map((group, groupIndex) => (
          <Box key={groupIndex}>
            <Flex align="center" justify="between" pb="2" className="border-b border-gray-200 dark:border-gray-700">
              <Heading 
                size="2" 
                color={group.title.includes('Completed') ? "green" : group.title.includes('Available') ? "blue" : "orange"}
              >
                {group.title}
              </Heading>
              {group.isCollapsible && (
                <IconButton
                  size="1"
                  variant="ghost"
                  onClick={group.onToggleCollapse}
                >
                  {group.isCollapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
                </IconButton>
              )}
            </Flex>

            {(!group.isCollapsible || !group.isCollapsed) && (
              <Box 
                mt="3"
                style={{
                  opacity: group.title.includes('Completed') ? 0.75 : 1
                }}
              >
                <Flex direction="column" gap="2">
                  {group.items.map(item => {
                    const findItemWithChildren = (items: ChecklistItemType[], targetId: number): ChecklistItemType | null => {
                      for (const item of items) {
                        if (item.id === targetId) {
                          return item
                        }
                        if (item.children) {
                          const found = findItemWithChildren(item.children, targetId)
                          if (found) return found
                        }
                      }
                      return null
                    }
                    
                    const itemWithChildren = findItemWithChildren(itemTree, item.id)
                    
                    return (
                      <ChecklistItem
                        key={item.id}
                        item={item}
                        onUpdate={updateItem}
                        onDelete={deleteItem}
                        onLock={lockItem}
                        children={itemWithChildren?.children || []}
                        allItems={allItems}
                      />
                    )
                  })}
                </Flex>
              </Box>
            )}
          </Box>
        ))}
      </Flex>
    )
  }

  if (!uuid) {
    return (
      <Flex align="center" justify="center" style={{ minHeight: '100vh' }}>
        <Text size="4" color="red" weight="medium">Invalid checklist ID</Text>
      </Flex>
    )
  }



  return (
    <Box style={{ minHeight: '100vh' }} className="bg-gray-50 dark:bg-gray-900">
      <Box className="bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700">
        <Box style={{ maxWidth: '1024px' }} mx="auto" p="3">
          <Flex direction={{ initial: 'column', sm: 'row' }} align="center" justify="between" gap="3">
            <Flex align="center" gap="3">
              <Link to="/">
                <Button variant="ghost" size="2">
                  <ArrowLeftIcon />
                  Back
                </Button>
              </Link>
              <EditableTitle 
                title={checkListName} 
                onSave={updateChecklistName}
                className="text-base"
              />
            </Flex>
            <Flex align="center" gap="2">
              <Button 
                onClick={handleExportChecklist}
                disabled={isExporting || !isConnected}
                size="2"
                color="violet"
              >
                <DownloadIcon />
                {isExporting ? 'Exporting...' : 'Export'}
              </Button>
              <Badge 
                color={isConnected ? "green" : "red"} 
                variant="surface"
                size="2"
              >
                <Box 
                  width="8px" 
                  height="8px" 
                  className={`rounded-full ${isConnected ? 'bg-green-500' : 'bg-red-500'}`}
                />
                {isConnected ? 'Connected' : 'Disconnected'}
              </Badge>
            </Flex>
          </Flex>
        </Box>
      </Box>

      {error && (
        <Box style={{ maxWidth: '1024px' }} mx="auto" px="2" py="2">
          <Card size="2" style={{ backgroundColor: 'var(--red-a3)', borderColor: 'var(--red-a6)' }}>
            <Flex align="center" gap="2">
              <Text color="red">⚠️</Text>
              <Text color="red" weight="medium">{error}</Text>
            </Flex>
          </Card>
        </Box>
      )}

      <Box style={{ maxWidth: '1024px' }} mx="auto" px="3" py="4">
        <Box mb="4">
          <Flex direction={{ initial: 'column', sm: 'row' }} gap="2">
            <Box style={{ flex: 1 }}>
              <TextField.Root
                size="3"
                placeholder="Add a new item..."
                value={newItemContent}
                onChange={(e) => setNewItemContent(e.target.value)}
                onKeyDown={handleKeyPress}
                disabled={isAddingItem || !isConnected}
              />
            </Box>
            <Button 
              onClick={handleAddItem}
              disabled={isAddingItem || !newItemContent.trim() || !isConnected}
              size="3"
            >
              {isAddingItem ? 'Adding...' : 'Add'}
            </Button>
          </Flex>
        </Box>

        <Box>
          {renderGroupedItems(items)}
        </Box>
      </Box>
    </Box>
  )
} 