import type { QuestionWithCategories, ResponseDraft } from './assessment-types'

export interface OverallStats {
  totalRelevant: number
  answered: number
  unanswered: number
  notRelevant: number
  flagged: number
  commented: number
  score: number | null
  progress: number
  ratingDistribution: { rating: number; count: number; label: string }[]
}

export interface MainCatStat {
  id: string
  code: string
  label: string
  sort_order: number
  total: number
  answered: number
  avg: number | null
  progress: number
}

export interface SubCatStat {
  id: string
  code: string
  label: string
  mainId: string
  mainCode: string
  mainLabel: string
  mainSortOrder: number
  sort_order: number
  total: number
  answered: number
  avg: number | null
  progress: number
}

const RATING_LABEL: Record<number, string> = {
  1: 'Nicht erfüllt',
  2: 'Teilweise',
  3: 'Erfüllt',
  4: 'Best Practice',
}

export function computeOverallStats(
  questions: QuestionWithCategories[],
  responses: Record<string, ResponseDraft>,
): OverallStats {
  let totalRelevant = 0, answered = 0, notRelevant = 0
  let flagged = 0, commented = 0, ratingSum = 0
  const dist: Record<number, number> = { 1: 0, 2: 0, 3: 0, 4: 0 }

  for (const q of questions) {
    const r = responses[q.id]
    if (r?.is_relevant === false) { notRelevant++; continue }
    totalRelevant++
    if (r?.selected_rating !== null && r?.selected_rating !== undefined) {
      answered++
      ratingSum += r.selected_rating
      dist[r.selected_rating] = (dist[r.selected_rating] ?? 0) + 1
    }
    if (r?.is_flagged) flagged++
    if (r?.comment?.trim()) commented++
  }

  return {
    totalRelevant,
    answered,
    unanswered: totalRelevant - answered,
    notRelevant,
    flagged,
    commented,
    score: answered > 0 ? ratingSum / answered : null,
    progress: totalRelevant > 0 ? (answered / totalRelevant) * 100 : 0,
    ratingDistribution: [1, 2, 3, 4].map((r) => ({
      rating: r,
      count: dist[r] ?? 0,
      label: RATING_LABEL[r],
    })),
  }
}

export function computeMainCategoryStats(
  questions: QuestionWithCategories[],
  responses: Record<string, ResponseDraft>,
): MainCatStat[] {
  const map = new Map<string, {
    code: string; label: string; sort_order: number
    total: number; answered: number; sum: number
  }>()

  for (const q of questions) {
    const r = responses[q.id]
    if (r?.is_relevant === false) continue
    const id = q.main_category_id
    if (!map.has(id)) {
      map.set(id, {
        code: q.main_category.code,
        label: q.main_category.label,
        sort_order: q.main_category.sort_order,
        total: 0, answered: 0, sum: 0,
      })
    }
    const m = map.get(id)!
    m.total++
    if (r?.selected_rating !== null && r?.selected_rating !== undefined) {
      m.answered++
      m.sum += r.selected_rating
    }
  }

  return [...map.entries()]
    .sort((a, b) => a[1].sort_order - b[1].sort_order)
    .map(([id, { code, label, sort_order, total, answered, sum }]) => ({
      id, code, label, sort_order, total, answered,
      avg: answered > 0 ? sum / answered : null,
      progress: total > 0 ? (answered / total) * 100 : 0,
    }))
}

export function computeSubCategoryStats(
  questions: QuestionWithCategories[],
  responses: Record<string, ResponseDraft>,
): SubCatStat[] {
  const map = new Map<string, {
    code: string; label: string
    mainId: string; mainCode: string; mainLabel: string
    mainSortOrder: number; sort_order: number
    total: number; answered: number; sum: number
  }>()

  for (const q of questions) {
    const r = responses[q.id]
    if (r?.is_relevant === false) continue
    const id = q.sub_category_id
    if (!map.has(id)) {
      map.set(id, {
        code: q.sub_category.code,
        label: q.sub_category.label,
        mainId: q.main_category_id,
        mainCode: q.main_category.code,
        mainLabel: q.main_category.label,
        mainSortOrder: q.main_category.sort_order,
        sort_order: q.sub_category.sort_order,
        total: 0, answered: 0, sum: 0,
      })
    }
    const m = map.get(id)!
    m.total++
    if (r?.selected_rating !== null && r?.selected_rating !== undefined) {
      m.answered++
      m.sum += r.selected_rating
    }
  }

  return [...map.entries()]
    .sort((a, b) =>
      a[1].mainSortOrder - b[1].mainSortOrder || a[1].sort_order - b[1].sort_order
    )
    .map(([id, { code, label, mainId, mainCode, mainLabel, mainSortOrder, sort_order, total, answered, sum }]) => ({
      id, code, label, mainId, mainCode, mainLabel, mainSortOrder, sort_order, total, answered,
      avg: answered > 0 ? sum / answered : null,
      progress: total > 0 ? (answered / total) * 100 : 0,
    }))
}
