import React, { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import LoadingError from './LoadingError'
import { useAuth } from './auth/AuthContext'
import TaskDetail from './TaskDetail'

// Функция для форматирования скорa (аналогично formatScore из TaskDetail)
const formatScore = (num) => {
  if (num === 0) return '0'

  let str = num.toPrecision(4)
  str = str.replace(/\.?0+$/, '')

  if (str.includes('e+') || str.includes('e-')) {
    const numValue = parseFloat(str)
    if (Math.abs(numValue) >= 10000) {
      return str
    }
    return numValue.toString().replace(/\.?0+$/, '')
  }

  return str
}

// Функция для форматирования текста с заменой плейсхолдеров на nodes
const formatEntryText = (text, nodes) => {
  if (!text || !nodes || nodes.length === 0) {
    return text
  }

  // Создаем map для быстрого доступа к nodes по индексу
  const nodesMap = {}
  nodes.forEach(node => {
    nodesMap[node.index] = node
  })

  // Создаем массив для хранения частей текста и React элементов
  const parts = []
  let lastIndex = 0
  let currentText = text

  // Сначала защищаем экранированные плейсхолдеры
  const escapedMarkers = {}
  for (let i = 0; i < 100; i++) {
    const escaped = `\\$${i}`
    const marker = `__ESCAPED_DOLLAR_${i}__`
    if (currentText.includes(escaped)) {
      escapedMarkers[marker] = escaped
      currentText = currentText.replace(new RegExp(escaped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), marker)
    }
  }

  // Заменяем ${0}, ${1}, и т.д.
  for (let i = 0; i < 100; i++) {
    const placeholder = `\${${i}}`
    const regex = new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')
    if (nodesMap[i] && currentText.includes(placeholder)) {
      const node = nodesMap[i]
      const scoreStr = node.score >= 0
        ? `${node.project_name}+${formatScore(node.score)}`
        : `${node.project_name}-${formatScore(Math.abs(node.score))}`
      currentText = currentText.replace(regex, `__NODE_${i}__`)
      // Сохраняем информацию о замене
      if (!escapedMarkers[`__NODE_${i}__`]) {
        escapedMarkers[`__NODE_${i}__`] = { type: 'node', text: scoreStr }
      }
    }
  }

  // Заменяем $0, $1, и т.д. (с конца, чтобы не заменить $1 в $10)
  for (let i = 99; i >= 0; i--) {
    if (nodesMap[i]) {
      const node = nodesMap[i]
      const scoreStr = node.score >= 0
        ? `${node.project_name}+${formatScore(node.score)}`
        : `${node.project_name}-${formatScore(Math.abs(node.score))}`
      const regex = new RegExp(`\\$${i}(?!\\d)`, 'g')
      if (currentText.match(regex)) {
        currentText = currentText.replace(regex, `__NODE_${i}__`)
        if (!escapedMarkers[`__NODE_${i}__`]) {
          escapedMarkers[`__NODE_${i}__`] = { type: 'node', text: scoreStr }
        }
      }
    }
  }

  // Разбиваем текст на части и создаем React элементы
  const result = []
  let searchIndex = 0

  while (searchIndex < currentText.length) {
    // Ищем следующий маркер
    let foundMarker = null
    let markerIndex = currentText.length

    // Ищем все маркеры
    for (const marker in escapedMarkers) {
      const index = currentText.indexOf(marker, searchIndex)
      if (index !== -1 && index < markerIndex) {
        markerIndex = index
        foundMarker = marker
      }
    }

    // Если нашли маркер
    if (foundMarker) {
      // Добавляем текст до маркера
      if (markerIndex > searchIndex) {
        result.push(currentText.substring(searchIndex, markerIndex))
      }

      // Добавляем элемент для маркера
      const markerData = escapedMarkers[foundMarker]
      if (markerData && markerData.type === 'node') {
        result.push(
          <strong key={`node-${searchIndex}`}>{markerData.text}</strong>
        )
      } else if (typeof markerData === 'string') {
        // Это экранированный плейсхолдер
        result.push(markerData)
      }

      searchIndex = markerIndex + foundMarker.length
    } else {
      // Больше маркеров нет, добавляем оставшийся текст
      if (searchIndex < currentText.length) {
        result.push(currentText.substring(searchIndex))
      }
      break
    }
  }

  return result.length > 0 ? result : currentText
}

// Модальное окно редактирования записи
function EditEntryModal({ entry, onClose, onSuccess, authFetch }) {
  const [message, setMessage] = useState(() => {
    // Заменяем ${N} на $N для удобного отображения
    return (entry.text || '').replace(/\$\{(\d+)\}/g, '$$$1')
  })
  const [rewards, setRewards] = useState(() => {
    if (!entry.nodes || entry.nodes.length === 0) return []
    const sorted = [...entry.nodes].sort((a, b) => a.index - b.index)
    return sorted.map((node, idx) => ({
      position: idx,
      project_name: node.project_name,
      value: String(node.score)
    }))
  })
  const [projects, setProjects] = useState([])
  const [isSending, setIsSending] = useState(false)
  const [error, setError] = useState(null)
  const debounceTimer = useRef(null)

  useEffect(() => {
    const loadProjects = async () => {
      try {
        const response = await authFetch('/projects')
        if (response.ok) {
          const data = await response.json()
          setProjects(Array.isArray(data) ? data : [])
        }
      } catch (err) {
        console.error('Error loading projects:', err)
      }
    }
    loadProjects()
  }, [authFetch])

  const findMaxPlaceholderIndex = (msg) => {
    if (!msg) return -1
    const indices = []
    const matchesCurly = msg.match(/\$\{(\d+)\}/g) || []
    matchesCurly.forEach(match => {
      const numMatch = match.match(/\d+/)
      if (numMatch) indices.push(parseInt(numMatch[0]))
    })
    let searchIndex = 0
    while (true) {
      const index = msg.indexOf('$', searchIndex)
      if (index === -1) break
      if (index === 0 || msg[index - 1] !== '\\') {
        const afterDollar = msg.substring(index + 1)
        const digitMatch = afterDollar.match(/^(\d+)/)
        if (digitMatch) {
          indices.push(parseInt(digitMatch[0]))
        }
      }
      searchIndex = index + 1
    }
    return indices.length > 0 ? Math.max(...indices) : -1
  }

  // Пересчет rewards при изменении сообщения
  useEffect(() => {
    if (debounceTimer.current) clearTimeout(debounceTimer.current)
    debounceTimer.current = setTimeout(() => {
      const maxIndex = findMaxPlaceholderIndex(message)
      setRewards(prevRewards => {
        const currentRewards = [...prevRewards]
        while (currentRewards.length > maxIndex + 1) currentRewards.pop()
        while (currentRewards.length < maxIndex + 1) {
          currentRewards.push({ position: currentRewards.length, project_name: '', value: '0' })
        }
        return currentRewards
      })
    }, 500)
    return () => { if (debounceTimer.current) clearTimeout(debounceTimer.current) }
  }, [message])

  const handleRewardChange = (index, field, value) => {
    const newRewards = [...rewards]
    newRewards[index] = { ...newRewards[index], [field]: value }
    setRewards(newRewards)
  }

  const buildFinalMessage = () => {
    let result = message
    const rewardStrings = {}
    rewards.forEach((reward, index) => {
      const score = parseFloat(reward.value) || 0
      const projectName = reward.project_name.trim()
      if (!projectName) return
      const scoreStr = score >= 0
        ? `**${projectName}+${score}**`
        : `**${projectName}${score}**`
      rewardStrings[index] = scoreStr
    })
    for (let i = 0; i < 100; i++) {
      const placeholder = `\${${i}}`
      if (rewardStrings[i]) result = result.split(placeholder).join(rewardStrings[i])
    }
    for (let i = 99; i >= 0; i--) {
      if (rewardStrings[i]) {
        const regex = new RegExp(`\\$${i}(?!\\d)`, 'g')
        result = result.replace(regex, rewardStrings[i])
      }
    }
    return result
  }

  const isFormValid = () => {
    if (rewards.length === 0) return true
    return rewards.every(reward => {
      const projectName = reward.project_name?.trim() || ''
      const value = reward.value?.toString().trim() || ''
      return projectName !== '' && value !== ''
    })
  }

  const handleSubmit = async () => {
    for (const reward of rewards) {
      if (!reward.project_name.trim()) {
        setError('Заполните все проекты')
        return
      }
    }
    const finalMessage = buildFinalMessage()
    if (!finalMessage.trim()) {
      setError('Введите сообщение')
      return
    }

    setIsSending(true)
    setError(null)
    try {
      const response = await authFetch(`/api/entries/${entry.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: finalMessage })
      })
      if (!response.ok) throw new Error('Ошибка при сохранении')
      onSuccess()
    } catch (err) {
      console.error('Error updating entry:', err)
      setError(err.message || 'Ошибка при сохранении')
    } finally {
      setIsSending(false)
    }
  }

  const modalContent = (
    <div className="add-entry-modal-overlay" onClick={onClose}>
      <div className="add-entry-modal" onClick={(e) => e.stopPropagation()}>
        <div className="add-entry-modal-header">
          <h2 className="add-entry-modal-title">Редактировать запись</h2>
          <button onClick={onClose} className="add-entry-close-button">✕</button>
        </div>
        <div className="add-entry-modal-content">
          <div className="add-entry-field">
            <label className="add-entry-label">Сообщение</label>
            <textarea
              value={message}
              onChange={(e) => setMessage(e.target.value)}
              placeholder="Используйте $0, $1 для указания проектов"
              className="add-entry-textarea"
              rows={3}
            />
          </div>
          {rewards.length > 0 && (
            <div className="add-entry-rewards">
              {rewards.map((reward, index) => (
                <div key={index} className="add-entry-reward-item">
                  <span className="add-entry-reward-number">{index}</span>
                  <input
                    type="text"
                    value={reward.project_name}
                    onChange={(e) => handleRewardChange(index, 'project_name', e.target.value)}
                    placeholder="Проект"
                    className="add-entry-input add-entry-project-input"
                    list={`edit-entry-projects-${index}`}
                  />
                  <datalist id={`edit-entry-projects-${index}`}>
                    {projects.map(p => (
                      <option key={p.project_id} value={p.project_name} />
                    ))}
                  </datalist>
                  <input
                    type="number"
                    step="any"
                    value={reward.value}
                    onChange={(e) => handleRewardChange(index, 'value', e.target.value)}
                    placeholder="Баллы"
                    className="add-entry-input add-entry-score-input"
                  />
                </div>
              ))}
            </div>
          )}
          {error && (
            <div style={{ color: '#ef4444', fontSize: '0.875rem', marginBottom: '0.5rem' }}>{error}</div>
          )}
          <button
            onClick={handleSubmit}
            disabled={isSending || !isFormValid()}
            className="add-entry-submit-button"
          >
            {isSending ? 'Сохранение...' : 'Сохранить'}
          </button>
        </div>
      </div>
    </div>
  )

  return typeof document !== 'undefined'
    ? createPortal(modalContent, document.body)
    : modalContent
}

function TodayEntriesList({ data, loading, error, onRetry, onDelete, onNavigate }) {
  const { authFetch } = useAuth()
  const [deletingIds, setDeletingIds] = useState(new Set())
  const [selectedTaskId, setSelectedTaskId] = useState(null)
  const [editingEntry, setEditingEntry] = useState(null)
  const [removingAutoCompleteId, setRemovingAutoCompleteId] = useState(null)
  const selectedTaskIdRef = useRef(null)
  const historyPushedRef = useRef(false)

  // Обновляем ref при изменении selectedTaskId
  useEffect(() => {
    selectedTaskIdRef.current = selectedTaskId
  }, [selectedTaskId])

  // Управление историей браузера при открытии/закрытии TaskDetail
  useEffect(() => {
    if (selectedTaskId && !historyPushedRef.current) {
      window.history.pushState({ modalOpen: true, type: 'task-detail-statistics' }, '', window.location.href)
      historyPushedRef.current = true
    } else if (!selectedTaskId) {
      historyPushedRef.current = false
    }

    if (!selectedTaskId) return

    const handlePopState = () => {
      if (selectedTaskIdRef.current) {
        setSelectedTaskId(null)
        historyPushedRef.current = false
      }
    }

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

  const handleOpenTaskDetail = (taskId) => {
    setSelectedTaskId(taskId)
  }

  const handleCloseTaskDetail = (skipHistoryBack = false) => {
    if (!skipHistoryBack && historyPushedRef.current) {
      window.history.back()
    } else {
      historyPushedRef.current = false
      setSelectedTaskId(null)
    }
  }

  const handleTaskSaved = () => {
    if (onDelete) onDelete()
  }

  const handleRemoveAutoComplete = async (taskId) => {
    if (!window.confirm('Убрать автовыполнение этой задачи в конце дня?')) return

    setRemovingAutoCompleteId(taskId)
    try {
      const response = await authFetch(`/api/tasks/${taskId}/draft`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ auto_complete: false })
      })
      if (!response.ok) throw new Error('Ошибка при обновлении')
      if (onDelete) onDelete()
    } catch (err) {
      console.error('Remove auto-complete failed:', err)
      alert(err.message || 'Не удалось убрать автовыполнение')
    } finally {
      setRemovingAutoCompleteId(null)
    }
  }

  const handleDelete = async (entryId) => {
    if (deletingIds.has(entryId)) return

    if (!window.confirm('Вы уверены, что хотите удалить эту запись? Это действие нельзя отменить.')) {
      return
    }

    setDeletingIds(prev => new Set(prev).add(entryId))

    try {
      const response = await authFetch(`/api/entries/${entryId}`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
      })

      if (!response.ok) {
        const errorText = await response.text()
        console.error('Delete error:', response.status, errorText)
        throw new Error(`Ошибка при удалении записи: ${response.status}`)
      }

      if (onDelete) onDelete()
    } catch (err) {
      console.error('Delete failed:', err)
      alert(err.message || 'Не удалось удалить запись')
    } finally {
      setDeletingIds(prev => {
        const next = new Set(prev)
        next.delete(entryId)
        return next
      })
    }
  }

  if (loading) {
    return (
      <div className="flex justify-center items-center py-8">
        <div className="w-8 h-8 border-4 border-indigo-200 border-t-indigo-600 rounded-full animate-spin"></div>
      </div>
    )
  }

  if (error) {
    return <LoadingError onRetry={onRetry} />
  }

  if (!data || data.length === 0) {
    return (
      <div className="text-center py-8 text-gray-500">
        Нет записей за выбранный день
      </div>
    )
  }

  return (
    <>
    <div className="mt-2 mb-6">
      <div className="space-y-3">
        {data.map((entry) => {
          const isDraft = entry.is_draft === true
          return (
            <div
              key={isDraft ? `draft-${entry.task_id}` : entry.id}
              className={`bg-white rounded-lg p-4 shadow-sm border relative group ${
                isDraft ? 'border-blue-400 cursor-pointer' : 'border-gray-200 cursor-pointer'
              }`}
              onClick={() => {
                if (isDraft) {
                  handleOpenTaskDetail(entry.task_id)
                } else {
                  setEditingEntry(entry)
                }
              }}
            >
              {isDraft ? (
                // Кнопка-молния с зачёркиванием — убрать автовыполнение
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    handleRemoveAutoComplete(entry.task_id)
                  }}
                  disabled={removingAutoCompleteId === entry.task_id}
                  className="absolute top-4 right-4"
                  style={{
                    color: '#3b82f6',
                    background: 'none',
                    border: 'none',
                    cursor: 'pointer',
                    padding: '0.25rem',
                    borderRadius: '0.25rem',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    width: '24px',
                    height: '24px',
                    transition: 'all 0.2s',
                    opacity: removingAutoCompleteId === entry.task_id ? 0.5 : 1,
                    zIndex: 10
                  }}
                  onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = '#eff6ff' }}
                  onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent' }}
                  title="Убрать автовыполнение"
                >
                  {/* Молния с зачёркиванием */}
                  <svg width="16" height="16" viewBox="0 0 24 24">
                    <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" fill="currentColor" />
                    {/* Зачёркивающая линия: белая с синей обводкой */}
                    <line x1="3" y1="21" x2="21" y2="3" stroke="white" strokeWidth="4" strokeLinecap="round" />
                    <line x1="3" y1="21" x2="21" y2="3" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
                  </svg>
                </button>
              ) : (
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    handleDelete(entry.id)
                  }}
                  disabled={deletingIds.has(entry.id)}
                  className="absolute top-4 right-4 disabled:opacity-50 disabled:cursor-not-allowed"
                  style={{
                    color: '#6b7280',
                    background: 'none',
                    border: 'none',
                    cursor: 'pointer',
                    padding: '0.25rem',
                    borderRadius: '0.25rem',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    width: '24px',
                    height: '24px',
                    transition: 'all 0.2s',
                    opacity: deletingIds.has(entry.id) ? 0.5 : 1,
                    zIndex: 10
                  }}
                  onMouseEnter={(e) => {
                    if (!deletingIds.has(entry.id)) {
                      e.currentTarget.style.backgroundColor = '#f3f4f6'
                      e.currentTarget.style.color = '#1f2937'
                    }
                  }}
                  onMouseLeave={(e) => {
                    e.currentTarget.style.backgroundColor = 'transparent'
                    e.currentTarget.style.color = '#6b7280'
                  }}
                  title="Удалить запись"
                >
                  {deletingIds.has(entry.id) ? (
                    <svg className="w-5 h-5 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                      <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                    </svg>
                  ) : (
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M3 6h18"></path>
                      <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                      <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                      <line x1="10" y1="11" x2="10" y2="17"></line>
                      <line x1="14" y1="11" x2="14" y2="17"></line>
                    </svg>
                  )}
                </button>
              )}
              <div className="text-gray-800 whitespace-pre-wrap pr-8">
                {formatEntryText(entry.text, entry.nodes)}
              </div>
              <div className="text-xs text-gray-500 mt-2">
                {isDraft ? 'в конце дня' : (
                  entry.created_date && new Date(entry.created_date).toLocaleTimeString('ru-RU', {
                    hour: '2-digit',
                    minute: '2-digit'
                  })
                )}
              </div>
            </div>
          )
        })}
      </div>
    </div>
    {selectedTaskId && (
      <TaskDetail
        taskId={selectedTaskId}
        onClose={handleCloseTaskDetail}
        onRefresh={handleTaskSaved}
        onNavigate={onNavigate}
      />
    )}
    {editingEntry && (
      <EditEntryModal
        entry={editingEntry}
        onClose={() => setEditingEntry(null)}
        onSuccess={() => {
          setEditingEntry(null)
          if (onDelete) onDelete()
        }}
        authFetch={authFetch}
      />
    )}
    </>
  )
}

export default TodayEntriesList
