import React, { useState, useEffect, useRef, useMemo } from 'react'
import { createPortal } from 'react-dom'
import { useAuth } from './auth/AuthContext'
import ShoppingItemDetail from './ShoppingItemDetail'
import Toast from './Toast'
import { DayPicker } from 'react-day-picker'
import { ru } from 'react-day-picker/locale'
import 'react-day-picker/style.css'
import './TaskList.css'
import './ShoppingList.css'

// Форматирование даты в YYYY-MM-DD (локальное время)
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 ''
  const date = new Date(dateStr)
  if (isNaN(date.getTime())) return ''

  const now = new Date()
  now.setHours(0, 0, 0, 0)
  const target = new Date(date.getFullYear(), date.getMonth(), date.getDate())
  const diffDays = Math.round((target - now) / (1000 * 60 * 60 * 24))

  if (diffDays === 0) return 'Сегодня'
  if (diffDays === 1) return 'Завтра'

  const months = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
    'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
  return `${date.getDate()} ${months[date.getMonth()]}`
}

const calculateNextDateFromRepetitionPeriod = (periodStr) => {
  if (!periodStr) return null
  const match = periodStr.match(/(\d+)\s*(day|week|mon|year)/i)
  if (!match) return null
  const value = parseInt(match[1], 10)
  const unit = match[2].toLowerCase()
  const next = new Date()
  next.setHours(0, 0, 0, 0)
  if (unit.startsWith('day')) next.setDate(next.getDate() + value)
  else if (unit.startsWith('week')) next.setDate(next.getDate() + value * 7)
  else if (unit.startsWith('mon')) next.setMonth(next.getMonth() + value)
  else if (unit.startsWith('year')) next.setFullYear(next.getFullYear() + value)
  return next
}

function PurchaseScreen({ onNavigate, purchaseConfigId, taskId, taskName }) {
  const { authFetch } = useAuth()
  const [items, setItems] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(false)
  const [selectedItemForDetail, setSelectedItemForDetail] = useState(null)
  const [selectedItemForPostpone, setSelectedItemForPostpone] = useState(null)
  const [postponeDate, setPostponeDate] = useState('')
  const [isPostponing, setIsPostponing] = useState(false)
  const [toast, setToast] = useState(null)
  const [expandedFuture, setExpandedFuture] = useState({})
  const [isCompleting, setIsCompleting] = useState(false)
  const historyPushedForDetailRef = useRef(false)
  const historyPushedForPostponeRef = useRef(false)
  const selectedItemForDetailRef = useRef(null)
  const selectedItemForPostponeRef = useRef(null)

  const fetchItems = async () => {
    if (!purchaseConfigId) return
    try {
      setLoading(true)
      setError(false)
      const response = await authFetch(`/api/purchase/items/${purchaseConfigId}`)
      if (response.ok) {
        const data = await response.json()
        setItems(Array.isArray(data) ? data : [])
      } else {
        setError(true)
      }
    } catch (err) {
      console.error('Error loading purchase items:', err)
      setError(true)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    fetchItems()
  }, [purchaseConfigId])

  const handleRefresh = () => {
    fetchItems()
  }

  const handleClose = () => {
    window.history.back()
  }

  const handleCompleteTask = async () => {
    if (!taskId || isCompleting) return
    setIsCompleting(true)
    try {
      const response = await authFetch(`/api/tasks/${taskId}/complete`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({})
      })
      if (response.ok) {
        setTimeout(() => window.history.back(), 500)
        return
      } else {
        const errorData = await response.json().catch(() => ({}))
        setToast({ message: errorData.error || 'Ошибка выполнения', type: 'error' })
      }
    } catch (err) {
      setToast({ message: 'Ошибка выполнения', type: 'error' })
    }
    setIsCompleting(false)
  }

  // Синхронизация refs для диалогов
  useEffect(() => {
    selectedItemForDetailRef.current = selectedItemForDetail
    selectedItemForPostponeRef.current = selectedItemForPostpone
  }, [selectedItemForDetail, selectedItemForPostpone])

  // Пуш в историю при открытии модалок и обработка popstate
  useEffect(() => {
    if (selectedItemForPostpone && !historyPushedForPostponeRef.current) {
      window.history.pushState({ modalOpen: true, type: 'purchase-postpone' }, '', window.location.href)
      historyPushedForPostponeRef.current = true
    } else if (!selectedItemForPostpone) {
      historyPushedForPostponeRef.current = false
    }

    if (selectedItemForDetail && !historyPushedForDetailRef.current) {
      window.history.pushState({ modalOpen: true, type: 'purchase-detail' }, '', window.location.href)
      historyPushedForDetailRef.current = true
    } else if (!selectedItemForDetail) {
      historyPushedForDetailRef.current = false
    }

    if (!selectedItemForDetail && !selectedItemForPostpone) return

    const handlePopState = () => {
      const currentDetail = selectedItemForDetailRef.current
      const currentPostpone = selectedItemForPostponeRef.current

      if (currentPostpone) {
        setSelectedItemForPostpone(null)
        setPostponeDate('')
        historyPushedForPostponeRef.current = false
        return
      }

      if (currentDetail) {
        setSelectedItemForDetail(null)
        historyPushedForDetailRef.current = false
      }
    }

    window.addEventListener('popstate', handlePopState)
    return () => {
      window.removeEventListener('popstate', handlePopState)
    }
  }, [selectedItemForDetail, selectedItemForPostpone])

  // Фильтрация и группировка
  const groupedItems = useMemo(() => {
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    const todayEnd = new Date(now)
    todayEnd.setHours(23, 59, 59, 999)

    const groups = {}

    items.forEach(item => {
      const groupKey = item.group_name || 'Остальные'
      if (!groups[groupKey]) {
        groups[groupKey] = { active: [], future: [] }
      }

      if (!item.next_show_at) {
        groups[groupKey].future.push(item)
        return
      }
      const showAt = new Date(item.next_show_at)
      if (showAt > todayEnd) {
        groups[groupKey].future.push(item)
        return
      }
      groups[groupKey].active.push(item)
    })

    Object.values(groups).forEach(group => {
      group.future.sort((a, b) => {
        if (!a.next_show_at) return 1
        if (!b.next_show_at) return -1
        return new Date(a.next_show_at) - new Date(b.next_show_at)
      })
    })

    return groups
  }, [items])

  const groupNames = useMemo(() => {
    const names = Object.keys(groupedItems)
    return names.sort((a, b) => {
      const groupA = groupedItems[a]
      const groupB = groupedItems[b]
      const hasActiveA = groupA.active.length > 0
      const hasActiveB = groupB.active.length > 0

      if (hasActiveA && !hasActiveB) return -1
      if (!hasActiveA && hasActiveB) return 1

      if (a === 'Остальные') return 1
      if (b === 'Остальные') return -1
      return a.localeCompare(b, 'ru')
    })
  }, [groupedItems])

  const toggleFuture = (groupName) => {
    setExpandedFuture(prev => ({
      ...prev,
      [groupName]: !prev[groupName]
    }))
  }

  const handleCloseDetail = (skipHistoryBack) => {
    if (!skipHistoryBack && historyPushedForDetailRef.current) {
      window.history.back()
    } else {
      setSelectedItemForDetail(null)
      historyPushedForDetailRef.current = false
    }
  }

  const handlePostponeClose = () => {
    if (historyPushedForPostponeRef.current) {
      window.history.back()
    } else {
      setSelectedItemForPostpone(null)
      setPostponeDate('')
    }
  }

  const handlePostponeSubmitWithDate = async (dateStr) => {
    if (!selectedItemForPostpone || !dateStr) return
    setIsPostponing(true)
    try {
      const nextShowAt = new Date(dateStr + 'T00:00:00')
      const res = await authFetch(`/api/shopping/items/${selectedItemForPostpone.id}/postpone`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ next_show_at: nextShowAt.toISOString() })
      })
      if (res.ok) {
        setToast({ message: 'Дата обновлена', type: 'success' })
        handleRefresh()
        handlePostponeClose()
      } else {
        setToast({ message: 'Ошибка переноса', type: 'error' })
      }
    } catch (err) {
      setToast({ message: 'Ошибка переноса', type: 'error' })
    } finally {
      setIsPostponing(false)
    }
  }

  const handleDateSelect = (date) => {
    if (date) {
      setPostponeDate(formatDateToLocal(date))
    }
  }

  const handleDayClick = (date) => {
    if (date) {
      handlePostponeSubmitWithDate(formatDateToLocal(date))
    }
  }

  const handleTodayClick = () => {
    handlePostponeSubmitWithDate(formatDateToLocal(new Date()))
  }

  const handleTomorrowClick = () => {
    const tomorrow = new Date()
    tomorrow.setDate(tomorrow.getDate() + 1)
    handlePostponeSubmitWithDate(formatDateToLocal(tomorrow))
  }

  const handleWithoutDateClick = async () => {
    if (!selectedItemForPostpone) return
    setIsPostponing(true)
    try {
      const res = await authFetch(`/api/shopping/items/${selectedItemForPostpone.id}/postpone`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ next_show_at: null })
      })
      if (res.ok) {
        setToast({ message: 'Дата убрана', type: 'success' })
        handleRefresh()
        handlePostponeClose()
      }
    } catch (err) {
      setToast({ message: 'Ошибка', type: 'error' })
    } finally {
      setIsPostponing(false)
    }
  }

  const renderItem = (item) => {
    let dateDisplay = null
    if (item.next_show_at) {
      const itemDate = new Date(item.next_show_at)
      const now = new Date()
      now.setHours(0, 0, 0, 0)
      const target = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate())
      if (target > now) {
        dateDisplay = formatDateForDisplay(item.next_show_at)
      }
    }

    return (
      <div
        key={item.id}
        className="task-item"
        onClick={() => setSelectedItemForDetail(item.id)}
      >
        <div className="task-item-content">
          <div
            className="task-checkmark"
            onClick={(e) => {
              e.stopPropagation()
              setSelectedItemForDetail(item.id)
            }}
            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="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>
          </div>
          <div className="task-name-container">
            <div className="task-name-wrapper">
              <div className="task-name">{item.name}</div>
              {dateDisplay && (
                <div className="task-next-show-date">{dateDisplay}</div>
              )}
            </div>
          </div>
          <div className="task-actions">
            <button
              className="task-postpone-button"
              onClick={(e) => {
                e.stopPropagation()
                setSelectedItemForPostpone(item)
                // Предвыбираем дату "по плану" если она не совпадает с текущей next_show_at
                const now2 = new Date()
                now2.setHours(0, 0, 0, 0)
                let planned
                if (item.repetition_period) {
                  planned = calculateNextDateFromRepetitionPeriod(item.repetition_period)
                }
                if (!planned) {
                  planned = new Date(now2)
                  planned.setDate(planned.getDate() + 1)
                }
                planned.setHours(0, 0, 0, 0)
                const plannedStr = formatDateToLocal(planned)
                let nextShowStr = null
                if (item.next_show_at) {
                  nextShowStr = formatDateToLocal(new Date(item.next_show_at))
                }
                if (plannedStr !== nextShowStr) {
                  setPostponeDate(plannedStr)
                } else {
                  setPostponeDate('')
                }
              }}
              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>
    )
  }

  return (
    <div className="max-w-2xl mx-auto" style={{ paddingBottom: taskId ? '5rem' : '2.5rem' }}>
      <button className="close-x-button" onClick={handleClose}>✕</button>
      <h2 className="text-2xl font-semibold text-gray-800 mb-6" style={{ marginTop: '1.25rem' }}>{taskName || 'Закупка'}</h2>

      {loading && items.length === 0 && (
        <div className="shopping-loading">
          <div className="w-8 h-8 border-4 border-indigo-200 border-t-indigo-600 rounded-full animate-spin"></div>
        </div>
      )}

      {error && (
        <div className="shopping-empty">
          <p>Ошибка загрузки</p>
          <button onClick={handleRefresh} style={{ marginTop: '8px', color: 'var(--accent-color)' }}>
            Повторить
          </button>
        </div>
      )}

      {!loading && !error && items.length === 0 && (
        <div className="shopping-empty">
          <p>Нет товаров</p>
        </div>
      )}

      {groupNames.map(groupName => {
        const group = groupedItems[groupName]
        const hasActive = group.active.length > 0
        const hasFuture = group.future.length > 0
        const isFutureExpanded = expandedFuture[groupName]

        return (
          <div key={groupName} className={`project-group ${!hasActive ? 'project-group-no-tasks' : ''}`}>
            <div
              className={`project-group-header ${hasFuture ? 'project-group-header-clickable' : ''}`}
              onClick={hasFuture ? () => toggleFuture(groupName) : undefined}
            >
              <h3 className={`project-group-title ${!hasActive ? 'project-group-title-empty' : ''}`}>{groupName}</h3>
              {hasFuture ? (
                <button
                  className="completed-toggle-header"
                  onClick={(e) => {
                    e.stopPropagation()
                    toggleFuture(groupName)
                  }}
                  title={isFutureExpanded ? 'Скрыть ожидающие' : 'Показать ожидающие'}
                >
                  <span className="completed-toggle-icon">
                    {isFutureExpanded ? '▼' : '▶'}
                  </span>
                </button>
              ) : (
                <div className="completed-toggle-header" style={{ visibility: 'hidden', pointerEvents: 'none' }}>
                  <span className="completed-toggle-icon">▶</span>
                </div>
              )}
            </div>

            {hasActive && (
              <div className="task-group">
                {group.active.map(item => renderItem(item))}
              </div>
            )}

            {hasFuture && isFutureExpanded && (
              <div className="task-group completed-tasks">
                {group.future.map(item => renderItem(item))}
              </div>
            )}
          </div>
        )
      })}

      {/* Кнопка завершения задачи — фиксированная внизу */}
      {!loading && !error && taskId && createPortal(
        <div style={{
          position: 'fixed',
          bottom: 0,
          left: 0,
          right: 0,
          padding: '0.75rem 1rem',
          paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))',
          background: 'linear-gradient(to top, white 60%, rgba(255,255,255,0))',
          zIndex: 1500,
          display: 'flex',
          justifyContent: 'center',
        }}>
          <button
            onClick={handleCompleteTask}
            disabled={isCompleting}
            style={{
              width: '100%',
              maxWidth: '42rem',
              padding: '0.875rem',
              background: 'linear-gradient(to right, #10b981, #059669)',
              color: 'white',
              border: 'none',
              borderRadius: '0.5rem',
              fontSize: '1rem',
              fontWeight: 600,
              cursor: isCompleting ? 'not-allowed' : 'pointer',
              opacity: isCompleting ? 0.6 : 1,
              transition: 'all 0.2s',
            }}
          >
            {isCompleting ? 'Выполняется...' : 'Завершить'}
          </button>
        </div>,
        document.body
      )}

      {/* Модалка выполнения */}
      {selectedItemForDetail && (
        <ShoppingItemDetail
          itemId={selectedItemForDetail}
          onClose={handleCloseDetail}
          onRefresh={handleRefresh}
          onItemCompleted={() => setToast({ message: 'Товар выполнен', type: 'success' })}
          onNavigate={onNavigate}
        />
      )}

      {/* Модалка переноса */}
      {selectedItemForPostpone && (() => {
        const todayStr = formatDateToLocal(new Date())
        const tomorrow = new Date()
        tomorrow.setDate(tomorrow.getDate() + 1)
        const tomorrowStr = formatDateToLocal(tomorrow)

        let nextShowAtStr = null
        if (selectedItemForPostpone.next_show_at) {
          const nextShowAtDate = new Date(selectedItemForPostpone.next_show_at)
          nextShowAtStr = formatDateToLocal(nextShowAtDate)
        }

        const isTomorrow = nextShowAtStr === tomorrowStr
        const showTodayChip = !nextShowAtStr || nextShowAtStr > todayStr

        const item = selectedItemForPostpone
        let plannedDate
        const now = new Date()
        now.setHours(0, 0, 0, 0)
        if (item.repetition_period) {
          const nextDate = calculateNextDateFromRepetitionPeriod(item.repetition_period)
          if (nextDate) plannedDate = nextDate
        }
        if (!plannedDate) {
          plannedDate = new Date(now)
          plannedDate.setDate(plannedDate.getDate() + 1)
        }
        plannedDate.setHours(0, 0, 0, 0)
        const plannedDateStr = formatDateToLocal(plannedDate)
        const plannedNorm = plannedDateStr.slice(0, 10)
        const nextShowNorm = nextShowAtStr ? String(nextShowAtStr).slice(0, 10) : ''
        const isCurrentDatePlanned = plannedNorm && nextShowNorm && plannedNorm === nextShowNorm

        const modalContent = (
          <div className="task-postpone-modal-overlay" onClick={handlePostponeClose}>
            <div className="task-postpone-modal" onClick={(e) => e.stopPropagation()}>
              <div className="task-postpone-modal-header">
                <h3>{selectedItemForPostpone.name}</h3>
                <button onClick={handlePostponeClose} className="task-postpone-close-button">
                  ✕
                </button>
              </div>
              <div className="task-postpone-modal-content">
                <div className="task-postpone-calendar">
                  <DayPicker
                    mode="single"
                    selected={postponeDate ? new Date(postponeDate + 'T00:00:00') : undefined}
                    onSelect={handleDateSelect}
                    onDayClick={handleDayClick}
                    disabled={{ before: (() => {
                      const today = new Date()
                      today.setHours(0, 0, 0, 0)
                      return today
                    })() }}
                    locale={ru}
                  />
                </div>
                <div className="task-postpone-quick-buttons">
                  {showTodayChip && (
                    <button
                      className="task-postpone-quick-button"
                      onClick={handleTodayClick}
                      disabled={isPostponing}
                    >
                      Сегодня
                    </button>
                  )}
                  {!isTomorrow && (
                    <button
                      className="task-postpone-quick-button"
                      onClick={handleTomorrowClick}
                      disabled={isPostponing}
                    >
                      Завтра
                    </button>
                  )}
                  {!isCurrentDatePlanned && (
                    <button
                      className="task-postpone-quick-button"
                      onClick={() => handlePostponeSubmitWithDate(plannedDateStr)}
                      disabled={isPostponing}
                    >
                      По плану
                    </button>
                  )}
                  {nextShowAtStr && (
                    <button
                      className="task-postpone-quick-button task-postpone-quick-button-danger"
                      onClick={handleWithoutDateClick}
                      disabled={isPostponing}
                    >
                      Без даты
                    </button>
                  )}
                </div>
              </div>
            </div>
          </div>
        )
        return typeof document !== 'undefined'
          ? createPortal(modalContent, document.body)
          : modalContent
      })()}

      {toast && (
        <Toast
          message={toast.message}
          type={toast.type}
          onClose={() => setToast(null)}
        />
      )}
    </div>
  )
}

export default PurchaseScreen
