import React, { useState, useEffect, useMemo, useRef } from 'react'
import { useAuth } from './auth/AuthContext'
import TaskDetail from './TaskDetail'
import LoadingError from './LoadingError'
import Toast from './Toast'
import './TaskList.css'

const API_URL = '/api/tasks'

function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry, onRefresh }) {
  const { authFetch } = useAuth()
  // Инициализируем tasks из data, если data есть, иначе пустой массив
  const [tasks, setTasks] = useState(() => data && Array.isArray(data) ? data : [])
  const [selectedTaskForDetail, setSelectedTaskForDetail] = useState(null)
  const [isCompleting, setIsCompleting] = useState(false)
  const [expandedCompleted, setExpandedCompleted] = useState({})
  const [selectedTaskForPostpone, setSelectedTaskForPostpone] = useState(null)
  const [postponeDate, setPostponeDate] = useState('')
  const [isPostponing, setIsPostponing] = useState(false)
  const [toast, setToast] = useState(null)
  const dateInputRef = useRef(null)

  useEffect(() => {
    if (data) {
      setTasks(data)
    }
  }, [data])

  // Загрузка данных управляется из App.jsx через loadTabData
  // TaskList не инициирует загрузку самостоятельно

  const handleTaskClick = (task) => {
    onNavigate?.('task-form', { taskId: task.id })
  }

  const handleCheckmarkClick = async (task, e) => {
    e.stopPropagation()

    // Для задач-тестов запускаем тест вместо открытия модального окна
    const isTest = task.config_id != null
    if (isTest) {
      if (task.config_id) {
        try {
          // Загружаем детальную информацию о задаче, чтобы получить maxCards
          const response = await authFetch(`${API_URL}/${task.id}`)
          if (!response.ok) {
            throw new Error('Ошибка при загрузке деталей задачи')
          }
          const taskDetail = await response.json()

          // Переходим к тесту с maxCards
          onNavigate?.('test', {
            configId: task.config_id,
            taskId: task.id,
            maxCards: taskDetail.max_cards
          })
        } catch (err) {
          console.error('Failed to load task details:', err)
          // В случае ошибки всё равно переходим к тесту, но без maxCards
          onNavigate?.('test', { configId: task.config_id, taskId: task.id })
        }
      }
      return
    }

    // Для обычных задач открываем диалог подтверждения
    setSelectedTaskForDetail(task.id)
  }

  const handleCloseDetail = () => {
    setSelectedTaskForDetail(null)
  }



  // Функция для вычисления следующей даты по repetition_date
  const calculateNextDateFromRepetitionDate = (repetitionDateStr) => {
    if (!repetitionDateStr) return null
    
    const parts = repetitionDateStr.trim().split(/\s+/)
    if (parts.length < 2) return null
    
    const value = parts[0]
    const unit = parts[1].toLowerCase()
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    
    switch (unit) {
      case 'week': {
        // N-й день недели (1=понедельник, 7=воскресенье)
        const dayOfWeek = parseInt(value, 10)
        if (isNaN(dayOfWeek) || dayOfWeek < 1 || dayOfWeek > 7) return null
        // JavaScript: 0=воскресенье, 1=понедельник... 6=суббота
        // Наш формат: 1=понедельник... 7=воскресенье
        // Конвертируем: наш 1 (Пн) -> JS 1, наш 7 (Вс) -> JS 0
        const targetJsDay = dayOfWeek === 7 ? 0 : dayOfWeek
        const currentJsDay = now.getDay()
        // Вычисляем дни до следующего вхождения (включая сегодня, если ещё не прошло)
        let daysUntil = (targetJsDay - currentJsDay + 7) % 7
        // Если сегодня тот же день, берём следующую неделю
        if (daysUntil === 0) daysUntil = 7
        const nextDate = new Date(now)
        nextDate.setDate(now.getDate() + daysUntil)
        return nextDate
      }
      case 'month': {
        // N-й день месяца
        const dayOfMonth = parseInt(value, 10)
        if (isNaN(dayOfMonth) || dayOfMonth < 1 || dayOfMonth > 31) return null
        
        // Ищем ближайшую дату с этим днём
        let searchDate = new Date(now)
        for (let i = 0; i < 12; i++) {
          const year = searchDate.getFullYear()
          const month = searchDate.getMonth()
          const lastDayOfMonth = new Date(year, month + 1, 0).getDate()
          const actualDay = Math.min(dayOfMonth, lastDayOfMonth)
          const candidateDate = new Date(year, month, actualDay)
          
          if (candidateDate > now) {
            return candidateDate
          }
          // Переходим к следующему месяцу
          searchDate = new Date(year, month + 1, 1)
        }
        return null
      }
      case 'year': {
        // MM-DD формат
        const dateParts = value.split('-')
        if (dateParts.length !== 2) return null
        const monthNum = parseInt(dateParts[0], 10)
        const day = parseInt(dateParts[1], 10)
        if (isNaN(monthNum) || isNaN(day) || monthNum < 1 || monthNum > 12 || day < 1 || day > 31) return null
        
        let year = now.getFullYear()
        let candidateDate = new Date(year, monthNum - 1, day)
        
        if (candidateDate <= now) {
          candidateDate = new Date(year + 1, monthNum - 1, day)
        }
        return candidateDate
      }
      default:
        return null
    }
  }

  // Функция для вычисления следующей даты по repetition_period
  const calculateNextDateFromRepetitionPeriod = (repetitionPeriodStr) => {
    if (!repetitionPeriodStr) return null
    
    const parts = repetitionPeriodStr.trim().split(/\s+/)
    if (parts.length < 2) return null
    
    const value = parseInt(parts[0], 10)
    if (isNaN(value) || value === 0) return null
    
    const unit = parts[1].toLowerCase()
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    
    const nextDate = new Date(now)
    
    switch (unit) {
      case 'minute':
      case 'minutes':
      case 'mins':
      case 'min':
        nextDate.setMinutes(nextDate.getMinutes() + value)
        break
      case 'hour':
      case 'hours':
      case 'hrs':
      case 'hr':
        nextDate.setHours(nextDate.getHours() + value)
        break
      case 'day':
      case 'days':
        // PostgreSQL может возвращать недели как дни (например, "7 days" вместо "1 week")
        // Если количество дней кратно 7, обрабатываем как недели
        if (value % 7 === 0 && value >= 7) {
          const weeks = value / 7
          nextDate.setDate(nextDate.getDate() + weeks * 7)
        } else {
          nextDate.setDate(nextDate.getDate() + value)
        }
        break
      case 'week':
      case 'weeks':
      case 'wks':
      case 'wk':
        nextDate.setDate(nextDate.getDate() + value * 7)
        break
      case 'month':
      case 'months':
      case 'mons':
      case 'mon':
        nextDate.setMonth(nextDate.getMonth() + value)
        break
      case 'year':
      case 'years':
      case 'yrs':
      case 'yr':
        nextDate.setFullYear(nextDate.getFullYear() + value)
        break
      default:
        return null
    }
    
    return nextDate
  }

  // Форматирование даты в YYYY-MM-DD (локальное время, без смещения в UTC)
  const formatDateToLocal = (date) => {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
  }

  // Форматирование даты для отображения с понятными названиями
  const formatDateForDisplay = (dateStr) => {
    if (!dateStr) return ''
    
    // Парсим дату из формата YYYY-MM-DD
    const dateParts = dateStr.split('-')
    if (dateParts.length !== 3) return dateStr
    
    const yearNum = parseInt(dateParts[0], 10)
    const monthNum = parseInt(dateParts[1], 10) - 1 // месяцы в JS начинаются с 0
    const dayNum = parseInt(dateParts[2], 10)
    
    if (isNaN(yearNum) || isNaN(monthNum) || isNaN(dayNum)) return dateStr
    
    const targetDate = new Date(yearNum, monthNum, dayNum)
    targetDate.setHours(0, 0, 0, 0)
    
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    
    const diffDays = Math.floor((targetDate - now) / (1000 * 60 * 60 * 24))
    
    // Сегодня
    if (diffDays === 0) {
      return 'Сегодня'
    }
    
    // Завтра
    if (diffDays === 1) {
      return 'Завтра'
    }
    
    // Вчера
    if (diffDays === -1) {
      return 'Вчера'
    }
    
    // Дни недели для ближайших дней из будущего (в пределах 7 дней)
    if (diffDays > 0 && diffDays <= 7) {
      const dayNames = ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота']
      const dayOfWeek = targetDate.getDay()
      return dayNames[dayOfWeek]
    }
    
    const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 
                       'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
    
    // Если это число из того же года - только день и месяц
    if (targetDate.getFullYear() === now.getFullYear()) {
      const displayDay = targetDate.getDate()
      const displayMonth = monthNames[targetDate.getMonth()]
      return `${displayDay} ${displayMonth}`
    }
    
    // Для других случаев - полная дата
    const displayDay = targetDate.getDate()
    const displayMonth = monthNames[targetDate.getMonth()]
    const displayYear = targetDate.getFullYear()
    return `${displayDay} ${displayMonth} ${displayYear}`
  }

  const handlePostponeClick = (task, e) => {
    e.stopPropagation()
    setSelectedTaskForPostpone(task)
    
    // Устанавливаем дату по умолчанию
    let defaultDate
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    
    if (task.repetition_date) {
      // Для задач с repetition_date - вычисляем следующую подходящую дату
      const nextDate = calculateNextDateFromRepetitionDate(task.repetition_date)
      if (nextDate) {
        defaultDate = nextDate
      }
    } else if (task.repetition_period && !isZeroPeriod(task.repetition_period)) {
      // Для задач с repetition_period (не нулевым) - вычисляем следующую дату
      const nextDate = calculateNextDateFromRepetitionPeriod(task.repetition_period)
      if (nextDate) {
        defaultDate = nextDate
      }
    }
    
    if (!defaultDate) {
      // Без repetition_date/repetition_period или если не удалось вычислить - завтра
      defaultDate = new Date(now)
      defaultDate.setDate(defaultDate.getDate() + 1)
    }
    
    defaultDate.setHours(0, 0, 0, 0)
    setPostponeDate(formatDateToLocal(defaultDate))
  }

  const handlePostponeSubmit = async () => {
    if (!selectedTaskForPostpone || !postponeDate) return
    await handlePostponeSubmitWithDate(postponeDate)
  }

  const handlePostponeClose = () => {
    setSelectedTaskForPostpone(null)
    setPostponeDate('')
  }

  const handleTodayClick = () => {
    const today = new Date()
    today.setHours(0, 0, 0, 0)
    setPostponeDate(formatDateToLocal(today))
    // Применяем дату сразу
    if (selectedTaskForPostpone) {
      handlePostponeSubmitWithDate(formatDateToLocal(today))
    }
  }

  const handleTomorrowClick = () => {
    const tomorrow = new Date()
    tomorrow.setDate(tomorrow.getDate() + 1)
    tomorrow.setHours(0, 0, 0, 0)
    setPostponeDate(formatDateToLocal(tomorrow))
    // Применяем дату сразу
    if (selectedTaskForPostpone) {
      handlePostponeSubmitWithDate(formatDateToLocal(tomorrow))
    }
  }

  const handlePostponeSubmitWithDate = async (dateToUse) => {
    if (!selectedTaskForPostpone || !dateToUse) return

    setIsPostponing(true)
    try {
      // Преобразуем дату в ISO формат с временем
      const dateObj = new Date(dateToUse)
      dateObj.setHours(0, 0, 0, 0)
      const isoDate = dateObj.toISOString()

      const response = await authFetch(`${API_URL}/${selectedTaskForPostpone.id}/postpone`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ next_show_at: isoDate }),
      })

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.message || 'Ошибка при переносе задачи')
      }

      // Обновляем список
      if (onRefresh) {
        onRefresh()
      }

      // Закрываем модальное окно
      setSelectedTaskForPostpone(null)
      setPostponeDate('')
    } catch (err) {
      console.error('Error postponing task:', err)
      setToast({ message: err.message || 'Ошибка при переносе задачи', type: 'error' })
    } finally {
      setIsPostponing(false)
    }
  }

  const toggleCompletedExpanded = (projectName) => {
    setExpandedCompleted(prev => ({
      ...prev,
      [projectName]: !prev[projectName]
    }))
  }

  // Получаем все проекты из задачи (теперь они приходят в task.project_names)
  const getTaskProjects = (task) => {
    if (task.project_names && Array.isArray(task.project_names)) {
      return task.project_names
    }
    return []
  }

  // Функция для проверки, является ли период нулевым
  const isZeroPeriod = (intervalStr) => {
    if (!intervalStr) return false
    
    const trimmed = intervalStr.trim()
    
    // Проверяем формат времени "00:00:00" или "0:00:00"
    if (/^\d{1,2}:\d{2}:\d{2}/.test(trimmed)) {
      const timeParts = trimmed.split(':')
      if (timeParts.length >= 3) {
        const hours = parseInt(timeParts[0], 10)
        const minutes = parseInt(timeParts[1], 10)
        const seconds = parseInt(timeParts[2], 10)
        return !isNaN(hours) && !isNaN(minutes) && !isNaN(seconds) && 
               hours === 0 && minutes === 0 && seconds === 0
      }
    }
    
    // PostgreSQL может возвращать "0 day", "0 days", "0", и т.д.
    const parts = trimmed.split(/\s+/)
    if (parts.length < 1) return false
    
    const value = parseInt(parts[0], 10)
    return !isNaN(value) && value === 0
  }

  // Функция для проверки, является ли repetition_date нулевым
  const isZeroDate = (dateStr) => {
    if (!dateStr) return false
    
    const trimmed = dateStr.trim()
    const parts = trimmed.split(/\s+/)
    if (parts.length < 2) return false
    
    const value = parts[0]
    // Проверяем, является ли значение "0" (для формата "0 week", "0 month", "0 year")
    const numValue = parseInt(value, 10)
    return !isNaN(numValue) && numValue === 0
  }

  // Группируем задачи по проектам
  const groupedTasks = useMemo(() => {
    const today = new Date()
    today.setHours(0, 0, 0, 0)

    const groups = {}
    
    tasks.forEach(task => {
      const projects = getTaskProjects(task)
      
      // Если у задачи нет проектов, добавляем в группу "Без проекта"
      if (projects.length === 0) {
        projects.push('Без проекта')
      }
      
      // Определяем, в какую группу попадает задача
      let isCompleted = false
      let isInfinite = false
      
      // Используем только next_show_at для группировки
      if (task.next_show_at) {
        const nextShowDate = new Date(task.next_show_at)
        nextShowDate.setHours(0, 0, 0, 0)
        isCompleted = nextShowDate.getTime() > today.getTime()
        isInfinite = false
      } else {
        // Бесконечная задача: repetition_period == 0 И (repetition_date == 0 ИЛИ отсутствует)
        // Для обратной совместимости: если repetition_period = 0, считаем бесконечной
        const hasZeroPeriod = task.repetition_period && isZeroPeriod(task.repetition_period)
        const hasZeroDate = task.repetition_date && isZeroDate(task.repetition_date)
        // Идеально: оба поля = 0, но для старых задач может быть только repetition_period = 0
        isInfinite = (hasZeroPeriod && hasZeroDate) || (hasZeroPeriod && !task.repetition_date)
        isCompleted = false
      }
      
      projects.forEach(projectName => {
        if (!groups[projectName]) {
          groups[projectName] = {
            notCompleted: [],
            completed: []
          }
        }
        
        if (isCompleted) {
          groups[projectName].completed.push(task)
        } else {
          // Бесконечные задачи теперь идут в обычный список
          groups[projectName].notCompleted.push(task)
        }
      })
    })
    
    return groups
  }, [tasks])

  // Сортируем проекты: сначала с невыполненными задачами, потом без них
  // Группа "Без проекта" всегда последняя в своей категории
  const projectNames = useMemo(() => {
    const sorted = Object.keys(groupedTasks).sort((a, b) => {
      const groupA = groupedTasks[a]
      const groupB = groupedTasks[b]
      const hasNotCompletedA = groupA.notCompleted.length > 0
      const hasNotCompletedB = groupB.notCompleted.length > 0
      
      // Если у одной группы есть невыполненные, а у другой нет - сортируем по этому признаку
      if (hasNotCompletedA && !hasNotCompletedB) return -1
      if (!hasNotCompletedA && hasNotCompletedB) return 1
      
      // Если обе группы в одной категории
      const isNoProjectA = a === 'Без проекта'
      const isNoProjectB = b === 'Без проекта'
      
      // "Без проекта" всегда последняя в своей категории
      if (isNoProjectA && !isNoProjectB) return 1
      if (!isNoProjectA && isNoProjectB) return -1
      
      // Остальные группы сортируем по алфавиту
      return a.localeCompare(b)
    })
    return sorted
  }, [groupedTasks])

  const renderTaskItem = (task, isCompleted = false) => {
    const hasProgression = task.has_progression || task.progression_base != null
    const hasSubtasks = task.subtasks_count > 0
    const isTest = task.config_id != null
    const showDetailOnCheckmark = !isTest
    const isWishlist = task.wishlist_id != null
    
    // Проверяем бесконечную задачу: repetition_period = 0 И (repetition_date = 0 ИЛИ отсутствует)
    // Для обратной совместимости: если repetition_period = 0, считаем бесконечной
    const hasZeroPeriod = task.repetition_period && isZeroPeriod(task.repetition_period)
    const hasZeroDate = task.repetition_date && isZeroDate(task.repetition_date)
    // Бесконечная задача: repetition_period = 0 И (repetition_date = 0 ИЛИ отсутствует)
    // Не проверяем next_show_at, так как для бесконечных задач он может быть установлен при выполнении
    const isInfinite = (hasZeroPeriod && hasZeroDate) || (hasZeroPeriod && !task.repetition_date)
    
    // Одноразовая задача: когда оба поля null/undefined
    const isOneTime = (task.repetition_period == null || task.repetition_period === undefined) && 
                      (task.repetition_date == null || task.repetition_date === undefined)

    return (
      <div
        key={task.id}
        className="task-item"
        onClick={() => handleTaskClick(task)}
      >
        <div className="task-item-content">
          <div
            className={`task-checkmark ${showDetailOnCheckmark ? 'task-checkmark-detail' : ''} ${task.auto_complete ? 'task-checkmark-auto-complete' : ''}`}
            onClick={(e) => handleCheckmarkClick(task, e)}
            title={isTest ? 'Запустить тест' : (showDetailOnCheckmark ? 'Открыть детали' : 'Выполнить задачу')}
          >
            {isTest ? (
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path>
                <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path>
              </svg>
            ) : isWishlist ? (
              <>
                <svg
                  width="20"
                  height="20"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                >
                  <path d="M20 12v10M4 12v10M20 22H4"></path>
                  <path d="M22 7H2M22 7v5M2 7v5"></path>
                  <path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path>
                  <path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
                </svg>
                {task.auto_complete && (
                  <svg
                    className="task-checkmark-wishlist-lightning-icon"
                    width="16"
                    height="16"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                    title="Задача-желание"
                  >
                    <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
                  </svg>
                )}
              </>
            ) : (
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="10" cy="10" r="9" stroke="currentColor" strokeWidth="2" fill="none" className="checkmark-circle" />
                <path d="M6 10 L9 13 L14 7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="checkmark-check" />
              </svg>
            )}
            {task.auto_complete && !isTest && !isWishlist && (
              <svg
                className="task-checkmark-auto-complete-icon"
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="currentColor"
                title="Автовыполнение в конце дня"
              >
                <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
              </svg>
            )}
          </div>
          <div className="task-name-container">
            <div className="task-name-wrapper">
              <div className="task-name">
                {task.name}
                {hasSubtasks && (
                  <span className="task-subtasks-count">(+{task.subtasks_count})</span>
                )}
                <span className="task-badge-bar">
                  {!isOneTime && !isInfinite && !isWishlist && (
                    <svg
                      className="task-recurring-icon"
                      width="16"
                      height="16"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      title="Повторяющаяся задача"
                    >
                      <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/>
                      <path d="M21 3v5h-5"/>
                      <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/>
                      <path d="M3 21v-5h5"/>
                    </svg>
                  )}
                  {isInfinite && (
                    <svg
                      className="task-infinite-icon"
                      width="16"
                      height="16"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      title="Бесконечная задача"
                    >
                      <path d="M12 12c0-2.5-1.5-4.5-3.5-4.5S5 9.5 5 12s1.5 4.5 3.5 4.5S12 14.5 12 12z"/>
                      <path d="M12 12c0 2.5 1.5 4.5 3.5 4.5S19 14.5 19 12s-1.5-4.5-3.5-4.5S12 9.5 12 12z"/>
                    </svg>
                  )}
                  {hasProgression && (
                    <svg
                      className="task-progression-icon"
                      width="16"
                      height="16"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      title="Задача с прогрессией"
                    >
                      <polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline>
                      <polyline points="17 6 23 6 23 12"></polyline>
                    </svg>
                  )}
                </span>
              </div>
              {/* Показываем дату только для выполненных задач */}
              {isCompleted && task.next_show_at && (() => {
                const showDate = new Date(task.next_show_at)
                // Нормализуем дату: устанавливаем время в 00:00:00 в локальном времени
                const showDateNormalized = new Date(showDate.getFullYear(), showDate.getMonth(), showDate.getDate())
                
                const today = new Date()
                const todayNormalized = new Date(today.getFullYear(), today.getMonth(), today.getDate())
                
                const tomorrowNormalized = new Date(todayNormalized)
                tomorrowNormalized.setDate(tomorrowNormalized.getDate() + 1)
                
                // Не показываем текст если дата равна сегодня
                if (showDateNormalized.getTime() === todayNormalized.getTime()) {
                  return null
                }
                
                let dateText
                if (showDateNormalized.getTime() === tomorrowNormalized.getTime()) {
                  dateText = 'Завтра'
                } else {
                  dateText = showDate.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' })
                }
                
                return (
                  <div className="task-next-show-date">
                    {dateText}
                  </div>
                )
              })()}
            </div>
          </div>
          <div className="task-actions">
            <button
              className="task-postpone-button"
              onClick={(e) => handlePostponeClick(task, e)}
              title="Перенести задачу"
            >
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="10" cy="10" r="8" stroke="currentColor" strokeWidth="1.5" fill="none"/>
                <path d="M10 5V10L13 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" fill="none"/>
              </svg>
            </button>
          </div>
        </div>
      </div>
    )
  }

  // Показываем загрузку только если данных нет и это не фоновая загрузка
  // Проверяем наличие данных более надежно: либо в data, либо в tasks
  // Важно: проверяем оба источника данных, так как они могут обновляться асинхронно
  const hasDataInProps = data && Array.isArray(data) && data.length > 0
  const hasDataInState = tasks && Array.isArray(tasks) && tasks.length > 0
  const hasData = hasDataInProps || hasDataInState
  
  // Показываем ошибку загрузки, если есть ошибка и нет данных
  if (error && !hasData && !loading) {
    return (
      <div className="task-list">
        <LoadingError onRetry={onRetry} />
      </div>
    )
  }
  
  // Показываем загрузку только если:
  // 1. Идет загрузка (loading = true)
  // 2. Это не фоновая загрузка (backgroundLoading = false)
  // 3. Данных нет (hasData = false)
  // Это предотвращает показ загрузки при переключении табов, когда данные уже есть
  if (loading && !backgroundLoading && !hasData) {
    return (
      <div className="task-list">
        <div className="fixed inset-0 bottom-20 flex justify-center items-center">
          <div className="flex flex-col items-center">
            <div className="w-12 h-12 border-4 border-indigo-200 border-t-indigo-600 rounded-full animate-spin mb-4"></div>
            <div className="text-gray-600 font-medium">Загрузка...</div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="task-list">
      {toast && (
        <Toast
          message={toast.message}
          type={toast.type || 'success'}
          onClose={() => setToast(null)}
        />
      )}

      {projectNames.length === 0 && !loading && tasks.length === 0 && (
        <div className="empty-state">
          <p>Задач пока нет. Добавьте задачу через кнопку "Добавить".</p>
        </div>
      )}

      {projectNames.map(projectName => {
        const group = groupedTasks[projectName]
        const hasCompleted = group.completed.length > 0
        const hasNotCompleted = group.notCompleted.length > 0
        const isCompletedExpanded = expandedCompleted[projectName]

        return (
          <div key={projectName} className={`project-group ${!hasNotCompleted ? 'project-group-no-tasks' : ''}`}>
            <div className="project-group-header">
              <h3 className={`project-group-title ${!hasNotCompleted ? 'project-group-title-empty' : ''}`}>{projectName}</h3>
              {hasCompleted && (
                <button
                  className="completed-toggle-header"
                  onClick={() => toggleCompletedExpanded(projectName)}
                  title={isCompletedExpanded ? 'Скрыть выполненные' : 'Показать выполненные'}
                >
                  <span className="completed-toggle-icon">
                    {isCompletedExpanded ? '▼' : '▶'}
                  </span>
                </button>
              )}
            </div>
            
            {/* Обычные задачи (включая бесконечные) */}
            {group.notCompleted.length > 0 && (
              <div className="task-group">
                {group.notCompleted.map(task => renderTaskItem(task, false))}
              </div>
            )}

            {/* Выполненные задачи */}
            {hasCompleted && isCompletedExpanded && (
              <div className="task-group completed-tasks">
                {group.completed.map(task => renderTaskItem(task, true))}
              </div>
            )}

            {group.notCompleted.length === 0 && !hasCompleted && (
              <div className="empty-group">Нет задач в этой группе</div>
            )}
          </div>
        )
      })}

      {/* Модальное окно для деталей задачи */}
      {selectedTaskForDetail && (
        <TaskDetail
          taskId={selectedTaskForDetail}
          onClose={handleCloseDetail}
          onRefresh={onRefresh}
          onTaskCompleted={() => setToast({ message: 'Задача выполнена', type: 'success' })}
          onNavigate={onNavigate}
        />
      )}


      {/* Модальное окно для переноса задачи */}
      {selectedTaskForPostpone && (() => {
        const todayStr = formatDateToLocal(new Date())
        const tomorrow = new Date()
        tomorrow.setDate(tomorrow.getDate() + 1)
        const tomorrowStr = formatDateToLocal(tomorrow)
        
        // Проверяем next_show_at задачи, а не значение в поле ввода
        let nextShowAtStr = null
        if (selectedTaskForPostpone.next_show_at) {
          const nextShowAtDate = new Date(selectedTaskForPostpone.next_show_at)
          nextShowAtStr = formatDateToLocal(nextShowAtDate)
        }
        
        const isToday = nextShowAtStr === todayStr
        const isTomorrow = nextShowAtStr === tomorrowStr
        
        return (
          <div className="task-postpone-modal-overlay" onClick={handlePostponeClose}>
            <div className="task-postpone-modal" onClick={(e) => e.stopPropagation()}>
              <div className="task-postpone-modal-header">
                <h3>{selectedTaskForPostpone.name}</h3>
                <button onClick={handlePostponeClose} className="task-postpone-close-button">
                  ✕
                </button>
              </div>
              <div className="task-postpone-modal-content">
                <div className="task-postpone-input-group">
                  <input
                    ref={dateInputRef}
                    type="date"
                    value={postponeDate}
                    onChange={(e) => setPostponeDate(e.target.value)}
                    className="task-postpone-input"
                    min={new Date().toISOString().split('T')[0]}
                  />
                  <div 
                    className="task-postpone-display-date"
                    onClick={() => {
                      // Открываем календарь при клике
                      if (dateInputRef.current) {
                        if (typeof dateInputRef.current.showPicker === 'function') {
                          dateInputRef.current.showPicker()
                        } else {
                          // Fallback для браузеров без showPicker
                          dateInputRef.current.focus()
                          dateInputRef.current.click()
                        }
                      }
                    }}
                  >
                    {postponeDate ? formatDateForDisplay(postponeDate) : 'Выберите дату'}
                  </div>
                  {postponeDate && (
                    <button
                      onClick={handlePostponeSubmit}
                      disabled={isPostponing || !postponeDate}
                      className="task-postpone-submit-checkmark"
                    >
                      ✓
                    </button>
                  )}
                </div>
                <div className="task-postpone-quick-buttons">
                  {!isToday && (
                    <button
                      onClick={handleTodayClick}
                      className="task-postpone-quick-button"
                      disabled={isPostponing}
                    >
                      Сегодня
                    </button>
                  )}
                  {!isTomorrow && (
                    <button
                      onClick={handleTomorrowClick}
                      className="task-postpone-quick-button"
                      disabled={isPostponing}
                    >
                      Завтра
                    </button>
                  )}
                </div>
              </div>
            </div>
          </div>
        )
      })()}
    </div>
  )
}

export default TaskList

