import React, { useState, useMemo } from 'react'
import {
  Box,
  Typography,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Chip,
  Stack,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  useMediaQuery,
  useTheme,
  Checkbox,
  Toolbar,
  Button,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogContentText,
  DialogActions,
} from '@mui/material'
import { Delete as DeleteIcon } from '@mui/icons-material'
import { useTasks } from '~/hooks/useTasks'
import { TaskStatus, type Task } from '~/types/task'
import LoadingSpinner from './LoadingSpinner'

type SortOption =
  | 'created_desc'
  | 'created_asc'
  | 'title_asc'
  | 'title_desc'
  | 'status'

interface TaskListProps {
  className?: string
  initialTasks?: Task[]
}

export function TaskList({ className, initialTasks }: TaskListProps) {
  const { tasks, loading, error, deleteTask } = useTasks({
    autoFetch: !initialTasks,
    initialData: initialTasks,
  })
  const [statusFilter, setStatusFilter] = useState<TaskStatus | 'all'>('all')
  const [sortBy, setSortBy] = useState<SortOption>('created_desc')
  const [selectedTaskIds, setSelectedTaskIds] = useState<Set<string>>(new Set())
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
  const theme = useTheme()
  const isMobile = useMediaQuery(theme.breakpoints.down('md'))

  const filteredAndSortedTasks = useMemo(() => {
    let filteredTasks = tasks

    // Apply status filter
    if (statusFilter !== 'all') {
      filteredTasks = tasks.filter(task => task.status === statusFilter)
    }

    // Apply sorting
    const sorted = [...filteredTasks].sort((a, b) => {
      switch (sortBy) {
        case 'created_desc':
          return (
            new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
          )
        case 'created_asc':
          return (
            new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
          )
        case 'title_asc':
          return a.title.localeCompare(b.title)
        case 'title_desc':
          return b.title.localeCompare(a.title)
        case 'status': {
          const statusOrder = {
            [TaskStatus.Todo]: 0,
            [TaskStatus.Backlog]: 1,
            [TaskStatus.Done]: 2,
          }
          return statusOrder[a.status] - statusOrder[b.status]
        }
        default:
          return 0
      }
    })

    return sorted
  }, [tasks, statusFilter, sortBy])

  const getStatusColor = (status: TaskStatus) => {
    switch (status) {
      case TaskStatus.Todo:
        return 'primary'
      case TaskStatus.Done:
        return 'success'
      case TaskStatus.Backlog:
        return 'default'
      default:
        return 'default'
    }
  }

  const formatCompactDate = (dateString: string) => {
    const date = new Date(dateString)
    const now = new Date()
    const diffInDays = Math.floor(
      (now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24)
    )

    if (diffInDays === 0) return 'Today'
    if (diffInDays === 1) return 'Yesterday'
    if (diffInDays < 7) return `${diffInDays}d ago`
    if (diffInDays < 30) return `${Math.floor(diffInDays / 7)}w ago`
    if (diffInDays < 365) return `${Math.floor(diffInDays / 30)}mo ago`
    return `${Math.floor(diffInDays / 365)}y ago`
  }

  const handleSelectAll = (checked: boolean) => {
    if (checked) {
      setSelectedTaskIds(new Set(filteredAndSortedTasks.map(task => task.id)))
    } else {
      setSelectedTaskIds(new Set())
    }
  }

  const handleSelectTask = (taskId: string, checked: boolean) => {
    const newSelected = new Set(selectedTaskIds)
    if (checked) {
      newSelected.add(taskId)
    } else {
      newSelected.delete(taskId)
    }
    setSelectedTaskIds(newSelected)
  }

  const handleBulkDelete = async () => {
    try {
      const results = await Promise.all(
        Array.from(selectedTaskIds).map(taskId => deleteTask(taskId))
      )

      // Check if all deletions were successful
      const allSuccessful = results.every(result => result === true)

      if (allSuccessful) {
        setSelectedTaskIds(new Set())
        setDeleteDialogOpen(false)
      } else {
        console.error('Some tasks failed to delete')
        // Clear selection of successfully deleted tasks
        const failedTaskIds = Array.from(selectedTaskIds).filter(
          (taskId, index) => !results[index]
        )
        setSelectedTaskIds(new Set(failedTaskIds))
      }
    } catch (error) {
      console.error('Error deleting tasks:', error)
    }
  }

  const isAllSelected =
    filteredAndSortedTasks.length > 0 &&
    filteredAndSortedTasks.every(task => selectedTaskIds.has(task.id))
  const isIndeterminate = selectedTaskIds.size > 0 && !isAllSelected

  if (loading) {
    return <LoadingSpinner />
  }

  if (error) {
    return (
      <Box sx={{ p: 2, textAlign: 'center' }}>
        <Typography color="error" variant="h6">
          Error loading tasks
        </Typography>
        <Typography color="text.secondary" variant="body2">
          {error}
        </Typography>
      </Box>
    )
  }

  return (
    <Box className={className}>
      {/* Filter and Sort Controls */}
      <Paper sx={{ p: 2, mb: 2 }}>
        <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
          <FormControl size="small" sx={{ minWidth: 120 }}>
            <InputLabel>Status</InputLabel>
            <Select
              value={statusFilter}
              label="Status"
              onChange={e =>
                setStatusFilter(e.target.value as TaskStatus | 'all')
              }
            >
              <MenuItem value="all">All Tasks</MenuItem>
              <MenuItem value={TaskStatus.Todo}>Todo</MenuItem>
              <MenuItem value={TaskStatus.Done}>Done</MenuItem>
              <MenuItem value={TaskStatus.Backlog}>Backlog</MenuItem>
            </Select>
          </FormControl>

          <FormControl size="small" sx={{ minWidth: 150 }}>
            <InputLabel>Sort by</InputLabel>
            <Select
              value={sortBy}
              label="Sort by"
              onChange={e => setSortBy(e.target.value as SortOption)}
            >
              <MenuItem value="created_desc">Newest First</MenuItem>
              <MenuItem value="created_asc">Oldest First</MenuItem>
              <MenuItem value="title_asc">Title A-Z</MenuItem>
              <MenuItem value="title_desc">Title Z-A</MenuItem>
              <MenuItem value="status">By Status</MenuItem>
            </Select>
          </FormControl>

          <Typography
            variant="body2"
            color="text.secondary"
            sx={{ display: 'flex', alignItems: 'center' }}
          >
            {filteredAndSortedTasks.length} task
            {filteredAndSortedTasks.length !== 1 ? 's' : ''}
          </Typography>
        </Stack>
      </Paper>

      {/* Bulk Actions Toolbar */}
      {selectedTaskIds.size > 0 && (
        <Paper sx={{ mb: 2 }}>
          <Toolbar sx={{ pl: 2, pr: 1 }}>
            <Typography
              sx={{ flex: '1 1 100%' }}
              color="inherit"
              variant="subtitle1"
              component="div"
            >
              {selectedTaskIds.size} task{selectedTaskIds.size > 1 ? 's' : ''}{' '}
              selected
            </Typography>
            <Button
              variant="contained"
              color="error"
              startIcon={<DeleteIcon />}
              onClick={() => setDeleteDialogOpen(true)}
            >
              Delete
            </Button>
          </Toolbar>
        </Paper>
      )}

      {/* Task Table */}
      {filteredAndSortedTasks.length === 0 ? (
        <Paper sx={{ p: 4, textAlign: 'center' }}>
          <Typography variant="h6" color="text.secondary" gutterBottom>
            No tasks found
          </Typography>
          <Typography variant="body2" color="text.secondary">
            {statusFilter === 'all'
              ? 'Create your first task to get started!'
              : `No ${statusFilter} tasks found.`}
          </Typography>
        </Paper>
      ) : (
        <TableContainer component={Paper}>
          <Table size="small" sx={{ '& .MuiTableCell-root': { py: 1 } }}>
            <TableHead>
              <TableRow>
                <TableCell padding="checkbox">
                  <Checkbox
                    color="primary"
                    indeterminate={isIndeterminate}
                    checked={isAllSelected}
                    onChange={e => handleSelectAll(e.target.checked)}
                    inputProps={{
                      'aria-label': 'select all tasks',
                    }}
                  />
                </TableCell>
                <TableCell sx={{ fontWeight: 'bold' }}>Title</TableCell>
                {!isMobile && (
                  <TableCell sx={{ fontWeight: 'bold' }}>Description</TableCell>
                )}
                <TableCell sx={{ fontWeight: 'bold', width: 100 }}>
                  Status
                </TableCell>
                <TableCell sx={{ fontWeight: 'bold', width: 120 }}>
                  Created
                </TableCell>
                {!isMobile && (
                  <TableCell sx={{ fontWeight: 'bold', width: 120 }}>
                    Completed
                  </TableCell>
                )}
              </TableRow>
            </TableHead>
            <TableBody>
              {filteredAndSortedTasks.map(task => (
                <TableRow
                  key={task.id}
                  sx={{
                    '&:hover': {
                      backgroundColor: 'action.hover',
                    },
                    '&:last-child td, &:last-child th': { border: 0 },
                    backgroundColor: selectedTaskIds.has(task.id)
                      ? 'action.selected'
                      : 'inherit',
                  }}
                >
                  <TableCell padding="checkbox">
                    <Checkbox
                      color="primary"
                      checked={selectedTaskIds.has(task.id)}
                      onChange={e =>
                        handleSelectTask(task.id, e.target.checked)
                      }
                      inputProps={{
                        'aria-labelledby': `task-${task.id}`,
                      }}
                    />
                  </TableCell>
                  <TableCell>
                    <Box>
                      <Typography
                        id={`task-${task.id}`}
                        variant="body1"
                        component="div"
                        sx={{
                          textDecoration:
                            task.status === TaskStatus.Done
                              ? 'line-through'
                              : 'none',
                          opacity: task.status === TaskStatus.Done ? 0.7 : 1,
                          fontWeight: 500,
                        }}
                      >
                        {task.title}
                      </Typography>
                      {isMobile && task.description && (
                        <Typography
                          variant="body2"
                          color="text.secondary"
                          sx={{ mt: 0.5 }}
                        >
                          {task.description}
                        </Typography>
                      )}
                    </Box>
                  </TableCell>
                  {!isMobile && (
                    <TableCell>
                      <Typography
                        variant="body2"
                        color="text.secondary"
                        sx={{
                          maxWidth: 300,
                          overflow: 'hidden',
                          textOverflow: 'ellipsis',
                          whiteSpace: 'nowrap',
                        }}
                      >
                        {task.description || '—'}
                      </Typography>
                    </TableCell>
                  )}
                  <TableCell>
                    <Chip
                      label={task.status}
                      color={getStatusColor(task.status)}
                      size="small"
                      variant="outlined"
                    />
                  </TableCell>
                  <TableCell>
                    <Typography variant="body2" color="text.secondary">
                      {formatCompactDate(task.created_at)}
                    </Typography>
                  </TableCell>
                  {!isMobile && (
                    <TableCell>
                      <Typography variant="body2" color="text.secondary">
                        {task.completed_at
                          ? formatCompactDate(task.completed_at)
                          : '—'}
                      </Typography>
                    </TableCell>
                  )}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      )}

      {/* Delete Confirmation Dialog */}
      <Dialog
        open={deleteDialogOpen}
        onClose={() => setDeleteDialogOpen(false)}
        aria-labelledby="delete-dialog-title"
        aria-describedby="delete-dialog-description"
      >
        <DialogTitle id="delete-dialog-title">
          Delete {selectedTaskIds.size} task
          {selectedTaskIds.size > 1 ? 's' : ''}?
        </DialogTitle>
        <DialogContent>
          <DialogContentText id="delete-dialog-description">
            This action cannot be undone. Are you sure you want to delete the
            selected task{selectedTaskIds.size > 1 ? 's' : ''}?
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteDialogOpen(false)}>Cancel</Button>
          <Button onClick={handleBulkDelete} color="error" autoFocus>
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}
