import { parseHierarchy, buildFullTitle, buildHierarchyPath, type ItemType } from '@/services/hierarchy'
import type { AnalysisEpic, AnalysisHU } from '@/services/project-analyzer'
import type { EnrichedEpic, EnrichedUserStory } from '@/stores/workitems'

export interface MaxCounters {
  epicMax: number
  byEpic: Map<string, Record<string, number>>
}

const ITEM_TYPE_MAP: Record<string, ItemType> = {
  feature: 'F',
  task: 'T',
  us: 'U',
  bug: 'B',
  spike: 'S',
}

/**
 * Analiza épicas e ítems existentes para determinar el próximo número disponible
 * para cada nivel jerárquico.
 */
export function analyzeExisting(
  epics: EnrichedEpic[],
  items: EnrichedUserStory[],
): MaxCounters {
  let epicMax = 0
  const byEpic = new Map<string, Record<string, number>>()

  function updateCounter(epicCode: string, type: string, num: number) {
    if (!byEpic.has(epicCode)) byEpic.set(epicCode, {})
    const map = byEpic.get(epicCode)!
    const current = map[type] || 0
    if (num > current) map[type] = num
  }

  for (const epic of epics) {
    const h = parseHierarchy(epic._cleanName || epic.name || epic.title || '')
    if (!h) {
      // Si no tiene código jerárquico, asumimos que usa el id numérico de KAPPA
      const fakeH = parseHierarchy(buildFullTitle('', Math.max(epicMax, 1)))
      if (fakeH) {
        const code = fakeH.epicCode
        if (code) {
          const num = parseInt(code.slice(1), 10)
          if (num > epicMax) epicMax = num
        }
      }
      continue
    }
    const epicItem = h.items.find(i => i.type === 'E')
    if (epicItem) {
      const code = `E${String(epicItem.number).padStart(2, '0')}`
      if (epicItem.number > epicMax) epicMax = epicItem.number
    }
  }

  for (const item of items) {
    const h = parseHierarchy(item._cleanTitle || item.title || '')
    if (!h) continue
    const epicItem = h.items.find(i => i.type === 'E')
    if (!epicItem) continue
    const epicCode = `E${String(epicItem.number).padStart(2, '0')}`

    for (const seg of h.items) {
      if (seg.type === 'E') continue
      updateCounter(epicCode, seg.type, seg.number)
    }
  }

  return { epicMax, byEpic }
}

/**
 * Asigna códigos jerárquicos a épicas propuestas y devuelve el array
 * enriquecido con epicCode en metadata.
 */
export function assignEpicCodes(
  proposedEpics: AnalysisEpic[],
  counters: MaxCounters,
): (AnalysisEpic & { epicCode: string })[] {
  let nextEpicNum = counters.epicMax + 1

  return proposedEpics.map(epic => {
    const epicCode = `E${String(nextEpicNum).padStart(2, '0')}`
    nextEpicNum++
    return { ...epic, epicCode }
  })
}

/**
 * Asigna códigos jerárquicos a ítems propuestos dentro de épicas confirmadas.
 * Requiere que cada HU tenga epicName (nombre de la épica) y type.
 * Devuelve HUs con title y description enriquecidos con el código.
 */
export function assignItemCodes(
  proposedHUs: AnalysisHU[],
  confirmedEpics: { name: string; epicCode: string }[],
  counters: MaxCounters,
): AnalysisHU[] {
  const epicNameToCode = new Map<string, string>()
  for (const e of confirmedEpics) {
    epicNameToCode.set(e.name.toLowerCase().trim(), e.epicCode)
  }

  // Clonar counters para no mutar el original
  const localCounters = new Map<string, Record<string, number>>()
  for (const [key, val] of counters.byEpic) {
    localCounters.set(key, { ...val })
  }

  return proposedHUs.map(hu => {
    const epicName = (hu.epicName || '').toLowerCase().trim()
    const epicCode = epicNameToCode.get(epicName) || ''
    const epicNum = epicCode ? parseInt(epicCode.slice(1), 10) : 0

    const itemType = ITEM_TYPE_MAP[(hu.type || 'feature').toLowerCase()] || 'F'

    // Obtener próximo número para este tipo dentro de la épica
    const epicMap = localCounters.get(epicCode) || {}
    const nextNum = (epicMap[itemType] || 0) + 1
    if (!localCounters.has(epicCode)) localCounters.set(epicCode, {})
    localCounters.get(epicCode)![itemType] = nextNum

    // Construir título y descripción con código
    const fullTitle = buildFullTitle(hu.title, epicNum || undefined, itemType, nextNum)
    const codeTag = buildHierarchyPath(epicNum || undefined, itemType, nextNum)

    const typeLabel: Record<string, string> = {
      feature: 'Feature', task: 'Tarea', us: 'HU', bug: 'Bug', spike: 'Spike',
    }

    const huType = (hu.type || 'feature').toLowerCase()
    const descPrefix = `[Tipo: ${typeLabel[huType] || 'HU'} | Épica: ${epicCode} | Código: ${codeTag}]<br>`
    const enrichedDesc = hu.description
      ? `${descPrefix}${hu.description}`
      : descPrefix

    return {
      ...hu,
      title: fullTitle,
      description: enrichedDesc,
    }
  })
}
