import { MergedCell } from '@/type/template'
import { MergedCellInfo } from './types'

export function getColumnLabel(index: number): string {
  let label = ''
  let col = index
  while (col >= 0) {
    label = String.fromCharCode(65 + (col % 26)) + label
    col = Math.floor(col / 26) - 1
  }
  return label
}

// Создает адрес ячейки из координат (например, A1, B2)
export function createCellAddress(row: number, col: number): string {
  return getColumnLabel(col) + (row + 1)
}

// Создает квалифицированную ссылку на ячейку с указанием листа
export function createQualifiedCellReference(
  sheetType: 'report' | 'calculations',
  row: number,
  col: number
): string {
  const sheetName = sheetType === 'report' ? 'L' : 'R'
  const cellAddress = createCellAddress(row, col)
  return `${sheetName}!${cellAddress}`
}

export function findMergedCellInfo(
  row: number,
  col: number,
  mergedCells: MergedCell[]
): MergedCellInfo {
  for (const mergedCell of mergedCells) {
    const { startRow, startCol, endRow, endCol } = mergedCell

    // Проверяем, попадает ли ячейка в диапазон объединенных ячеек
    if (row >= startRow && row <= endRow && col >= startCol && col <= endCol) {
      // Это главная ячейка (левая верхняя)
      const isMainCell = row === startRow && col === startCol

      return {
        isMerged: true,
        isMainCell,
        mergedCell,
        spans: {
          rowSpan: endRow - startRow + 1,
          colSpan: endCol - startCol + 1,
        },
      }
    }
  }

  return { isMerged: false, isMainCell: false }
}

// Регулярные выражения для разных типов ссылок на ячейки
const QUALIFIED_REF_RE = /\b[A-Za-z0-9_]+![A-Z]+[0-9]+\b/g // SheetName!A1
const LOCAL_REF_RE = /\b[A-Z]+[0-9]+\b/g // A1, B2, etc.
const RANGE_RE = /\b[A-Z]+[0-9]+:[A-Z]+[0-9]+\b/g // A1:B2, D5:D7, etc.
const QUALIFIED_RANGE_RE = /\b[A-Za-z0-9_]+![A-Z]+[0-9]+:[A-Z]+[0-9]+\b/g // SheetName!A1:B2

// Интерфейс для ссылки на ячейку
export interface CellReference {
  sheet: string | null // null для локальных ссылок
  address: string // например "A1" или "B2:C3"
  isRange: boolean
  startRow: number
  startCol: number
  endRow: number
  endCol: number
}

// Парсит адрес ячейки типа "A1" в координаты
export function parseCellAddress(
  address: string
): { row: number; col: number } | null {
  const match = address.match(/^([A-Z]+)(\d+)$/)
  if (!match) return null

  const column = match[1]
  const row = parseInt(match[2], 10)

  // Конвертируем колонку в индекс
  let colIndex = 0
  for (let i = 0; i < column.length; i++) {
    colIndex = colIndex * 26 + (column.charCodeAt(i) - 65 + 1)
  }
  colIndex -= 1 // Конвертируем в 0-based индекс

  return { row: row - 1, col: colIndex } // Конвертируем в 0-based индексы
}

// Парсит диапазон ячеек типа "A1:B2"
export function parseCellRange(range: string): {
  startRow: number
  startCol: number
  endRow: number
  endCol: number
} | null {
  const parts = range.split(':')
  if (parts.length !== 2) return null

  const start = parseCellAddress(parts[0])
  const end = parseCellAddress(parts[1])

  if (!start || !end) return null

  return {
    startRow: Math.min(start.row, end.row),
    startCol: Math.min(start.col, end.col),
    endRow: Math.max(start.row, end.row),
    endCol: Math.max(start.col, end.col),
  }
}

// Извлекает все ссылки на ячейки из формулы
export function extractCellReferences(formula: string): CellReference[] {
  if (!formula.startsWith('=')) return []

  const expr = formula.substring(1) // Убираем знак =
  const references: CellReference[] = []

  // Функция для проверки, не является ли ссылка частью имени функции
  const isFunction = (ref: string): boolean => {
    const commonFunctions = [
      'SUM',
      'AVERAGE',
      'COUNT',
      'MAX',
      'MIN',
      'IF',
      'AND',
      'OR',
      'NOT',
      'СУММ',
      'СРЕДНЕЕ',
      'СЧЁТ',
      'МАКС',
      'МИН',
      'ЕСЛИ',
    ]
    return commonFunctions.includes(ref.toUpperCase())
  }

  // 1. Обрабатываем квалифицированные диапазоны (SheetName!A1:B2)
  const qualifiedRangeMatches = expr.match(QUALIFIED_RANGE_RE)
  if (qualifiedRangeMatches) {
    for (const match of qualifiedRangeMatches) {
      const [sheetPart, rangePart] = match.split('!')
      const rangeCoords = parseCellRange(rangePart)

      if (rangeCoords) {
        references.push({
          sheet: sheetPart,
          address: rangePart,
          isRange: true,
          ...rangeCoords,
        })
      }
    }
  }

  // 2. Обрабатываем локальные диапазоны (A1:B2)
  let cleanExpr = expr
  // Удаляем уже обработанные квалифицированные диапазоны
  cleanExpr = cleanExpr.replace(QUALIFIED_RANGE_RE, '')

  const rangeMatches = cleanExpr.match(RANGE_RE)
  if (rangeMatches) {
    for (const match of rangeMatches) {
      const rangeCoords = parseCellRange(match)

      if (rangeCoords) {
        references.push({
          sheet: null,
          address: match,
          isRange: true,
          ...rangeCoords,
        })
      }
    }
  }

  // 3. Обрабатываем квалифицированные одиночные ссылки (SheetName!A1)
  const qualifiedMatches = expr.match(QUALIFIED_REF_RE)
  if (qualifiedMatches) {
    for (const match of qualifiedMatches) {
      const [sheetPart, cellPart] = match.split('!')
      const cellCoords = parseCellAddress(cellPart)

      if (cellCoords) {
        references.push({
          sheet: sheetPart,
          address: cellPart,
          isRange: false,
          startRow: cellCoords.row,
          startCol: cellCoords.col,
          endRow: cellCoords.row,
          endCol: cellCoords.col,
        })
      }
    }
  }

  // 4. Обрабатываем локальные одиночные ссылки (A1, B2)
  // Удаляем уже обработанные квалифицированные ссылки и диапазоны
  cleanExpr = expr
    .replace(QUALIFIED_RANGE_RE, '')
    .replace(QUALIFIED_REF_RE, '')
    .replace(RANGE_RE, '')

  const localMatches = cleanExpr.match(LOCAL_REF_RE)
  if (localMatches) {
    for (const match of localMatches) {
      // Пропускаем функции
      if (isFunction(match)) continue

      const cellCoords = parseCellAddress(match)

      if (cellCoords) {
        references.push({
          sheet: null,
          address: match,
          isRange: false,
          startRow: cellCoords.row,
          startCol: cellCoords.col,
          endRow: cellCoords.row,
          endCol: cellCoords.col,
        })
      }
    }
  }

  return references
}

// Интерфейс для подсвеченной ячейки
export interface HighlightedCell {
  sheet: string // нормализованное имя листа ('L' или 'R')
  row: number
  col: number
  color: string // класс CSS для цвета подсветки
}

// Конвертирует ссылки на ячейки в подсвеченные ячейки
export function convertReferencesToHighlights(
  references: CellReference[],
  currentSheetType: 'report' | 'calculations'
): HighlightedCell[] {
  const highlights: HighlightedCell[] = []
  const colors = [
    'bg-blue-200 text-blue-600',
    'bg-green-200 text-green-600',
    'bg-purple-200 text-purple-600',
    'bg-red-200 text-red-600',
    'bg-yellow-200 text-yellow-600',
    'bg-indigo-200 text-indigo-600',
    'bg-pink-200 text-pink-600',
    'bg-orange-200 text-orange-600',
  ]

  let colorIndex = 0

  for (const ref of references) {
    let sheetName: string

    // Определяем имя листа
    if (ref.sheet) {
      // Квалифицированная ссылка
      if (ref.sheet === 'L' || ref.sheet.toLowerCase() === 'report') {
        sheetName = 'L'
      } else if (
        ref.sheet === 'R' ||
        ref.sheet.toLowerCase() === 'calculations'
      ) {
        sheetName = 'R'
      } else {
        // Неизвестный лист, пропускаем
        continue
      }
    } else {
      // Локальная ссылка - используем текущий лист
      sheetName = currentSheetType === 'report' ? 'L' : 'R'
    }

    const color = colors[colorIndex % colors.length]
    colorIndex++

    // Добавляем все ячейки в диапазоне
    for (let row = ref.startRow; row <= ref.endRow; row++) {
      for (let col = ref.startCol; col <= ref.endCol; col++) {
        highlights.push({
          sheet: sheetName,
          row,
          col,
          color,
        })
      }
    }
  }

  return highlights
}

// Функции для работы с выделением множества ячеек
import { CellSelection } from './types'

export const isInSelection = (
  row: number,
  col: number,
  selection: CellSelection
): boolean => {
  const { startRow, startCol, endRow, endCol } = selection
  const minRow = Math.min(startRow, endRow)
  const maxRow = Math.max(startRow, endRow)
  const minCol = Math.min(startCol, endCol)
  const maxCol = Math.max(startCol, endCol)

  return row >= minRow && row <= maxRow && col >= minCol && col <= maxCol
}

export const isInAnySelection = (
  row: number,
  col: number,
  selections: CellSelection[]
): boolean => {
  return selections.some(selection => isInSelection(row, col, selection))
}

export const normalizeSelection = (selection: CellSelection): CellSelection => {
  const { startRow, startCol, endRow, endCol } = selection
  return {
    startRow: Math.min(startRow, endRow),
    startCol: Math.min(startCol, endCol),
    endRow: Math.max(startRow, endRow),
    endCol: Math.max(startCol, endCol),
  }
}

export const getAllCellsInSelections = (
  selections: CellSelection[]
): Array<{ row: number; col: number }> => {
  const cells: Array<{ row: number; col: number }> = []

  selections.forEach(selection => {
    const normalized = normalizeSelection(selection)
    for (let row = normalized.startRow; row <= normalized.endRow; row++) {
      for (let col = normalized.startCol; col <= normalized.endCol; col++) {
        cells.push({ row, col })
      }
    }
  })

  return cells
}

export const createSelectionFromRange = (
  startRow: number,
  startCol: number,
  endRow: number,
  endCol: number
): CellSelection => {
  return {
    startRow,
    startCol,
    endRow,
    endCol,
  }
}
