// React Imports
import { useState, useEffect, forwardRef } from 'react'
import type { SyntheticEvent } from 'react'

// MUI Imports
import Drawer from '@mui/material/Drawer'
import IconButton from '@mui/material/IconButton'
import Typography from '@mui/material/Typography'
import Button from '@mui/material/Button'
import Checkbox from '@mui/material/Checkbox'
import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem'
import ListItemIcon from '@mui/material/ListItemIcon'
import ListItemText from '@mui/material/ListItemText'
import Divider from '@mui/material/Divider'
import Box from '@mui/material/Box'
import Chip from '@mui/material/Chip'
import Avatar from '@mui/material/Avatar'
import Switch from '@mui/material/Switch'
import FormControlLabel from '@mui/material/FormControlLabel'
import { useTheme } from '@mui/material/styles'

// Third-party Imports
import { useForm, Controller } from 'react-hook-form'
import PerfectScrollbar from 'react-perfect-scrollbar'
import classnames from 'classnames'

// Type Imports
import type { TodoType } from '@/types/apps/todoTypes'
import type { ThemeColor } from '@core/types'

// Component Imports
import CustomTextField from '@core/components/mui/TextField'
import AppReactDatepicker from '@/libs/styles/AppReactDatepicker'

// API Imports
import { todoService } from '@/libs/api'

type Props = {
  open: boolean
  onClose: () => void
  todoData?: TodoType[]
  setData: (data: TodoType[]) => void
  editTodo?: TodoType | null
  setEditTodo: (todo: TodoType | null) => void
  isBelowMdScreen: boolean
}

type FormValidateType = {
  title: string
  description: string
}

const defaultLabels = ['Frontend', 'Backend', 'Doc', 'Bug']
const defaultLabelColors: Record<string, ThemeColor> = {
  Frontend: 'primary',
  Backend: 'warning',
  Doc: 'success',
  Bug: 'error'
}

const STORAGE_KEY = 'todo_custom_labels'
const STORAGE_COLORS_KEY = 'todo_label_colors'

// Helper functions for localStorage
const getCustomLabels = (): string[] => {
  if (typeof window === 'undefined') return []
  try {
    const stored = localStorage.getItem(STORAGE_KEY)
    return stored ? JSON.parse(stored) : []
  } catch {
    return []
  }
}

const saveCustomLabels = (labels: string[]) => {
  if (typeof window === 'undefined') return
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(labels))
  } catch (error) {
    console.error('Error saving custom labels:', error)
  }
}

const getLabelColors = (): Record<string, ThemeColor> => {
  if (typeof window === 'undefined') return defaultLabelColors
  try {
    const stored = localStorage.getItem(STORAGE_COLORS_KEY)
    const customColors = stored ? JSON.parse(stored) : {}
    return { ...defaultLabelColors, ...customColors }
  } catch {
    return defaultLabelColors
  }
}

const saveLabelColor = (label: string, color: ThemeColor) => {
  if (typeof window === 'undefined') return
  try {
    // Save colors for all labels (both default and custom)
    const stored = localStorage.getItem(STORAGE_COLORS_KEY)
    const customColors = stored ? JSON.parse(stored) : {}
    customColors[label] = color
    localStorage.setItem(STORAGE_COLORS_KEY, JSON.stringify(customColors))
  } catch (error) {
    console.error('Error saving label color:', error)
  }
}

// Custom Input Component for Date Range
type CustomInputProps = {
  label?: string
  start?: Date | null
  end?: Date | null
  onClick?: () => void
  onKeyDown?: () => void
  readOnly?: boolean
  value?: string
}

const CustomDateRangeInput = forwardRef<HTMLInputElement, CustomInputProps>((props, ref) => {
  const { start, end, onClick, onKeyDown, readOnly, ...rest } = props
  const formatDate = (date: Date | null) => {
    if (!date) return ''
    return date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' })
  }

  const startDateStr = start ? formatDate(start) : ''
  const endDateStr = end ? formatDate(end) : ''
  const value = startDateStr && endDateStr ? `${startDateStr} - ${endDateStr}` : startDateStr || endDateStr || ''

  return (
    <CustomTextField
      {...rest}
      inputRef={ref}
      value={value}
      label='Date Range (Start - Due)'
      fullWidth
      onClick={onClick}
      onKeyDown={onKeyDown}
      slotProps={{
        input: {
          readOnly: readOnly
        }
      }}
    />
  )
})

CustomDateRangeInput.displayName = 'CustomDateRangeInput'

const TodoTaskSidebar = (props: Props) => {
  // Props
  const { open, onClose, todoData, setData, editTodo, setEditTodo, isBelowMdScreen } = props

  // States
  const [selectedLabels, setSelectedLabels] = useState<string[]>([])
  const [isImportant, setIsImportant] = useState(false)
  const [isStarred, setIsStarred] = useState(false)
  const [isKanban, setIsKanban] = useState(false)
  const [labelsAnchorEl, setLabelsAnchorEl] = useState<null | HTMLElement>(null)
  const [startDate, setStartDate] = useState<Date | null>(null)
  const [endDate, setEndDate] = useState<Date | null>(null)
  const [customLabels, setCustomLabels] = useState<string[]>(getCustomLabels())
  const [labelColors, setLabelColors] = useState<Record<string, ThemeColor>>(getLabelColors())
  const [newLabelInput, setNewLabelInput] = useState('')
  const [colorMenuAnchor, setColorMenuAnchor] = useState<{ el: HTMLElement; label: string } | null>(null)

  // Hooks
  const theme = useTheme()
  const {
    control,
    reset: resetForm,
    handleSubmit,
    formState: { errors },
    setValue,
    watch
  } = useForm<FormValidateType>({
    defaultValues: {
      title: '',
      description: ''
    }
  })

  const titleValue = watch('title')

  // Reset form when editTodo changes
  useEffect(() => {
    if (editTodo) {
      setValue('title', editTodo.title)
      setValue('description', editTodo.description)
      setSelectedLabels(editTodo.labels || [])
      setIsImportant(editTodo.isImportant)
      setIsStarred(editTodo.isStarred)
      setIsKanban(editTodo.isKanban || false)
      setStartDate(editTodo.startDate ? new Date(editTodo.startDate) : null)
      setEndDate(editTodo.dueDate ? new Date(editTodo.dueDate) : null)
    } else {
      resetForm({
        title: '',
        description: ''
      })
      setSelectedLabels([])
      setIsImportant(false)
      setIsStarred(false)
      setIsKanban(false)
      setStartDate(null)
      setEndDate(null)
    }
  }, [editTodo, setValue, resetForm])

  const handleLabelsMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
    setLabelsAnchorEl(event.currentTarget)
  }

  const handleLabelsMenuClose = () => {
    setLabelsAnchorEl(null)
    setNewLabelInput('')
    setColorMenuAnchor(null)
  }

  const handleLabelToggle = (label: string) => {
    setSelectedLabels(prev =>
      prev.includes(label) ? prev.filter(l => l !== label) : [...prev, label]
    )
  }

  // Get all available labels (default + custom)
  const availableLabels = [...defaultLabels, ...customLabels]

  // Handle adding new label
  const handleAddLabel = () => {
    const trimmedLabel = newLabelInput.trim()
    if (trimmedLabel && !availableLabels.includes(trimmedLabel)) {
      const updatedCustomLabels = [...customLabels, trimmedLabel]
      setCustomLabels(updatedCustomLabels)
      saveCustomLabels(updatedCustomLabels)
      
      // Set default color for new label (cycle through available colors)
      const colors: ThemeColor[] = ['primary', 'secondary', 'success', 'error', 'warning', 'info']
      const defaultColor = colors[updatedCustomLabels.length % colors.length] || 'default'
      const updatedColors = { ...labelColors, [trimmedLabel]: defaultColor }
      setLabelColors(updatedColors)
      saveLabelColor(trimmedLabel, defaultColor)
      
      setNewLabelInput('')
    }
  }

  // Handle Enter key in new label input
  const handleNewLabelKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === 'Enter') {
      event.preventDefault()
      handleAddLabel()
    }
  }

  // Handle color menu open
  const handleColorMenuOpen = (event: React.MouseEvent<HTMLElement>, label: string) => {
    event.stopPropagation()
    setColorMenuAnchor({ el: event.currentTarget, label })
  }

  // Handle color menu close
  const handleColorMenuClose = () => {
    setColorMenuAnchor(null)
  }

  // Handle color change
  const handleColorChange = (label: string, color: ThemeColor) => {
    const updatedColors = { ...labelColors, [label]: color }
    setLabelColors(updatedColors)
    saveLabelColor(label, color)
    handleColorMenuClose()
  }

  // Get color value from theme
  const getColorValue = (colorName: ThemeColor): string => {
    const colorMap: Record<ThemeColor, string> = {
      primary: theme.palette.primary.main,
      secondary: theme.palette.secondary.main,
      success: theme.palette.success.main,
      error: theme.palette.error.main,
      warning: theme.palette.warning.main,
      info: theme.palette.info.main
    }
    return colorMap[colorName] || theme.palette.grey[500]
  }

  // Available colors for selection
  const availableColors: ThemeColor[] = ['primary', 'secondary', 'success', 'error', 'warning', 'info']

  const handleDateRangeChange = (dates: [Date | null, Date | null]) => {
    const [start, end] = dates
    setStartDate(start)
    setEndDate(end)
  }

  const onSubmit = async (data: FormValidateType) => {
    try {
      const startDateString = startDate ? new Date(startDate).toISOString() : undefined
      const dueDateString = endDate ? new Date(endDate).toISOString() : undefined

      if (editTodo) {
        // Update existing todo
        const updatedTodo = await todoService.updateTodo(editTodo.id, {
          title: data.title,
          description: data.description,
          labels: selectedLabels,
          isImportant,
          isStarred,
          isKanban,
          startDate: startDateString,
          dueDate: dueDateString
        })
        const updatedTodos = todoData?.map(todo => (todo.id === editTodo.id ? updatedTodo : todo))
        setData(updatedTodos || [])
      } else {
        // Add new todo using API
        const newTodo = await todoService.createTodo({
          title: data.title,
          description: data.description,
          status: 'pending',
          priority: 'medium',
          labels: selectedLabels,
          isImportant,
          isStarred,
          isKanban,
          startDate: startDateString,
          dueDate: dueDateString,
          routine: 0 // NONE
        })
        
        // Update state with the todo returned from API
        setData([...(todoData ?? []), newTodo])
      }
      handleClose()
    } catch (error) {
      console.error('Error saving todo:', error)
      // TODO: Show error message to user (e.g., using a toast notification)
    }
  }

  const handleClose = () => {
    onClose()
    setEditTodo(null)
    setSelectedLabels([])
    setIsImportant(false)
    setIsStarred(false)
    setIsKanban(false)
    setStartDate(null)
    setEndDate(null)
    resetForm({
      title: '',
      description: ''
    })
  }

  const isFormValid = titleValue && titleValue.trim().length > 0

  return (
    <Drawer
      open={open}
      anchor='right'
      variant='temporary'
      onClose={handleClose}
      ModalProps={{ keepMounted: true }}
      sx={{
        zIndex: isBelowMdScreen ? 12 : 11,
        '& .MuiDrawer-paper': {
          width: { xs: 300, sm: 400 },
          boxShadow: 'none',
          borderLeft: '1px solid var(--mui-palette-divider)'
        }
      }}
    >
      <div className='flex items-center justify-between plb-5 pli-6 border-be border-solid border-bs'>
        <Typography variant='h5' className='font-semibold'>
          {editTodo ? 'Edit Task' : 'Add Task'}
        </Typography>
        <IconButton size='small' onClick={handleClose}>
          <i className='tabler-x text-xl text-textPrimary' />
        </IconButton>
      </div>
      <div className='flex items-center justify-between p-4 border-be border-solid border-bs'>
        <div className='flex items-center gap-2'>
          <IconButton
            size='small'
            onClick={() => setIsImportant(!isImportant)}
            className={classnames({ 'text-success': isImportant })}
          >
            <i className='tabler-info-circle text-lg' />
          </IconButton>
          <IconButton
            size='small'
            onClick={() => setIsStarred(!isStarred)}
            className={classnames({ 'text-warning': isStarred })}
          >
            <i className={classnames('tabler-star text-lg', { 'fill-current': isStarred })} />
          </IconButton>
          <IconButton size='small' onClick={handleLabelsMenuOpen}>
            <i className='tabler-tag text-lg text-textSecondary' />
          </IconButton>
          <FormControlLabel
            control={
              <Switch
                checked={isKanban}
                onChange={(e) => setIsKanban(e.target.checked)}
                size='small'
              />
            }
            label='Kanban'
            sx={{ margin: 0, marginLeft: 1 }}
          />
          <Menu
            anchorEl={labelsAnchorEl}
            open={Boolean(labelsAnchorEl)}
            onClose={handleLabelsMenuClose}
            anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
            transformOrigin={{ vertical: 'top', horizontal: 'left' }}
            PaperProps={{
              sx: { minWidth: 250 }
            }}
          >
            {availableLabels.map(label => {
              const labelColor = labelColors[label] || 'default'
              const colorValue = getColorValue(labelColor)
              
              return (
                <MenuItem 
                  key={label} 
                  onClick={() => handleLabelToggle(label)}
                  sx={{ display: 'flex', alignItems: 'center', gap: 1 }}
                >
                  <ListItemIcon sx={{ minWidth: 40 }}>
                    <Checkbox checked={selectedLabels.includes(label)} />
                  </ListItemIcon>

                  <ListItemText primary={label} sx={{ flex: 1 }} />
                  <IconButton
                    size='small'
                    onClick={(e) => handleColorMenuOpen(e, label)}
                    sx={{ padding: 0.5 }}
                  >
                    <i className='tabler-palette text-base' />
                  </IconButton>
                  <Button
                    size='small'
                    sx={{
                      minWidth: 10,
                      width: 10,
                      height: 10,
                      padding: 0,
                      bgcolor: colorValue,
                      borderRadius: '50%',
                      '&:hover': {
                        bgcolor: colorValue,
                        opacity: 0.8
                      }
                    }}
                  />
                </MenuItem>
              )
            })}
            <Divider />
            <Box className='flex flex-col gap-2 p-2'>
              <CustomTextField
                size='small'
                placeholder='برچسب جدید...'
                value={newLabelInput}
                onChange={(e) => setNewLabelInput(e.target.value)}
                onKeyDown={handleNewLabelKeyDown}
                fullWidth
              />
              <Button
                variant='contained'
                size='small'
                onClick={handleAddLabel}
                disabled={!newLabelInput.trim() || availableLabels.includes(newLabelInput.trim())}
                fullWidth
              >
                افزودن برچسب
              </Button>
            </Box>
          </Menu>
          {/* Color Selection Menu */}
          <Menu
            anchorEl={colorMenuAnchor?.el || null}
            open={Boolean(colorMenuAnchor)}
            onClose={handleColorMenuClose}
            anchorOrigin={{ vertical: 'center', horizontal: 'right' }}
            transformOrigin={{ vertical: 'center', horizontal: 'left' }}
            PaperProps={{
              sx: { padding: 1 }
            }}
          >
            <Box sx={{ display: 'flex', gap: 1, flexDirection: 'row' }}>
              {availableColors.map(color => {
                const colorValue = getColorValue(color)
                const currentLabel = colorMenuAnchor?.label
                const isSelected = currentLabel && labelColors[currentLabel] === color
                
                return (
                  <Button
                  size='small'
                  sx={{
                    minWidth: 10,
                    width: 20,
                    height: 20,
                    padding: 0,
                    bgcolor: colorValue,
                    borderRadius: '50%',
                    '&:hover': {
                      bgcolor: colorValue,
                      opacity: 0.8
                    }
                  }}
                />
   
                )
              })}
            </Box>
          </Menu>
        </div>
      </div>
      <PerfectScrollbar>
        <form onSubmit={handleSubmit(onSubmit)} className='flex flex-col gap-6 p-6'>
          <Controller
            name='title'
            control={control}
            rules={{ required: true }}
            render={({ field }) => (
              <CustomTextField
                {...field}
                fullWidth
                placeholder='عنوان'
                {...(errors.title && { error: true, helperText: 'This field is required.' })}
              />
            )}
          />
          <Controller
            name='description'
            control={control}
            render={({ field }) => (
              <CustomTextField
                {...field}
                fullWidth
                multiline
                rows={5}
                placeholder='توضیحات'
              />
            )}
          />
          {selectedLabels.length > 0 && (
            <Box className='flex flex-wrap gap-2'>
              {selectedLabels.map(label => (
                <Chip
                  key={label}
                  label={label}
                  size='small'
                  variant='tonal'
                  color={labelColors[label] || 'default'}
                  onDelete={() => handleLabelToggle(label)}
                />
              ))}
            </Box>
          )}
          <AppReactDatepicker
            selectsRange
            startDate={startDate || undefined}
            endDate={endDate || undefined}
            selected={startDate || undefined}
            onChange={handleDateRangeChange}
            shouldCloseOnSelect={false}
            dateFormat='yyyy-MM-dd'
            customInput={<CustomDateRangeInput start={startDate} end={endDate} />}
          />
          <Divider />
          <div className='flex items-center justify-end gap-2'>
            <Button variant='outlined' onClick={handleClose}>
              Cancel
            </Button>
            <Button variant='contained' type='submit' disabled={!isFormValid}>
              {editTodo ? 'به‌روزرسانی' : 'افزودن'}
            </Button>
          </div>
        </form>
      </PerfectScrollbar>
    </Drawer>
  )
}

export default TodoTaskSidebar

