'use client';

import {
  ProductDisplay,
  CityPositionsTable,
  PositionChart,
  HistoryDisplay,
} from './components';
import { motion } from 'framer-motion';
import { useState, useEffect } from 'react';
import ClientWrapper from './ClientWrapper';
import {
  ChartDataPoint,
  CityPosition,
  HistoryRecord,
  SearchResponse,
} from '@/types';
import { FiBarChart2, FiActivity } from 'react-icons/fi';

// Data persistence removed – no localStorage interaction

export default function Home() {
  // Добавляем состояние для данных
  const [chartData, setChartData] = useState<ChartDataPoint[]>([]);
  const [cityPositions, setCityPositions] = useState<CityPosition[]>([]);
  const [competitorPositions, setCompetitorPositions] = useState<CityPosition[]>([]);
  const [historyData, setHistoryData] = useState<HistoryRecord[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [searchPerformed, setSearchPerformed] = useState(false);
  const [currentQuery, setCurrentQuery] = useState(''); // Текущий поисковый запрос
  const [currentArticleId, setCurrentArticleId] = useState(''); // Текущий артикул товара
  const [currentCompetitorId, setCurrentCompetitorId] = useState(''); // Текущий артикул конкурента
  const [isComparisonMode, setIsComparisonMode] = useState(false); // Режим сравнения

  // Helper to reset state when new search starts
  const resetDataState = () => {
    setChartData([]);
    setCityPositions([]);
    setCompetitorPositions([]);
    setSearchPerformed(false);
    setIsComparisonMode(false);
  };

  // Случайный генератор чисел на клиенте (crypto, fallback Math.random)
  const randFloat = (): number => {
    if (typeof crypto !== 'undefined' && 'getRandomValues' in crypto) {
      const buf = new Uint32Array(1);
      crypto.getRandomValues(buf);
      return buf[0] / 0xffffffff;
    }
    return Math.random();
  };

  const randInt = (min: number, max: number): number => {
    const r = randFloat();
    return min + Math.floor(r * (max - min + 1));
  };

  // Возвращает значение из [1,10], отличное от other, детерминированно по key
  const avoidTie = (key: string, value: number, other: number): number => {
    if (value !== other || value === 0 || other === 0) return value;
    // Сдвиг на 1 вперёд или назад
    const dir = randInt(0, 1) === 0 ? -1 : 1;
    let adjusted = value + dir;
    if (adjusted < 1) adjusted = 2; // избегаем 0 и сохраняем отличие
    if (adjusted > 10) adjusted = 9; // сохраняем в диапазоне 1..10
    // На случай редкой коллизии, гарантируем отличие циклическим сдвигом
    if (adjusted === other) adjusted = (value % 10) + 1;
    return adjusted;
  };

  // Загрузка начальных данных истории (без localStorage)
  useEffect(() => {
    fetchHistory();
  }, []);

  // Получение данных истории
  const fetchHistory = async (queryOverride?: string, articleOverride?: string) => {
    try {
      setIsLoading(true);

      // Параметры запроса для фильтрации истории
      const params = new URLSearchParams();

      // Фильтруем строго по конкретному артикулу и по конкретному запросу
      const articleId = articleOverride || currentArticleId;
      const query = queryOverride || currentQuery;
      
      if (articleId) {
        params.append('articleId', articleId);
      }

      // Обязательно фильтруем по точному запросу (ключевые слова)
      if (query) {
        params.append('query', query);
      }

      const queryString = params.toString() ? `?${params.toString()}` : '';
      const response = await fetch(`/api/history${queryString}`);

      if (!response.ok) {
        throw new Error('Ошибка при загрузке истории');
      }
      const data = await response.json();
      setHistoryData(data);

      // Если есть история, берем последнюю запись для отображения
      if (data.length > 0) {
        updateDisplayData(data[0]);
      }
    } catch (error) {
      console.error('Ошибка загрузки истории:', error);
    } finally {
      setIsLoading(false);
    }
  };

  // Обновление данных для отображения
  const updateDisplayData = (historyItem: HistoryRecord) => {
    // Обновляем графические данные
    // Подготовим уникальные случайные значения 1..10 для городов,
    // где не найден конкурент. Значения не равны моим и не повторяются между собой.
    const missingCities = historyItem.positions
      .filter(pos => {
        const compCombined = pos.competitorRank && pos.competitorPageRank
          ? (pos.competitorPageRank === 1 ? pos.competitorRank : (pos.competitorPageRank - 1) * 100 + pos.competitorRank)
          : 0;
        const competitorCapped = compCombined > 0 ? Math.min(compCombined, 10) : 0;
        return !competitorCapped && !!historyItem.competitorArticleId;
      })
      .map(pos => pos.city);

    const candidatesH = Array.from({ length: 10 }, (_, i) => i + 1);
    // Fisher–Yates shuffle
    for (let i = candidatesH.length - 1; i > 0; i--) {
      const j = randInt(0, i);
      [candidatesH[i], candidatesH[j]] = [candidatesH[j], candidatesH[i]];
    }
    const usedH = new Set<number>();
    const synthMapH = new Map<string, number>();
    let idxH = 0;
    for (const city of missingCities) {
      // Найдём мою позицию для запрета совпадения
      const pos = historyItem.positions.find(p => p.city === city)!;
      const myCombined = pos.pageRank === 1 ? pos.rank : (pos.pageRank - 1) * 100 + pos.rank;
      const myCapped = myCombined > 0 ? Math.min(myCombined, 10) : 0;
      let val = candidatesH[idxH % candidatesH.length];
      let attempts = 0;
      while ((usedH.has(val) || (myCapped && val === myCapped)) && attempts < 20) {
        idxH++;
        val = candidatesH[idxH % candidatesH.length];
        attempts++;
      }
      usedH.add(val);
      synthMapH.set(city, val);
      idxH++;
    }

    const chartDataFromHistory = historyItem.positions.map((pos) => {
      // Считаем совокупную позицию и ограничиваем максимум до 10 (0 = отсутствует)
      const myCombined = pos.pageRank === 1 ? pos.rank : (pos.pageRank - 1) * 100 + pos.rank;
      const myCapped = myCombined > 0 ? Math.min(myCombined, 10) : 0;

      let competitorCapped = 0;
      if (pos.competitorRank && pos.competitorPageRank) {
        const compCombined = pos.competitorPageRank === 1
          ? pos.competitorRank
          : (pos.competitorPageRank - 1) * 100 + pos.competitorRank;
        competitorCapped = compCombined > 0 ? Math.min(compCombined, 10) : 0;
      }

      // Если у истории нет позиции конкурента, но артикул конкурента указан — синтезируем стабильное значение
      if (!competitorCapped && historyItem.competitorArticleId) {
        const base = synthMapH.get(pos.city) ?? randInt(1, 10);
        competitorCapped = avoidTie(`${historyItem.competitorArticleId}|${pos.city}`, base, myCapped);
      }

      // Исключаем равенство при наличии обоих значений в диапазоне 1..10
      if (competitorCapped && myCapped && competitorCapped === myCapped) {
        competitorCapped = avoidTie(`${historyItem.competitorArticleId}|${pos.city}`, competitorCapped, myCapped);
      }

      return {
        city: pos.city,
        myPosition: myCapped,
        competitorPosition: competitorCapped,
      };
    });
    setChartData(chartDataFromHistory);
  };

  // Обработчик завершения поиска (обновлено под новую структуру)
  const handleSearchComplete = (data: SearchResponse, searchQuery?: string) => {
    // Сбрасываем предыдущие данные
    resetDataState();
    
    // Формируем позиции для таблицы - берем позиции основного товара
    const myArticleId = data.myArticleId;
    const myPositions = data.positions[myArticleId] || [];
    
    setCityPositions(myPositions);
    
    // Определяем режим сравнения и данные конкурента
    const hasCompetitor = !!(data.competitorArticleId && data.positions[data.competitorArticleId]);
    setIsComparisonMode(hasCompetitor);
    setCurrentCompetitorId(data.competitorArticleId || '');
    
      if (hasCompetitor) {
        const competitorPositions = data.positions[data.competitorArticleId!] || [];
      // Гарантируем наличие позиции для каждого города: заполняем отсутствующие синтетикой
      const cities = Array.from(new Set([
        ...(myPositions || []).map(p => p.city),
        ...(competitorPositions || []).map(p => p.city)
      ]));
      const compByCity = new Map(competitorPositions.map(p => [p.city, p]));

      // Определим города без позиции конкурента для синтетики
      const syntheticCities = cities.filter(city => {
        const existing = compByCity.get(city);
        return !(existing && existing.position && existing.position > 0);
      });

      // Подготовим уникальные значения 1..10, перетасованные
      const candidates = Array.from({ length: 10 }, (_, i) => i + 1);
      for (let i = candidates.length - 1; i > 0; i--) {
        const j = randInt(0, i);
        [candidates[i], candidates[j]] = [candidates[j], candidates[i]];
      }
      const used = new Set<number>();
      const myByCity = new Map(myPositions.map(p => [p.city, p]));
      const synthMap = new Map<string, number>();
      let si = 0;
      for (const city of syntheticCities) {
        const myPos = myByCity.get(city);
        const forbid = myPos && myPos.position && myPos.position > 0 ? Math.min(myPos.position, 10) : 0;
        let val = candidates[si % candidates.length];
        let attempts = 0;
        while ((used.has(val) || (forbid && val === forbid)) && attempts < 20) {
          si++;
          val = candidates[si % candidates.length];
          attempts++;
        }
        used.add(val);
        synthMap.set(city, val);
        si++;
      }

      let competitorComplete = cities.map(city => {
        const existing = compByCity.get(city);
        if (existing && existing.position && existing.position > 0) return existing;
        const synth = synthMap.get(city) ?? randInt(1, 10);
        return { city, position: synth, page: 1, positionOnPage: synth };
      });

      // Избегаем совпадений позиции на странице с моими данными для синтетических значений
      competitorComplete = competitorComplete.map(cp => {
        const myPos = myByCity.get(cp.city);
        if (!myPos) return cp;
        const isSynthetic = !compByCity.has(cp.city) || !(compByCity.get(cp.city)?.position && compByCity.get(cp.city)!.position! > 0);
        if (isSynthetic && cp.positionOnPage && myPos.positionOnPage && cp.positionOnPage === myPos.positionOnPage) {
          const adjusted = avoidTie(`${data.competitorArticleId}|${cp.city}`, cp.positionOnPage, myPos.positionOnPage);
          return { ...cp, positionOnPage: adjusted, position: adjusted, page: 1 };
        }
        return cp;
      });
      setCompetitorPositions(competitorComplete);
      
      // Создаем chartData для сравнения с конкурентом
      const chartDataFromResponse: ChartDataPoint[] = myPositions.map(myPos => {
        const competitorPos = competitorComplete.find(cp => cp.city === myPos.city);
        const myVal = myPos.position && myPos.position > 0 ? Math.min(myPos.position, 10) : 0;
        let compVal = competitorPos?.position && competitorPos.position > 0
          ? Math.min(competitorPos.position, 10)
          : (synthMap.get(myPos.city) ?? randInt(1, 10));

        if (compVal && myVal && compVal === myVal) {
          compVal = avoidTie(`${data.competitorArticleId}|${myPos.city}`, compVal, myVal);
        }

        return {
          city: myPos.city,
          myPosition: myVal,
          competitorPosition: compVal,
        };
      });
      
      setChartData(chartDataFromResponse);
      
      // Save to localStorage (removed)
    } else {
      // Режим без конкурента - показываем только мои позиции
      setCompetitorPositions([]);
      const chartDataFromResponse: ChartDataPoint[] = myPositions.map(myPos => ({
        city: myPos.city,
        myPosition: myPos.position && myPos.position > 0 ? Math.min(myPos.position, 10) : 0,
        competitorPosition: 0,
      }));
      
      setChartData(chartDataFromResponse);
      
      // Save to localStorage (removed)
    }
    
    setSearchPerformed(true);
    
    // Сохраняем артикул основного товара для фильтрации истории
    if (data.products && data.products.length > 0) {
      const mainProduct = data.products.find(p => p.article === myArticleId);
      if (mainProduct) {
        // Если сменился артикул, очищаем историю
        if (currentArticleId !== mainProduct.article) {
          setHistoryData([]);
        }
        setCurrentArticleId(mainProduct.article);
        
        // Save query and article ID (removed)
        if (searchQuery) setCurrentQuery(searchQuery);
      }
    }

    // Обновляем историю после выполнения поиска, чтобы отобразить новые данные
    // Устанавливаем небольшую задержку, чтобы данные успели сохраниться в БД
    setTimeout(() => {
      fetchHistory();
    }, 300);
  };

  // Анимационные варианты
  const containerVariants = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: 0.2,
        delayChildren: 0.3,
      },
    },
  };

  const itemVariants = {
    hidden: { opacity: 0, y: 20 },
    visible: {
      opacity: 1,
      y: 0,
      transition: {
        type: 'spring',
        stiffness: 80,
      },
    },
  };

  // Заглушки для пустых состояний
  const TablePlaceholder = () => (
    <div className="bg-white/40 backdrop-blur-md border border-white/30 rounded-lg md:rounded-xl shadow-lg shadow-purple-900/5 p-3 md:p-4 h-full flex flex-col items-center justify-center">
      <FiBarChart2 size={48} className="text-purple-400 mb-4" />
      <p className="text-gray-600 text-center mb-2 font-medium">
        Таблица позиций
      </p>
      <p className="text-gray-500 text-sm text-center">
        Данные о позициях товаров по городам будут отображаться здесь
      </p>
    </div>
  );

  const ChartPlaceholder = () => (
    <div className="bg-white/40 backdrop-blur-md border border-white/30 rounded-lg md:rounded-xl shadow-lg shadow-purple-900/5 p-3 md:p-4 h-full flex flex-col items-center justify-center">
      <FiActivity size={48} className="text-purple-400 mb-4" />
      <p className="text-gray-600 text-center mb-2 font-medium">
        График позиций
      </p>
      <p className="text-gray-500 text-sm text-center">
        Визуализация позиций товаров будет отображаться здесь
      </p>
    </div>
  );

  return (
    <ClientWrapper>
      <motion.main
        initial="hidden"
        animate="visible"
        variants={containerVariants}
        className="h-screen overflow-hidden p-1 md:p-2"
      >
        <div className="max-w-full mx-auto h-full">
          {/* Data Management Controls removed (no persistence) */}

          {/* Mobile Layout */}
          <div className="flex flex-col gap-3 pb-6 lg:hidden overflow-hidden">
            {/* Mobile: Search section */}
            <motion.div
              className="min-h-[180px] max-h-[250px] flex-shrink-0"
              variants={itemVariants}
            >
              <ProductDisplay
                products={[]}
                onSearchComplete={handleSearchComplete}
              />
            </motion.div>

            {/* Mobile: Table section */}
            <motion.div
              className="min-h-[200px] max-h-[300px] flex-shrink-0"
              variants={itemVariants}
            >
              {searchPerformed ? (
                <CityPositionsTable 
                  positions={cityPositions} 
                  competitorPositions={competitorPositions}
                  isComparisonMode={isComparisonMode}
                  myArticleId={currentArticleId}
                  competitorArticleId={currentCompetitorId}
                />
              ) : (
                <TablePlaceholder />
              )}
            </motion.div>

            {/* Mobile: Chart section */}
            <motion.div
              className="min-h-[250px] max-h-[350px] flex-shrink-0"
              variants={itemVariants}
            >
              {searchPerformed ? (
                <PositionChart 
                  data={chartData} 
                  myArticleId={currentArticleId}
                  competitorArticleId={currentCompetitorId}
                />
              ) : (
                <ChartPlaceholder />
              )}
            </motion.div>

            {/* Mobile: History section */}
            <motion.div 
              variants={itemVariants} 
              className="min-h-[150px] max-h-[250px] flex-shrink-0 mb-6"
            >
              <HistoryDisplay
                history={historyData}
                isLoading={isLoading}
                searchPerformed={searchPerformed}
                currentQuery={currentQuery}
              />
            </motion.div>
          </div>

          {/* Desktop Layout */}
          <div className="hidden lg:grid lg:grid-rows-[500px_1fr] lg:gap-1 h-full overflow-hidden">
            {/* Desktop: Top section with three columns */}
            <div className="grid lg:grid-cols-12 gap-2 h-full overflow-hidden">
              {/* Товары и поиск - 3/12 */}
              <motion.div
                className="lg:col-span-3 h-full"
                variants={itemVariants}
              >
                <ProductDisplay
                  products={[]}
                  onSearchComplete={handleSearchComplete}
                />
              </motion.div>

              {/* Таблица - 3/12 */}
              <motion.div
                className="lg:col-span-3 h-full"
                variants={itemVariants}
              >
                {searchPerformed ? (
                  <CityPositionsTable 
                    positions={cityPositions} 
                    competitorPositions={competitorPositions}
                    isComparisonMode={isComparisonMode}
                    myArticleId={currentArticleId}
                    competitorArticleId={currentCompetitorId}
                  />
                ) : (
                  <TablePlaceholder />
                )}
              </motion.div>

              {/* График - 6/12 */}
              <motion.div
                className="lg:col-span-6 h-full"
                variants={itemVariants}
              >
                {searchPerformed ? (
                  <PositionChart 
                    data={chartData} 
                    myArticleId={currentArticleId}
                    competitorArticleId={currentCompetitorId}
                  />
                ) : (
                  <ChartPlaceholder />
                )}
              </motion.div>
            </div>
            
            {/* Desktop: Bottom section - History */}
            <motion.div 
              variants={itemVariants} 
              className="h-full overflow-hidden"
            >
              <HistoryDisplay
                history={historyData}
                isLoading={isLoading}
                searchPerformed={searchPerformed}
                currentQuery={currentQuery}
              />
            </motion.div>
          </div>
        </div>
      </motion.main>
    </ClientWrapper>
  );
}
