'use client'

// React Imports
import { useEffect, useState, useRef } from 'react'

// MUI Imports
import { useMediaQuery } from '@mui/material'
import Backdrop from '@mui/material/Backdrop'
import Box from '@mui/material/Box'
import type { Theme } from '@mui/material/styles'

// Third-party Imports
import classnames from 'classnames'

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

// Component Imports
import TodoSidebar from './TodoSidebar'
import TodoContent from './TodoContent'
import TodoTaskSidebar from './TodoTaskSidebar'

// Hook Imports
import { useSettings } from '@core/hooks/useSettings'

// Util Imports
import { commonLayoutClasses } from '@layouts/utils/layoutClasses'

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

const TodoList = () => {
  // States
  const [todos, setTodos] = useState<TodoType[]>([])
  const [filteredTodos, setFilteredTodos] = useState<TodoType[]>([])
  const [activeFilter, setActiveFilter] = useState<string>('all')
  const [selectedLabel, setSelectedLabel] = useState<string | null>(null)
  const [searchTerm, setSearchTerm] = useState('')
  const [sidebarOpen, setSidebarOpen] = useState(false)
  const [taskSidebarOpen, setTaskSidebarOpen] = useState(false)
  const [backdropOpen, setBackdropOpen] = useState(false)
  const [editTodo, setEditTodo] = useState<TodoType | null>(null)

  // Refs
  const isInitialMount = useRef(true)

  // Hooks
  const { settings } = useSettings()
  const isBelowLgScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'))
  const isBelowMdScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down('md'))
  const isBelowSmScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm'))

  // Load data from API on mount and when filters change
  useEffect(() => {
    const loadTodos = async () => {
      try {
        const response = await todoService.getTodos({
          filter: activeFilter === 'all' ? undefined : (activeFilter as any),
          label: selectedLabel || undefined,
          search: searchTerm || undefined
        })
        setTodos(response.todos)
        setFilteredTodos(response.todos)
      } catch (error) {
        console.error('Error loading todos:', error)
      }
    }
    loadTodos()
  }, [activeFilter, selectedLabel, searchTerm])

  // Filter todos based on activeFilter, selectedLabel, and searchTerm
  useEffect(() => {
    let filtered = [...todos]

    // Filter by active filter
    if (activeFilter === 'starred') {
      filtered = filtered.filter(todo => todo.isStarred)
    } else if (activeFilter === 'important') {
      filtered = filtered.filter(todo => todo.isImportant)
    } else if (activeFilter === 'completed') {
      filtered = filtered.filter(todo => todo.status === 'completed')
    } else if (activeFilter === 'trashed') {
      filtered = filtered.filter(todo => todo.isTrashed)
    } else if (activeFilter === 'all') {
      filtered = filtered.filter(todo => !todo.isTrashed)
    }

    // Filter by selected label
    if (selectedLabel) {
      filtered = filtered.filter(todo => todo.labels.includes(selectedLabel))
    }

    // Filter by search term
    if (searchTerm) {
      const searchLower = searchTerm.toLowerCase()
      filtered = filtered.filter(
        todo =>
          todo.title.toLowerCase().includes(searchLower) ||
          todo.description.toLowerCase().includes(searchLower)
      )
    }

    setFilteredTodos(filtered)
  }, [todos, activeFilter, selectedLabel, searchTerm])

  // Handle backdrop on click
  const handleBackdropClick = () => {
    setSidebarOpen(false)
    setBackdropOpen(false)
  }

  // Hide backdrop when left sidebar is closed
  useEffect(() => {
    if (backdropOpen && !sidebarOpen) {
      setBackdropOpen(false)
    }
  }, [sidebarOpen, backdropOpen])

  // Hide backdrop when screen size is above md and set sidebar open state
  useEffect(() => {
    if (backdropOpen && !isBelowMdScreen) {
      setBackdropOpen(false)
    }

    if (!isBelowMdScreen) {
      setSidebarOpen(true)
    } else if (sidebarOpen && !isBelowMdScreen) {
      setSidebarOpen(false)
    }
  }, [isBelowMdScreen, backdropOpen, sidebarOpen])

  // Set loading false on initial mount
  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false
    }
  }, [])

  // Handlers
  const handleAddTask = () => {
    setEditTodo(null)
    setTaskSidebarOpen(true)
  }

  const handleTodoClick = (todo: TodoType) => {
    setEditTodo(todo)
    setTaskSidebarOpen(true)
  }

  const handleToggleComplete = async (id: number) => {
    try {
      const todo = todos.find(t => t.id === id)
      if (todo) {
        const updatedTodo = await todoService.updateTodo(id, {
          status: todo.status === 'completed' ? 'pending' : 'completed'
        })
        setTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
        setFilteredTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
      }
    } catch (error) {
      console.error('Error updating todo:', error)
    }
  }

  const handleToggleStar = async (id: number) => {
    try {
      const todo = todos.find(t => t.id === id)
      if (todo) {
        const updatedTodo = await todoService.updateTodo(id, {
          isStarred: !todo.isStarred
        })
        setTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
        setFilteredTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
      }
    } catch (error) {
      console.error('Error updating todo:', error)
    }
  }

  const handleToggleImportant = async (id: number) => {
    try {
      const todo = todos.find(t => t.id === id)
      if (todo) {
        const updatedTodo = await todoService.updateTodo(id, {
          isImportant: !todo.isImportant
        })
        setTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
        setFilteredTodos(prevTodos => prevTodos.map(t => (t.id === id ? updatedTodo : t)))
      }
    } catch (error) {
      console.error('Error updating todo:', error)
    }
  }

  const handleDelete = async (id: number) => {
    try {
      await todoService.deleteTodo(id)
      setTodos(prevTodos => prevTodos.filter(todo => todo.id !== id))
      setFilteredTodos(prevTodos => prevTodos.filter(todo => todo.id !== id))
    } catch (error) {
      console.error('Error deleting todo:', error)
    }
  }

  const handleSidebarToggle = () => {
    setSidebarOpen(!sidebarOpen)
    if (!sidebarOpen) {
      setBackdropOpen(true)
    }
  }

  return (
    <div
      className={classnames(commonLayoutClasses.contentHeightFixed, 'flex is-full bs-full overflow-hidden rounded relative', {
        border: settings.skin === 'bordered',
        'shadow-md': settings.skin !== 'bordered'
      })}
    >
      <TodoSidebar
        isBelowMdScreen={isBelowMdScreen}
        sidebarOpen={sidebarOpen}
        setSidebarOpen={setSidebarOpen}
        activeFilter={activeFilter}
        setActiveFilter={setActiveFilter}
        selectedLabel={selectedLabel}
        setSelectedLabel={setSelectedLabel}
        onAddTask={handleAddTask}
      />
      <Backdrop open={backdropOpen} onClick={handleBackdropClick} className='absolute z-10' />
      <Box className='flex-1 min-is-0' sx={{ width: '100%' }}>
        <TodoContent
          todos={filteredTodos}
          searchTerm={searchTerm}
          setSearchTerm={setSearchTerm}
          onToggleComplete={handleToggleComplete}
          onToggleStar={handleToggleStar}
          onToggleImportant={handleToggleImportant}
          onDelete={handleDelete}
          onTodoClick={handleTodoClick}
          onUpdate={(updatedTodo) => {
            setTodos(prevTodos => prevTodos.map(t => (t.id === updatedTodo.id ? updatedTodo : t)))
            setFilteredTodos(prevTodos => prevTodos.map(t => (t.id === updatedTodo.id ? updatedTodo : t)))
          }}
          isBelowMdScreen={isBelowMdScreen}
          onSidebarToggle={handleSidebarToggle}
        />
      </Box>
      <TodoTaskSidebar
        open={taskSidebarOpen}
        onClose={() => setTaskSidebarOpen(false)}
        todoData={todos}
        setData={setTodos}
        editTodo={editTodo}
        setEditTodo={setEditTodo}
        isBelowMdScreen={isBelowMdScreen}
      />
    </div>
  )
}

export default TodoList
