import type {
  ScopeQuestionBlockId,
  ScopeProfilingQuestion,
  ScopeProfilingAnswer,
} from './compliance-scope-types'
import type { CompanyProfile } from './types'
import {
  HIDDEN_SCORING_QUESTIONS,
} from './compliance-scope-profiling-blocks'
import {
  SCOPE_QUESTION_BLOCKS,
} from './compliance-scope-profiling-vvt-blocks'

/**
 * Prefill scope answers from CompanyProfile.
 */
export function prefillFromCompanyProfile(
  profile: CompanyProfile
): ScopeProfilingAnswer[] {
  const answers: ScopeProfilingAnswer[] = []

  // dpoName -> org_has_dsb (auto-filled, not shown in UI)
  if (profile.dpoName && profile.dpoName.trim() !== '') {
    answers.push({
      questionId: 'org_has_dsb',
      value: true,
    })
  }

  // offerings -> prod_type mapping (auto-filled, not shown in UI)
  if (profile.offerings && profile.offerings.length > 0) {
    const prodTypes: string[] = []
    const offeringsLower = profile.offerings.map((o) => o.toLowerCase())

    if (offeringsLower.some((o) => o.includes('webapp') || o.includes('web'))) {
      prodTypes.push('webapp')
    }
    if (
      offeringsLower.some((o) => o.includes('mobile') || o.includes('app'))
    ) {
      prodTypes.push('mobile')
    }
    if (offeringsLower.some((o) => o.includes('saas') || o.includes('cloud'))) {
      prodTypes.push('saas')
    }
    if (
      offeringsLower.some(
        (o) => o.includes('onpremise') || o.includes('on-premise')
      )
    ) {
      prodTypes.push('onpremise')
    }
    if (offeringsLower.some((o) => o.includes('api'))) {
      prodTypes.push('api')
    }
    if (offeringsLower.some((o) => o.includes('iot') || o.includes('hardware'))) {
      prodTypes.push('iot')
    }
    if (
      offeringsLower.some(
        (o) => o.includes('beratung') || o.includes('consulting')
      )
    ) {
      prodTypes.push('beratung')
    }
    if (
      offeringsLower.some(
        (o) => o.includes('handel') || o.includes('shop') || o.includes('commerce')
      )
    ) {
      prodTypes.push('handel')
    }

    if (prodTypes.length > 0) {
      answers.push({
        questionId: 'prod_type',
        value: prodTypes,
      })
    }

    // webshop auto-fill
    if (offeringsLower.some((o) => o.includes('webshop') || o.includes('shop'))) {
      answers.push({
        questionId: 'prod_webshop',
        value: true,
      })
    }
  }

  return answers
}

/**
 * Get auto-filled scoring values for questions removed from UI.
 */
export function getAutoFilledScoringAnswers(
  profile: CompanyProfile
): ScopeProfilingAnswer[] {
  const answers: ScopeProfilingAnswer[] = []

  if (profile.employeeCount != null) {
    answers.push({ questionId: 'org_employee_count', value: profile.employeeCount })
  }
  if (profile.annualRevenue) {
    answers.push({ questionId: 'org_annual_revenue', value: profile.annualRevenue })
  }
  if (profile.industry && profile.industry.length > 0) {
    answers.push({ questionId: 'org_industry', value: profile.industry.join(', ') })
  }
  if (profile.businessModel) {
    answers.push({ questionId: 'org_business_model', value: profile.businessModel })
  }
  if (profile.dpoName && profile.dpoName.trim() !== '') {
    answers.push({ questionId: 'org_has_dsb', value: true })
  }

  return answers
}

/**
 * Get profile info summary for display in "Aus Profil" info boxes.
 */
export function getProfileInfoForBlock(
  profile: CompanyProfile,
  blockId: ScopeQuestionBlockId
): { label: string; value: string }[] {
  const items: { label: string; value: string }[] = []

  if (blockId === 'organisation') {
    if (profile.industry && profile.industry.length > 0) items.push({ label: 'Branche', value: profile.industry.join(', ') })
    if (profile.employeeCount) items.push({ label: 'Mitarbeiter', value: profile.employeeCount })
    if (profile.annualRevenue) items.push({ label: 'Umsatz', value: profile.annualRevenue })
    if (profile.businessModel) items.push({ label: 'Geschäftsmodell', value: profile.businessModel })
    if (profile.dpoName) items.push({ label: 'DSB', value: profile.dpoName })
  }

  if (blockId === 'product') {
    if (profile.offerings && profile.offerings.length > 0) {
      items.push({ label: 'Angebote', value: profile.offerings.join(', ') })
    }
    const hasWebshop = profile.offerings?.some(o => o.toLowerCase().includes('webshop') || o.toLowerCase().includes('shop'))
    if (hasWebshop) items.push({ label: 'Webshop', value: 'Ja' })
  }

  return items
}

/**
 * Prefill scope answers from VVT profiling answers
 */
export function prefillFromVVTAnswers(
  vvtAnswers: Record<string, unknown>
): ScopeProfilingAnswer[] {
  const answers: ScopeProfilingAnswer[] = []
  const reverseMap: Record<string, string> = {}
  for (const block of SCOPE_QUESTION_BLOCKS) {
    for (const q of block.questions) {
      if (q.mapsToVVTQuestion) {
        reverseMap[q.mapsToVVTQuestion] = q.id
      }
    }
  }
  for (const [vvtQuestionId, vvtValue] of Object.entries(vvtAnswers)) {
    const scopeQuestionId = reverseMap[vvtQuestionId]
    if (scopeQuestionId) {
      answers.push({ questionId: scopeQuestionId, value: vvtValue as string | number | boolean | string[] })
    }
  }
  return answers
}

/**
 * Prefill scope answers from Loeschfristen profiling answers
 */
export function prefillFromLoeschfristenAnswers(
  lfAnswers: Array<{ questionId: string; value: unknown }>
): ScopeProfilingAnswer[] {
  const answers: ScopeProfilingAnswer[] = []
  const reverseMap: Record<string, string> = {}
  for (const block of SCOPE_QUESTION_BLOCKS) {
    for (const q of block.questions) {
      if (q.mapsToLFQuestion) {
        reverseMap[q.mapsToLFQuestion] = q.id
      }
    }
  }
  for (const lfAnswer of lfAnswers) {
    const scopeQuestionId = reverseMap[lfAnswer.questionId]
    if (scopeQuestionId) {
      answers.push({ questionId: scopeQuestionId, value: lfAnswer.value as string | number | boolean | string[] })
    }
  }
  return answers
}

/**
 * Export scope answers in VVT format
 */
export function exportToVVTAnswers(
  scopeAnswers: ScopeProfilingAnswer[]
): Record<string, unknown> {
  const vvtAnswers: Record<string, unknown> = {}
  for (const answer of scopeAnswers) {
    let question: ScopeProfilingQuestion | undefined
    for (const block of SCOPE_QUESTION_BLOCKS) {
      question = block.questions.find((q) => q.id === answer.questionId)
      if (question) break
    }
    if (question?.mapsToVVTQuestion) {
      vvtAnswers[question.mapsToVVTQuestion] = answer.value
    }
  }
  return vvtAnswers
}

/**
 * Export scope answers in Loeschfristen format
 */
export function exportToLoeschfristenAnswers(
  scopeAnswers: ScopeProfilingAnswer[]
): Array<{ questionId: string; value: unknown }> {
  const lfAnswers: Array<{ questionId: string; value: unknown }> = []
  for (const answer of scopeAnswers) {
    let question: ScopeProfilingQuestion | undefined
    for (const block of SCOPE_QUESTION_BLOCKS) {
      question = block.questions.find((q) => q.id === answer.questionId)
      if (question) break
    }
    if (question?.mapsToLFQuestion) {
      lfAnswers.push({ questionId: question.mapsToLFQuestion, value: answer.value })
    }
  }
  return lfAnswers
}

/**
 * Export scope answers for TOM generator
 */
export function exportToTOMProfile(
  scopeAnswers: ScopeProfilingAnswer[]
): Record<string, unknown> {
  const tomProfile: Record<string, unknown> = {}
  const getVal = (qId: string) => getAnswerValue(scopeAnswers, qId)

  tomProfile.industry = getVal('org_industry')
  tomProfile.employeeCount = getVal('org_employee_count')
  tomProfile.hasDataMinors = getVal('data_minors')
  tomProfile.hasSpecialCategories = Array.isArray(getVal('data_art9'))
    ? (getVal('data_art9') as string[]).length > 0
    : false
  tomProfile.hasAutomatedDecisions = getVal('proc_adm_scoring')
  tomProfile.usesAI = Array.isArray(getVal('proc_ai_usage'))
    ? !(getVal('proc_ai_usage') as string[]).includes('keine')
    : false
  tomProfile.hasThirdCountryTransfer = getVal('tech_third_country')
  tomProfile.hasEncryptionRest = getVal('tech_encryption_rest')
  tomProfile.hasEncryptionTransit = getVal('tech_encryption_transit')
  tomProfile.hasIncidentResponse = getVal('proc_incident_response')
  tomProfile.hasDeletionConcept = getVal('proc_deletion_concept')
  tomProfile.hasRegularAudits = getVal('proc_regular_audits')
  tomProfile.hasTraining = getVal('proc_training')

  return tomProfile
}

/**
 * Check if a block is complete (all required questions answered)
 */
export function isBlockComplete(
  answers: ScopeProfilingAnswer[],
  blockId: ScopeQuestionBlockId
): boolean {
  const block = SCOPE_QUESTION_BLOCKS.find((b) => b.id === blockId)
  if (!block) return false
  const requiredQuestions = block.questions.filter((q) => q.required)
  const answeredQuestionIds = new Set(answers.map((a) => a.questionId))
  return requiredQuestions.every((q) => answeredQuestionIds.has(q.id))
}

/**
 * Get progress for a specific block (0-100)
 */
export function getBlockProgress(
  answers: ScopeProfilingAnswer[],
  blockId: ScopeQuestionBlockId
): number {
  const block = SCOPE_QUESTION_BLOCKS.find((b) => b.id === blockId)
  if (!block) return 0
  const requiredQuestions = block.questions.filter((q) => q.required)
  if (requiredQuestions.length === 0) return 100
  const answeredQuestionIds = new Set(answers.map((a) => a.questionId))
  const answeredCount = requiredQuestions.filter((q) =>
    answeredQuestionIds.has(q.id)
  ).length
  return Math.round((answeredCount / requiredQuestions.length) * 100)
}

/**
 * Get total progress across all blocks (0-100)
 */
export function getTotalProgress(answers: ScopeProfilingAnswer[]): number {
  let totalRequired = 0
  let totalAnswered = 0
  const answeredQuestionIds = new Set(answers.map((a) => a.questionId))
  for (const block of SCOPE_QUESTION_BLOCKS) {
    const requiredQuestions = block.questions.filter((q) => q.required)
    totalRequired += requiredQuestions.length
    totalAnswered += requiredQuestions.filter((q) =>
      answeredQuestionIds.has(q.id)
    ).length
  }
  if (totalRequired === 0) return 100
  return Math.round((totalAnswered / totalRequired) * 100)
}

/**
 * Get answer value for a specific question
 */
export function getAnswerValue(
  answers: ScopeProfilingAnswer[],
  questionId: string
): unknown {
  const answer = answers.find((a) => a.questionId === questionId)
  return answer?.value
}

/**
 * Get all questions as a flat array (including hidden auto-filled questions)
 */
export function getAllQuestions(): ScopeProfilingQuestion[] {
  return [
    ...SCOPE_QUESTION_BLOCKS.flatMap((block) => block.questions),
    ...HIDDEN_SCORING_QUESTIONS,
  ]
}

/**
 * Get unanswered required questions, optionally filtered by block.
 */
export function getUnansweredRequiredQuestions(
  answers: ScopeProfilingAnswer[],
  blockId?: ScopeQuestionBlockId
): { blockId: ScopeQuestionBlockId; blockTitle: string; question: ScopeProfilingQuestion }[] {
  const answeredIds = new Set(answers.map((a) => a.questionId))
  const blocks = blockId
    ? SCOPE_QUESTION_BLOCKS.filter((b) => b.id === blockId)
    : SCOPE_QUESTION_BLOCKS

  const result: { blockId: ScopeQuestionBlockId; blockTitle: string; question: ScopeProfilingQuestion }[] = []
  for (const block of blocks) {
    for (const q of block.questions) {
      if (q.required && !answeredIds.has(q.id)) {
        result.push({ blockId: block.id, blockTitle: block.title, question: q })
      }
    }
  }
  return result
}
