import React from 'react'
import { getProjectColor, sortProjectsLikeCurrentWeek } from '../utils/projectUtils'

const formatWeekKey = ({ year, week }) => `${year}-W${week.toString().padStart(2, '0')}`

const parseWeekKey = (weekKey) => {
  const [yearStr, weekStr] = weekKey.split('-W')
  return { year: Number(yearStr), week: Number(weekStr) }
}

const compareWeekKeys = (a, b) => {
  const [yearA, weekA] = a.split('-W').map(Number)
  const [yearB, weekB] = b.split('-W').map(Number)

  if (yearA !== yearB) {
    return yearA - yearB
  }
  return weekA - weekB
}

// Функция для определения текущей недели в ISO формате
// ISO 8601: неделя начинается с понедельника, первая неделя года - та, в которой есть 4 января
const getCurrentWeek = () => {
  const now = new Date()
  const date = new Date(now.getTime())
  
  // ISO week calculation
  // Set to nearest Thursday: current date + 4 - current day number
  // Make Sunday's day number 7
  const day = date.getDay() || 7
  date.setDate(date.getDate() + 4 - day)
  
  // Get first day of year
  const yearStart = new Date(date.getFullYear(), 0, 1)
  
  // Calculate full weeks to nearest Thursday
  const week = Math.ceil((((date - yearStart) / 86400000) + 1) / 7)
  
  // ISO year is the year of the Thursday of that week
  const year = date.getFullYear()
  
  return { year, week }
}

function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedProject }) {
  // Определяем текущую неделю
  const currentWeek = getCurrentWeek()
  const currentWeekKey = formatWeekKey(currentWeek)

  // Используем переданный отсортированный список проектов или получаем из данных
  const allProjects = allProjectsSorted || (() => {
    if (!data || data.length === 0) {
      // Если нет данных, используем проекты из currentWeekData
      if (currentWeekData && currentWeekData.projects) {
        return currentWeekData.projects.map(p => p.project_name || p.name).filter(Boolean)
      }
      return []
    }
    const allProjectsSet = new Set()
    data.forEach(item => {
      allProjectsSet.add(item.project_name)
    })
    return Array.from(allProjectsSet).sort()
  })()

  // Группируем данные по неделям
  const weeksMap = {}
  
  if (data && data.length > 0) {
    data.forEach(item => {
      // Фильтруем по выбранному проекту, если он указан
      if (selectedProject && item.project_name !== selectedProject) {
        return
      }
      
      const weekKey = `${item.report_year}-W${item.report_week.toString().padStart(2, '0')}`
      
      if (!weeksMap[weekKey]) {
        weeksMap[weekKey] = []
      }
      
      weeksMap[weekKey].push({
        projectName: item.project_name,
        score: parseFloat(item.total_score) || 0,
        minGoalScore: parseFloat(item.min_goal_score) || 0,
        maxGoalScore: parseFloat(item.max_goal_score) || 0,
        normalizedTotalScore: parseFloat(item.normalized_total_score) || 0
      })
    })
  }

  // Добавляем данные текущей недели из currentWeekData, если они отсутствуют в data
  if (currentWeekData && currentWeekData.projects && !weeksMap[currentWeekKey]) {
    const projects = Array.isArray(currentWeekData.projects) 
      ? currentWeekData.projects 
      : (currentWeekData.projects?.projects || [])
    
    weeksMap[currentWeekKey] = projects.map(project => ({
      projectName: project.project_name || project.name,
      score: parseFloat(project.total_score || project.score || 0),
      normalizedTotalScore: parseFloat(project.normalized_total_score) || 0
    })).filter(p => {
      // Фильтруем по выбранному проекту, если он указан
      if (selectedProject && p.projectName !== selectedProject) {
        return false
      }
      return true
    })
  }

  // Получаем все уникальные недели и сортируем их (новые сверху)
  const allWeeks = Object.keys(weeksMap).sort((a, b) => -compareWeekKeys(a, b))
  
  // Находим индекс текущей недели
  const currentWeekIndex = allWeeks.findIndex(w => w === currentWeekKey)
  
  // Разделяем недели на группы
  // allWeeks отсортированы от новых к старым (индекс 0 - самая новая)
  // Если currentWeekIndex = 2:
  // - allWeeks[0, 1] - более новые недели (будущие, если есть)
  // - allWeeks[2] - текущая неделя
  // - allWeeks[3, 4, ...] - более старые недели (прошлые)
  let last4Weeks = []  // Последние 4 недели ДО текущей (более старые)
  let next4Weeks = []  // Следующие 4 недели ПОСЛЕ текущей (более новые, если есть)
  let currentWeekInData = null

  if (currentWeekIndex >= 0) {
    // Текущая неделя найдена в данных
    // Берем 4 недели ДО текущей (более старые) - это индексы после currentWeekIndex
    last4Weeks = allWeeks.slice(currentWeekIndex + 1, currentWeekIndex + 5)
    // Берем 4 недели ПОСЛЕ текущей (более новые) - это индексы до currentWeekIndex
    next4Weeks = allWeeks.slice(Math.max(0, currentWeekIndex - 4), currentWeekIndex)
    // Текущая неделя
    currentWeekInData = currentWeekKey
  } else {
    // Текущая неделя не найдена в данных, но мы её добавили из currentWeekData
    if (weeksMap[currentWeekKey]) {
      // Добавляем текущую неделю в начало списка (она самая новая)
      const weeksWithCurrent = [currentWeekKey, ...allWeeks]
      // Последние 4 недели - это первые 4 из старых данных (более старые)
      last4Weeks = allWeeks.slice(0, 4)
      // Следующие недели после текущей - их нет, так как текущая самая новая
      next4Weeks = []
      currentWeekInData = currentWeekKey
    } else {
      // Если текущей недели нет вообще, просто берем последние 4 (самые новые из доступных)
      last4Weeks = allWeeks.slice(0, 4)
      next4Weeks = []
    }
  }

  // Функция для обработки данных недели
  const processWeekData = (weekKey) => {
    const { year, week } = parseWeekKey(weekKey)
    const weekProjects = weeksMap[weekKey] || []
    const totalScore = weekProjects.reduce((sum, p) => sum + p.score, 0)
    
    // Используем абсолютные значения (баллы)
    // Сортируем проекты так же, как в полной статистике (по priority и min_goal_score)
    // Получаем цвет проекта из данных full-statistics, если доступен
    const projectsWithData = weekProjects.map(project => {
      // Ищем данные проекта в full-statistics для получения цвета и calculated_score
      const projectData = data?.find(item => 
        item.project_name === project.projectName && 
        item.report_year === year && 
        item.report_week === week
      )
      const projectColor = projectData?.color 
        ? getProjectColor(project.projectName, allProjects, projectData.color)
        : getProjectColor(project.projectName, allProjects)
      
      return {
        ...project,
        color: projectColor,
        normalizedTotalScore: projectData?.normalized_total_score !== undefined ? parseFloat(projectData.normalized_total_score) || 0 : project.normalizedTotalScore || 0
      }
    })
    
    // Применяем ту же сортировку, что и в FullStatistics
    const projectNames = projectsWithData.map(p => p.projectName)
    const sortedProjectNames = currentWeekData 
      ? sortProjectsLikeCurrentWeek(projectNames, currentWeekData)
      : projectNames
    
    // Пересобираем projectsWithData в правильном порядке
    const sortedProjectsWithData = sortedProjectNames.map(name => {
      return projectsWithData.find(p => p.projectName === name)
    }).filter(Boolean)
    
    return {
      weekKey,
      year,
      week,
      projects: sortedProjectsWithData,
      totalScore,
      isCurrent: weekKey === currentWeekKey
    }
  }

  // Обрабатываем данные для всех недель
  const currentWeekDataProcessed = currentWeekInData ? processWeekData(currentWeekInData) : null
  
  // Объединяем все недели кроме текущей
  // next4Weeks уже отсортированы от новых к старым (индексы 0..currentWeekIndex-1)
  // last4Weeks уже отсортированы от новых к старым (индексы currentWeekIndex+1..)
  // Для отображения: старые сверху, новые снизу - нужно перевернуть порядок
  // Объединяем: сначала более старые (last4Weeks), потом более новые (next4Weeks)
  const allOtherWeeks = [...last4Weeks, ...next4Weeks]
  // Переворачиваем, чтобы старые были сверху, новые снизу
  const allOtherWeeksData = allOtherWeeks.map(processWeekData).reverse()

  // Объединяем все недели для расчета максимального значения
  const allWeeksData = [...(currentWeekDataProcessed ? [currentWeekDataProcessed] : []), ...allOtherWeeksData]
  
  // Находим максимальное значение среди всех недель для единой шкалы сравнения
  const maxTotalScore = Math.max(...allWeeksData.map(w => w.totalScore), 1)

  if (allWeeksData.length === 0) {
    return null
  }

  // Компонент для отображения прогрессбара недели
  const WeekProgressBar = ({ weekData }) => {
    // Находим выбранный проект в данных недели для отображения normalized значения
    const selectedProjectData = selectedProject 
      ? weekData.projects.find(p => p.projectName === selectedProject)
      : null
    
    return (
      <div className="flex items-center gap-3">
        <div className="min-w-[85px] text-sm font-medium text-gray-700">
          Неделя {weekData.week}
        </div>
        <div className="flex-1 relative h-6 bg-gray-200 rounded-full overflow-hidden shadow-inner">
          {weekData.totalScore === 0 ? (
            <div className="absolute inset-0 flex items-center justify-center text-gray-400 text-xs">
              Нет данных
            </div>
          ) : (
            <>
              {weekData.projects.map((project, index) => {
                // Вычисляем позицию и ширину для каждого сегмента на основе абсолютных значений
                let left = 0
                for (let i = 0; i < index; i++) {
                  left += weekData.projects[i].score
                }
                
                const widthPercent = (project.score / maxTotalScore) * 100
                const leftPercent = (left / maxTotalScore) * 100
                
                return (
                  <div
                    key={project.projectName}
                    className="absolute h-full transition-all duration-300 hover:opacity-90"
                    style={{
                      left: `${leftPercent}%`,
                      width: `${widthPercent}%`,
                      backgroundColor: project.color,
                    }}
                    title={`${project.projectName}: ${project.score.toFixed(1)} баллов`}
                  />
                )
              })}
            </>
          )}
        </div>
        <div className="min-w-[85px] text-right text-sm text-gray-600 font-medium">
          {weekData.totalScore > 0 ? (
            <>
              {selectedProjectData && 
               selectedProjectData.normalizedTotalScore !== undefined && 
               selectedProjectData.normalizedTotalScore !== null && 
               selectedProjectData.normalizedTotalScore > 0 &&
               Math.abs(selectedProjectData.normalizedTotalScore - selectedProjectData.score) > 0.01 ? (
                <>
                  <span className="text-gray-400">
                    ({selectedProjectData.normalizedTotalScore.toFixed(1)})
                  </span>
                  <span className="ml-1">
                    {selectedProjectData.score.toFixed(1)}
                  </span>
                </>
              ) : (
                weekData.totalScore.toFixed(1)
              )}
            </>
          ) : '-'}
        </div>
      </div>
    )
  }

  return (
    <div>
      <h2 className="text-2xl font-semibold text-gray-800 mb-6" style={{ marginTop: '1.25rem' }}>Прогресс недель</h2>
      <div className="space-y-3">
        {/* Остальные недели (старые сверху, новые снизу) */}
        {allOtherWeeksData.map((weekData) => (
          <WeekProgressBar key={weekData.weekKey} weekData={weekData} />
        ))}
        
        {/* Разделитель перед текущей неделей */}
        {currentWeekDataProcessed && (
          <div className="border-t border-gray-300 my-3"></div>
        )}
        
        {/* Текущая неделя (последняя) */}
        {currentWeekDataProcessed && (
          <>
            <h3 className="text-lg font-semibold text-gray-800 mb-2">Текущая неделя</h3>
            <WeekProgressBar weekData={currentWeekDataProcessed} />
          </>
        )}
      </div>
    </div>
  )
}

export default WeekProgressChart

