import { useState, useEffect, useMemo, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { motion, AnimatePresence } from 'framer-motion'
import { Check, Flame, TrendingUp, Zap, Sparkles, Undo2, Plus, Calendar, AlertTriangle, LogOut, Snowflake } from 'lucide-react'
import { format, startOfWeek, differenceInDays, parseISO, isToday, isTomorrow, isPast, startOfDay, isBefore, isAfter } from 'date-fns'
import { ru } from 'date-fns/locale'
import { habitsApi } from '../api/habits'
import { tasksApi } from '../api/tasks'
import { useAuthStore } from '../store/auth'
import Navigation from '../components/Navigation'
import CreateTaskModal from '../components/CreateTaskModal'
import LogHabitModal from '../components/LogHabitModal'
import clsx from 'clsx'

// Check if habit is frozen on a specific date
function isHabitFrozenOnDate(habit, freezes, date) {
  if (!freezes || freezes.length === 0) return false
  const checkDate = startOfDay(date)
  return freezes.some(freeze => {
    const start = startOfDay(parseISO(freeze.start_date))
    const end = startOfDay(parseISO(freeze.end_date))
    return !isBefore(checkDate, start) && !isAfter(checkDate, end)
  })
}

// Определение "сегодняшних" привычек
function shouldShowToday(habit, lastLogDate, freezes) {
  const today = startOfDay(new Date())
  const dayOfWeek = today.getDay() || 7
  
  if (isHabitFrozenOnDate(habit, freezes, today)) return false
  
  const startDate = habit.start_date 
    ? startOfDay(parseISO(habit.start_date)) 
    : startOfDay(parseISO(habit.created_at))
  
  if (today < startDate) return false
  
  if (habit.frequency === "daily") return true
  
  if (habit.frequency === "weekly") {
    if (habit.target_days && habit.target_days.length > 0) {
      return habit.target_days.includes(dayOfWeek)
    }
    if (!lastLogDate) return true
    const weekStart = startOfWeek(today, { weekStartsOn: 1 })
    const lastLog = typeof lastLogDate === "string" ? parseISO(lastLogDate) : lastLogDate
    return lastLog < weekStart
  }
  
  if (habit.frequency === "interval" && habit.target_count > 0) {
    const daysSinceStart = differenceInDays(today, startDate)
    return daysSinceStart % habit.target_count === 0
  }
  
  if (habit.frequency === "custom" && habit.target_count > 0) {
    if (!lastLogDate) return today >= startDate
    const lastLog = typeof lastLogDate === "string" ? parseISO(lastLogDate) : lastLogDate
    const daysSinceLastLog = differenceInDays(today, startOfDay(lastLog))
    return daysSinceLastLog >= habit.target_count
  }
  
  return true
}

function formatDueDate(dateStr) {
  if (!dateStr) return null
  const date = parseISO(dateStr)
  if (isToday(date)) return 'Сегодня'
  if (isTomorrow(date)) return 'Завтра'
  return format(date, 'd MMM', { locale: ru })
}

export default function Home() {
  const [todayLogs, setTodayLogs] = useState({})
  const [lastLogDates, setLastLogDates] = useState({})
  const [habitFreezes, setHabitFreezes] = useState({})
  const [habitLogs, setHabitLogs] = useState({})
  const [showCreateTask, setShowCreateTask] = useState(false)
  const [logHabitModal, setLogHabitModal] = useState({ open: false, habit: null })
  const queryClient = useQueryClient()
  const { user, logout } = useAuthStore()

  const { data: habits = [], isLoading: habitsLoading } = useQuery({
    queryKey: ['habits'],
    queryFn: habitsApi.list,
  })

  const { data: stats } = useQuery({
    queryKey: ['stats'],
    queryFn: habitsApi.getStats,
  })

  const { data: todayTasks = [], isLoading: tasksLoading } = useQuery({
    queryKey: ['tasks-today'],
    queryFn: tasksApi.today,
  })

  useEffect(() => {
    if (habits.length > 0) {
      loadTodayLogs()
      loadHabitFreezes()
    }
  }, [habits])

  const loadTodayLogs = async () => {
    const today = format(new Date(), 'yyyy-MM-dd')
    const logsMap = {}
    const lastDates = {}
    const allLogs = {}
    
    await Promise.all(habits.map(async (habit) => {
      try {
        const logs = await habitsApi.getLogs(habit.id, 90)
        allLogs[habit.id] = logs.map(l => l.date)
        
        if (logs.length > 0) {
          const lastLog = logs[0]
          const logDate = lastLog.date.split('T')[0]
          lastDates[habit.id] = logDate
          if (logDate === today) logsMap[habit.id] = lastLog.id
        }
      } catch (e) {
        console.error('Error loading logs for habit', habit.id, e)
      }
    }))
    
    setTodayLogs(logsMap)
    setLastLogDates(lastDates)
    setHabitLogs(allLogs)
  }

  const loadHabitFreezes = async () => {
    const freezesMap = {}
    await Promise.all(habits.map(async (habit) => {
      try {
        const freezes = await habitsApi.getFreezes(habit.id)
        freezesMap[habit.id] = freezes
      } catch (e) {
        freezesMap[habit.id] = []
      }
    }))
    setHabitFreezes(freezesMap)
  }

  const logMutation = useMutation({
    mutationFn: ({ habitId, date }) => habitsApi.log(habitId, date ? { date } : {}),
    onSuccess: (data, { habitId, date }) => {
      const logDate = date || format(new Date(), 'yyyy-MM-dd')
      const today = format(new Date(), 'yyyy-MM-dd')
      
      if (logDate === today) setTodayLogs(prev => ({ ...prev, [habitId]: data.id }))
      setLastLogDates(prev => ({ ...prev, [habitId]: logDate }))
      setHabitLogs(prev => ({ ...prev, [habitId]: [...(prev[habitId] || []), logDate] }))
      queryClient.invalidateQueries({ queryKey: ['habits'] })
      queryClient.invalidateQueries({ queryKey: ['stats'] })
    },
  })

  const deleteLogMutation = useMutation({
    mutationFn: ({ habitId, logId }) => habitsApi.deleteLog(habitId, logId),
    onSuccess: (_, { habitId }) => {
      setTodayLogs(prev => {
        const newLogs = { ...prev }
        delete newLogs[habitId]
        return newLogs
      })
      loadTodayLogs()
      queryClient.invalidateQueries({ queryKey: ['habits'] })
      queryClient.invalidateQueries({ queryKey: ['stats'] })
    },
  })

  const completeTaskMutation = useMutation({
    mutationFn: (id) => tasksApi.complete(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tasks-today'] })
      queryClient.invalidateQueries({ queryKey: ['tasks'] })
    },
  })

  const uncompleteTaskMutation = useMutation({
    mutationFn: (id) => tasksApi.uncomplete(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tasks-today'] })
      queryClient.invalidateQueries({ queryKey: ['tasks'] })
    },
  })

  const handleToggleComplete = (habitId) => {
    if (todayLogs[habitId]) {
      deleteLogMutation.mutate({ habitId, logId: todayLogs[habitId] })
    } else {
      logMutation.mutate({ habitId })
    }
  }

  const handleLogHabitDate = async (habitId, date) => {
    await logMutation.mutateAsync({ habitId, date })
  }

  const handleToggleTask = (task) => {
    if (task.completed) uncompleteTaskMutation.mutate(task.id)
    else completeTaskMutation.mutate(task.id)
  }

  const todayHabits = useMemo(() => {
    return habits.filter(habit => shouldShowToday(habit, lastLogDates[habit.id], habitFreezes[habit.id]))
  }, [habits, lastLogDates, habitFreezes])

  const frozenHabits = useMemo(() => {
    const today = startOfDay(new Date())
    return habits.filter(habit => isHabitFrozenOnDate(habit, habitFreezes[habit.id], today))
  }, [habits, habitFreezes])

  const completedCount = Object.keys(todayLogs).length
  const totalToday = todayHabits.length
  const today = format(new Date(), 'EEEE, d MMMM', { locale: ru })
  const activeTasks = todayTasks.filter(t => !t.completed)

  return (
    <div className="min-h-screen bg-surface-50 dark:bg-gray-950 gradient-mesh pb-24 transition-colors duration-300">
      <header className="bg-white/70 dark:bg-gray-900/70 backdrop-blur-xl border-b border-gray-100/50 dark:border-gray-800 sticky top-0 z-10">
        <div className="max-w-lg mx-auto px-4 py-4 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center shadow-lg shadow-primary-500/20">
              <Zap className="w-5 h-5 text-white" />
            </div>
            <div>
              <h1 className="text-lg font-display font-bold text-gray-900 dark:text-white">
                Привет, {user?.username}!
              </h1>
              <p className="text-sm text-gray-500 dark:text-gray-400 capitalize">{today}</p>
            </div>
          </div>
          <button
            onClick={logout}
            className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-xl transition-colors"
            title="Выйти"
          >
            <LogOut size={20} />
          </button>
        </div>
      </header>

      <main className="max-w-lg mx-auto px-4 py-6 space-y-6">
        {/* Progress */}
        <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="card p-5">
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-semibold text-gray-900 dark:text-white">Прогресс на сегодня</h2>
            <span className="text-sm font-medium text-primary-600 dark:text-primary-400">{completedCount} / {totalToday}</span>
          </div>
          <div className="h-3 bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden">
            <motion.div
              initial={{ width: 0 }}
              animate={{ width: totalToday > 0 ? `${(completedCount / totalToday) * 100}%` : '0%' }}
              transition={{ duration: 0.5, ease: 'easeOut' }}
              className="h-full bg-gradient-to-r from-primary-500 to-accent-500 rounded-full"
            />
          </div>
          {completedCount === totalToday && totalToday > 0 && (
            <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="text-sm text-green-600 dark:text-green-400 mt-2 font-medium">
              🎉 Все привычки выполнены!
            </motion.p>
          )}
          {frozenHabits.length > 0 && (
            <div className="flex items-center gap-2 mt-2 text-sm text-cyan-600 dark:text-cyan-400">
              <Snowflake size={14} />
              <span>{frozenHabits.length} привычек на паузе</span>
            </div>
          )}
        </motion.div>

        {/* Stats */}
        {stats && (
          <div className="grid grid-cols-2 gap-4">
            <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="card p-5">
              <div className="flex items-center gap-4">
                <div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-accent-400 to-accent-500 flex items-center justify-center shadow-lg shadow-accent-400/20">
                  <Flame className="w-6 h-6 text-white" />
                </div>
                <div>
                  <p className="text-3xl font-display font-bold text-gray-900 dark:text-white">{stats.today_completed}</p>
                  <p className="text-sm text-gray-500 dark:text-gray-400">Выполнено</p>
                </div>
              </div>
            </motion.div>
            
            <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.1 }} className="card p-5">
              <div className="flex items-center gap-4">
                <div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center shadow-lg shadow-primary-500/20">
                  <TrendingUp className="w-6 h-6 text-white" />
                </div>
                <div>
                  <p className="text-3xl font-display font-bold text-gray-900 dark:text-white">{stats.active_habits}</p>
                  <p className="text-sm text-gray-500 dark:text-gray-400">Активных</p>
                </div>
              </div>
            </motion.div>
          </div>
        )}

        {/* Tasks */}
        {(activeTasks.length > 0 || !tasksLoading) && (
          <div>
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-xl font-display font-bold text-gray-900 dark:text-white">Задачи на сегодня</h2>
              <button
                onClick={() => setShowCreateTask(true)}
                className="p-2 bg-primary-100 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 rounded-xl hover:bg-primary-200 dark:hover:bg-primary-800/40 transition-colors"
              >
                <Plus size={18} />
              </button>
            </div>

            {tasksLoading ? (
              <div className="card p-5 animate-pulse">
                <div className="flex items-center gap-4">
                  <div className="w-10 h-10 rounded-xl bg-gray-200 dark:bg-gray-700" />
                  <div className="flex-1">
                    <div className="h-5 bg-gray-200 dark:bg-gray-700 rounded-lg w-3/4 mb-2" />
                    <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded-lg w-1/4" />
                  </div>
                </div>
              </div>
            ) : activeTasks.length === 0 ? (
              <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} className="card p-6 text-center">
                <p className="text-gray-500 dark:text-gray-400">Нет задач на сегодня</p>
                <button onClick={() => setShowCreateTask(true)} className="mt-3 text-sm text-primary-600 dark:text-primary-400 hover:text-primary-700 font-medium">
                  + Добавить задачу
                </button>
              </motion.div>
            ) : (
              <div className="space-y-3">
                <AnimatePresence>
                  {activeTasks.map((task, index) => (
                    <TaskCard key={task.id} task={task} index={index} onToggle={() => handleToggleTask(task)} isLoading={completeTaskMutation.isPending || uncompleteTaskMutation.isPending} />
                  ))}
                </AnimatePresence>
              </div>
            )}
          </div>
        )}

        {/* Habits */}
        <div>
          <h2 className="text-xl font-display font-bold text-gray-900 dark:text-white mb-5">Привычки</h2>

          {habitsLoading ? (
            <div className="space-y-4">
              {[1, 2, 3].map((i) => (
                <div key={i} className="card p-5 animate-pulse">
                  <div className="flex items-center gap-4">
                    <div className="w-14 h-14 rounded-2xl bg-gray-200 dark:bg-gray-700" />
                    <div className="flex-1">
                      <div className="h-5 bg-gray-200 dark:bg-gray-700 rounded-lg w-1/2 mb-2" />
                      <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded-lg w-1/3" />
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : todayHabits.length === 0 ? (
            <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} className="card p-10 text-center">
              <div className="w-20 h-20 rounded-3xl bg-gradient-to-br from-green-100 to-green-200 dark:from-green-900/30 dark:to-green-800/30 flex items-center justify-center mx-auto mb-5">
                <Sparkles className="w-10 h-10 text-green-600 dark:text-green-400" />
              </div>
              <h3 className="text-xl font-display font-bold text-gray-900 dark:text-white mb-2">Свободный день!</h3>
              <p className="text-gray-500 dark:text-gray-400">На сегодня нет запланированных привычек.</p>
            </motion.div>
          ) : (
            <div className="space-y-4">
              <AnimatePresence>
                {todayHabits.map((habit, index) => (
                  <HabitCard
                    key={habit.id}
                    habit={habit}
                    index={index}
                    isCompleted={!!todayLogs[habit.id]}
                    onToggle={() => handleToggleComplete(habit.id)}
                    onLongPress={() => setLogHabitModal({ open: true, habit })}
                    isLoading={logMutation.isPending || deleteLogMutation.isPending}
                  />
                ))}
              </AnimatePresence>
            </div>
          )}
        </div>
      </main>

      <Navigation />
      <CreateTaskModal open={showCreateTask} onClose={() => setShowCreateTask(false)} />
      <LogHabitModal
        open={logHabitModal.open}
        onClose={() => setLogHabitModal({ open: false, habit: null })}
        habit={logHabitModal.habit}
        completedDates={habitLogs[logHabitModal.habit?.id] || []}
        onLogDate={handleLogHabitDate}
      />
    </div>
  )
}

function TaskCard({ task, index, onToggle, isLoading }) {
  const [showConfetti, setShowConfetti] = useState(false)
  const dueDateLabel = formatDueDate(task.due_date)
  const isOverdue = task.due_date && isPast(parseISO(task.due_date)) && !isToday(parseISO(task.due_date)) && !task.completed

  const handleCheck = (e) => {
    e.stopPropagation()
    if (isLoading) return
    if (!task.completed) {
      setShowConfetti(true)
      setTimeout(() => setShowConfetti(false), 1000)
    }
    onToggle()
  }

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, x: -100 }}
      transition={{ delay: index * 0.05 }}
      className="card p-4 relative overflow-hidden"
    >
      {showConfetti && (
        <motion.div initial={{ opacity: 1 }} animate={{ opacity: 0 }} transition={{ duration: 1 }} className="absolute inset-0 pointer-events-none">
          {[...Array(6)].map((_, i) => (
            <motion.div
              key={i}
              initial={{ x: '50%', y: '50%', scale: 0 }}
              animate={{ x: `${Math.random() * 100}%`, y: `${Math.random() * 100}%`, scale: [0, 1, 0] }}
              transition={{ duration: 0.6, delay: i * 0.05 }}
              className="absolute w-2 h-2 rounded-full"
              style={{ backgroundColor: task.color }}
            />
          ))}
        </motion.div>
      )}
      
      <div className="flex items-center gap-3">
        <motion.button
          onClick={handleCheck}
          disabled={isLoading}
          whileTap={{ scale: 0.9 }}
          className={clsx(
            'w-10 h-10 rounded-xl flex items-center justify-center transition-all duration-300 flex-shrink-0',
            task.completed
              ? 'bg-gradient-to-br from-green-400 to-green-500 shadow-lg shadow-green-400/30'
              : 'border-2 hover:shadow-md'
          )}
          style={{ borderColor: task.completed ? undefined : task.color + '40', backgroundColor: task.completed ? undefined : task.color + '10' }}
        >
          {task.completed ? (
            <motion.div initial={{ scale: 0, rotate: -180 }} animate={{ scale: 1, rotate: 0 }} transition={{ type: 'spring', stiffness: 500 }}>
              <Check className="w-5 h-5 text-white" strokeWidth={3} />
            </motion.div>
          ) : (
            <span className="text-lg">{task.icon || '📋'}</span>
          )}
        </motion.button>
        
        <div className="flex-1 min-w-0">
          <h3 className={clsx("font-semibold truncate", task.completed ? "text-gray-400 line-through" : "text-gray-900 dark:text-white")}>{task.title}</h3>
          {(dueDateLabel || isOverdue) && (
            <span className={clsx('inline-flex items-center gap-1 text-xs font-medium mt-1', isOverdue ? 'text-red-600' : 'text-gray-500 dark:text-gray-400')}>
              {isOverdue && <AlertTriangle size={12} />}
              <Calendar size={12} />
              {dueDateLabel}
            </span>
          )}
        </div>
        
        {task.completed && (
          <motion.button initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} onClick={handleCheck} disabled={isLoading} className="p-2 text-gray-400 hover:text-orange-500 hover:bg-orange-50 dark:hover:bg-orange-900/20 rounded-xl transition-all" title="Отменить">
            <Undo2 size={18} />
          </motion.button>
        )}
      </div>
    </motion.div>
  )
}

function HabitCard({ habit, index, isCompleted, onToggle, onLongPress, isLoading }) {
  const [showConfetti, setShowConfetti] = useState(false)
  const longPressTimer = useRef(null)
  const isLongPress = useRef(false)

  const handleTouchStart = () => {
    isLongPress.current = false
    longPressTimer.current = setTimeout(() => { isLongPress.current = true; onLongPress() }, 500)
  }

  const handleTouchEnd = () => { if (longPressTimer.current) clearTimeout(longPressTimer.current) }

  const handleCheck = (e) => {
    e.stopPropagation()
    if (isLoading || isLongPress.current) return
    if (!isCompleted) { setShowConfetti(true); setTimeout(() => setShowConfetti(false), 1000) }
    onToggle()
  }

  const handleContextMenu = (e) => { e.preventDefault(); onLongPress() }

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, x: -100 }}
      transition={{ delay: index * 0.05 }}
      className="card p-5 relative overflow-hidden"
      onContextMenu={handleContextMenu}
    >
      {showConfetti && (
        <motion.div initial={{ opacity: 1 }} animate={{ opacity: 0 }} transition={{ duration: 1 }} className="absolute inset-0 pointer-events-none">
          {[...Array(6)].map((_, i) => (
            <motion.div
              key={i}
              initial={{ x: '50%', y: '50%', scale: 0 }}
              animate={{ x: `${Math.random() * 100}%`, y: `${Math.random() * 100}%`, scale: [0, 1, 0] }}
              transition={{ duration: 0.6, delay: i * 0.05 }}
              className="absolute w-2 h-2 rounded-full"
              style={{ backgroundColor: habit.color }}
            />
          ))}
        </motion.div>
      )}
      
      <div className="flex items-center gap-4">
        <motion.button
          onClick={handleCheck}
          onTouchStart={handleTouchStart}
          onTouchEnd={handleTouchEnd}
          onMouseDown={handleTouchStart}
          onMouseUp={handleTouchEnd}
          onMouseLeave={handleTouchEnd}
          disabled={isLoading}
          whileTap={{ scale: 0.9 }}
          className={clsx(
            'w-14 h-14 rounded-2xl flex items-center justify-center transition-all duration-300 relative flex-shrink-0',
            isCompleted
              ? 'bg-gradient-to-br from-green-400 to-green-500 shadow-lg shadow-green-400/30'
              : 'border-2 hover:shadow-md'
          )}
          style={{ borderColor: isCompleted ? undefined : habit.color + '40', backgroundColor: isCompleted ? undefined : habit.color + '10' }}
        >
          {isCompleted ? (
            <motion.div initial={{ scale: 0, rotate: -180 }} animate={{ scale: 1, rotate: 0 }} transition={{ type: 'spring', stiffness: 500 }}>
              <Check className="w-7 h-7 text-white" strokeWidth={3} />
            </motion.div>
          ) : (
            <span className="text-2xl">{habit.icon || '✨'}</span>
          )}
        </motion.button>
        
        <div className="flex-1 min-w-0">
          <h3 className={clsx("font-semibold text-lg truncate", isCompleted ? "text-gray-400 line-through" : "text-gray-900 dark:text-white")}>{habit.name}</h3>
          {habit.description && <p className="text-sm text-gray-500 dark:text-gray-400 truncate">{habit.description}</p>}
        </div>
        
        <div className="flex items-center gap-2">
          <button onClick={(e) => { e.stopPropagation(); onLongPress() }} className="p-2 text-gray-400 hover:text-primary-500 hover:bg-primary-50 dark:hover:bg-primary-900/20 rounded-xl transition-all" title="Отметить за другой день">
            <Calendar size={20} />
          </button>
          {isCompleted && (
            <motion.button initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} onClick={handleCheck} disabled={isLoading} className="p-2 text-gray-400 hover:text-orange-500 hover:bg-orange-50 dark:hover:bg-orange-900/20 rounded-xl transition-all" title="Отменить">
              <Undo2 size={20} />
            </motion.button>
          )}
        </div>
      </div>
    </motion.div>
  )
}
