import React, { useState, useEffect } from 'react';
import {
  Box,
  Grid,
  Card,
  CardContent,
  Typography,
  Chip,
  Avatar,
  IconButton,
  Menu,
  MenuItem,
  ListItemIcon,
  ListItemText,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  TextField,
  Button,
  FormControl,
  InputLabel,
  Select,
  MenuItem as SelectMenuItem,
} from '@mui/material';
import {
  MoreVert as MoreVertIcon,
  Edit as EditIcon,
  Delete as DeleteIcon,
  Comment as CommentIcon,
  AttachFile as AttachFileIcon,
  Person as PersonIcon,
  Schedule as ScheduleIcon,
  Add as AddIcon,
} from '@mui/icons-material';
import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, closestCorners } from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Task, tasksAPI, User } from '../../services/api';

interface KanbanBoardProps {
  projectId: number;
  tasks: Task[];
  onTaskUpdate: (task: Task) => void;
  onTaskDelete: (taskId: number) => void;
  users: User[];
}

interface TaskCardProps {
  task: Task;
  onEdit: (task: Task) => void;
  onDelete: (task: Task) => void;
  users: User[];
}

interface ColumnProps {
  status: string;
  tasks: Task[];
  onTaskEdit: (task: Task) => void;
  onTaskDelete: (task: Task) => void;
  users: User[];
}

const statusConfig = {
  todo: { label: 'To Do', color: 'default' },
  in_progress: { label: 'In Progress', color: 'warning' },
  review: { label: 'Review', color: 'info' },
  done: { label: 'Done', color: 'success' },
};

const priorityConfig = {
  low: { label: 'Low', color: 'success' },
  medium: { label: 'Medium', color: 'warning' },
  high: { label: 'High', color: 'error' },
  urgent: { label: 'Urgent', color: 'error' },
};

const SortableTaskCard: React.FC<TaskCardProps> = ({ task, onEdit, onDelete, users }) => {
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: task.id });

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

  const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
    event.stopPropagation();
    setAnchorEl(event.currentTarget);
  };

  const handleMenuClose = () => {
    setAnchorEl(null);
  };

  const assignedUser = users.find(user => user.id === task.assigned_to_id);

  return (
    <Card
      ref={setNodeRef}
      style={style}
      {...attributes}
      {...listeners}
      sx={{
        mb: 2,
        cursor: 'grab',
        '&:active': {
          cursor: 'grabbing',
        },
        '&:hover': {
          boxShadow: 4,
        },
      }}
    >
      <CardContent sx={{ p: 2, '&:last-child': { pb: 2 } }}>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 1 }}>
          <Typography variant="subtitle2" sx={{ fontWeight: 600, flexGrow: 1 }}>
            {task.title}
          </Typography>
          <IconButton size="small" onClick={handleMenuOpen}>
            <MoreVertIcon fontSize="small" />
          </IconButton>
        </Box>

        {task.description && (
          <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
            {task.description.length > 100 
              ? `${task.description.substring(0, 100)}...` 
              : task.description
            }
          </Typography>
        )}

        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
          <Chip
            label={priorityConfig[task.priority as keyof typeof priorityConfig]?.label || task.priority}
            size="small"
            color={priorityConfig[task.priority as keyof typeof priorityConfig]?.color as any || 'default'}
            variant="outlined"
          />
        </Box>

        <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
            {assignedUser && (
              <Avatar sx={{ width: 24, height: 24, fontSize: 12 }}>
                {assignedUser.first_name[0]}{assignedUser.last_name[0]}
              </Avatar>
            )}
            {task.comments && task.comments.length > 0 && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                <CommentIcon fontSize="small" color="action" />
                <Typography variant="caption">{task.comments.length}</Typography>
              </Box>
            )}
            {task.files && task.files.length > 0 && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                <AttachFileIcon fontSize="small" color="action" />
                <Typography variant="caption">{task.files.length}</Typography>
              </Box>
            )}
          </Box>
          
          {task.due_date && (
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
              <ScheduleIcon fontSize="small" color="action" />
              <Typography variant="caption">
                {new Date(task.due_date).toLocaleDateString()}
              </Typography>
            </Box>
          )}
        </Box>
      </CardContent>

      <Menu
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={handleMenuClose}
      >
        <MenuItem onClick={() => { onEdit(task); handleMenuClose(); }}>
          <ListItemIcon>
            <EditIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Edit</ListItemText>
        </MenuItem>
        <MenuItem onClick={() => { onDelete(task); handleMenuClose(); }} sx={{ color: 'error.main' }}>
          <ListItemIcon>
            <DeleteIcon fontSize="small" color="error" />
          </ListItemIcon>
          <ListItemText>Delete</ListItemText>
        </MenuItem>
      </Menu>
    </Card>
  );
};

const Column: React.FC<ColumnProps> = ({ status, tasks, onTaskEdit, onTaskDelete, users }) => {
  const config = statusConfig[status as keyof typeof statusConfig];
  
  return (
    <Box sx={{ minHeight: 400 }}>
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
          <Typography variant="h6" sx={{ fontWeight: 600 }}>
            {config?.label || status}
          </Typography>
          <Chip
            label={tasks.length}
            size="small"
            color={config?.color as any || 'default'}
            variant="outlined"
          />
        </Box>
      </Box>
      
      <SortableContext items={tasks.map(task => task.id)} strategy={verticalListSortingStrategy}>
        {tasks.map((task) => (
          <SortableTaskCard
            key={task.id}
            task={task}
            onEdit={onTaskEdit}
            onDelete={onTaskDelete}
            users={users}
          />
        ))}
      </SortableContext>
    </Box>
  );
};

const KanbanBoard: React.FC<KanbanBoardProps> = ({
  projectId,
  tasks,
  onTaskUpdate,
  onTaskDelete,
  users,
}) => {
  const [activeTask, setActiveTask] = useState<Task | null>(null);
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [selectedTask, setSelectedTask] = useState<Task | null>(null);
  const [formData, setFormData] = useState({
    title: '',
    description: '',
    status: '',
    priority: '',
    assigned_to_id: '',
    due_date: '',
  });

  const handleDragStart = (event: DragStartEvent) => {
    const task = tasks.find(t => t.id === event.active.id);
    setActiveTask(task || null);
  };

  const handleDragEnd = async (event: DragEndEvent) => {
    const { active, over } = event;
    setActiveTask(null);

    if (!over) return;

    const task = tasks.find(t => t.id === active.id);
    if (!task) return;

    const newStatus = over.id as string;
    if (task.status === newStatus) return;

    try {
      const updatedTask = { ...task, status: newStatus as Task['status'] };
      await tasksAPI.updateTask(projectId, task.id, { status: newStatus });
      onTaskUpdate(updatedTask);
    } catch (error) {
      console.error('Failed to update task status:', error);
    }
  };

  const handleTaskEdit = (task: Task) => {
    setSelectedTask(task);
    setFormData({
      title: task.title,
      description: task.description || '',
      status: task.status,
      priority: task.priority,
      assigned_to_id: task.assigned_to_id?.toString() || '',
      due_date: task.due_date ? new Date(task.due_date).toISOString().split('T')[0] : '',
    });
    setEditDialogOpen(true);
  };

  const handleTaskDelete = (task: Task) => {
    setSelectedTask(task);
    setDeleteDialogOpen(true);
  };

  const handleUpdateTask = async () => {
    if (!selectedTask) return;

    try {
      const updateData = {
        title: formData.title,
        description: formData.description,
        status: formData.status,
        priority: formData.priority,
        assigned_to_id: formData.assigned_to_id ? parseInt(formData.assigned_to_id) : undefined,
        due_date: formData.due_date || undefined,
      };

      const response = await tasksAPI.updateTask(projectId, selectedTask.id, updateData);
      if (response.success && response.data) {
        onTaskUpdate(response.data);
        setEditDialogOpen(false);
        setSelectedTask(null);
      }
    } catch (error) {
      console.error('Failed to update task:', error);
    }
  };

  const handleConfirmDelete = async () => {
    if (!selectedTask) return;

    try {
      await tasksAPI.deleteTask(projectId, selectedTask.id);
      onTaskDelete(selectedTask.id);
      setDeleteDialogOpen(false);
      setSelectedTask(null);
    } catch (error) {
      console.error('Failed to delete task:', error);
    }
  };

  const tasksByStatus = {
    todo: tasks.filter(task => task.status === 'todo'),
    in_progress: tasks.filter(task => task.status === 'in_progress'),
    review: tasks.filter(task => task.status === 'review'),
    done: tasks.filter(task => task.status === 'done'),
  };

  return (
    <Box>
      <DndContext
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
        collisionDetection={closestCorners}
      >
        <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: 3 }}>
          {Object.entries(tasksByStatus).map(([status, statusTasks]) => (
            <Column
              key={status}
              status={status}
              tasks={statusTasks}
              onTaskEdit={handleTaskEdit}
              onTaskDelete={handleTaskDelete}
              users={users}
            />
          ))}
        </Box>

        <DragOverlay>
          {activeTask ? (
            <SortableTaskCard
              task={activeTask}
              onEdit={handleTaskEdit}
              onDelete={handleTaskDelete}
              users={users}
            />
          ) : null}
        </DragOverlay>
      </DndContext>

      {/* Edit Task Dialog */}
      <Dialog open={editDialogOpen} onClose={() => setEditDialogOpen(false)} maxWidth="sm" fullWidth>
        <DialogTitle>Edit Task</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            margin="dense"
            label="Title"
            fullWidth
            variant="outlined"
            value={formData.title}
            onChange={(e) => setFormData({ ...formData, title: e.target.value })}
            sx={{ mb: 2 }}
          />
          
          <TextField
            margin="dense"
            label="Description"
            fullWidth
            multiline
            rows={3}
            variant="outlined"
            value={formData.description}
            onChange={(e) => setFormData({ ...formData, description: e.target.value })}
            sx={{ mb: 2 }}
          />

          <Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 2, mb: 2 }}>
            <FormControl fullWidth>
              <InputLabel>Status</InputLabel>
              <Select
                value={formData.status}
                label="Status"
                onChange={(e) => setFormData({ ...formData, status: e.target.value })}
              >
                {Object.entries(statusConfig).map(([value, config]) => (
                  <SelectMenuItem key={value} value={value}>
                    {config.label}
                  </SelectMenuItem>
                ))}
              </Select>
            </FormControl>
            
            <FormControl fullWidth>
              <InputLabel>Priority</InputLabel>
              <Select
                value={formData.priority}
                label="Priority"
                onChange={(e) => setFormData({ ...formData, priority: e.target.value })}
              >
                {Object.entries(priorityConfig).map(([value, config]) => (
                  <SelectMenuItem key={value} value={value}>
                    {config.label}
                  </SelectMenuItem>
                ))}
              </Select>
            </FormControl>
          </Box>

          <FormControl fullWidth sx={{ mb: 2 }}>
            <InputLabel>Assigned To</InputLabel>
            <Select
              value={formData.assigned_to_id}
              label="Assigned To"
              onChange={(e) => setFormData({ ...formData, assigned_to_id: e.target.value })}
            >
              <SelectMenuItem value="">Unassigned</SelectMenuItem>
              {users.map((user) => (
                <SelectMenuItem key={user.id} value={user.id.toString()}>
                  {user.first_name} {user.last_name}
                </SelectMenuItem>
              ))}
            </Select>
          </FormControl>

          <TextField
            margin="dense"
            label="Due Date"
            type="date"
            fullWidth
            variant="outlined"
            value={formData.due_date}
            onChange={(e) => setFormData({ ...formData, due_date: e.target.value })}
            InputLabelProps={{ shrink: true }}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setEditDialogOpen(false)}>Cancel</Button>
          <Button
            onClick={handleUpdateTask}
            variant="contained"
            disabled={!formData.title.trim()}
          >
            Update Task
          </Button>
        </DialogActions>
      </Dialog>

      {/* Delete Task Dialog */}
      <Dialog open={deleteDialogOpen} onClose={() => setDeleteDialogOpen(false)}>
        <DialogTitle>Delete Task</DialogTitle>
        <DialogContent>
          <Typography>
            Are you sure you want to delete "{selectedTask?.title}"? This action cannot be undone.
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteDialogOpen(false)}>Cancel</Button>
          <Button onClick={handleConfirmDelete} color="error" variant="contained">
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default KanbanBoard;
