import { titleLengthMinimumForCondition } from '@/lib/gekanator'

import type {
    GekanatorAnswerLog,
    GekanatorAnswerValue,
    GekanatorQuestion,
} from '@/lib/gekanator'


export const monthForCondition = (
    condition:  GekanatorQuestion['condition']): number | null => {
  if (condition.type === 'original-month')
    return condition.month

  if (condition.type !== 'original-month-day')
    return null

  const month = Number (condition.monthDay.split ('-')[0])
  return Number.isInteger (month) ? month : null
}


const isTitleLengthContradiction = (
    candidate:  GekanatorQuestion['condition'],
    previous:   GekanatorQuestion['condition'],
    answer:     GekanatorAnswerValue): boolean => {
  const candidateLength = titleLengthMinimumForCondition (candidate)
  const previousLength = titleLengthMinimumForCondition (previous)
  if (candidateLength === null || previousLength === null)
    return false

  switch (answer)
  {
  case 'yes':
    return candidateLength <= previousLength
  case 'no':
    return candidateLength >= previousLength
  default:
    return false
  }
}


const isQuestionRedundantAfterAnswers = (
    question:  GekanatorQuestion,
    answers:   GekanatorAnswerLog[]): boolean => answers.some (answer => {
  const previous = answer.questionCondition
  return previous !== undefined
      && isTitleLengthContradiction (question.condition, previous, answer.answer)
})


const isSourceFactBlocked = (
    candidate:  GekanatorQuestion['condition'],
    previous:   GekanatorQuestion['condition'],
    answer:     GekanatorAnswerValue): boolean => {
  if (candidate.type !== 'source' || previous.type !== 'source')
    return false

  switch (answer)
  {
  case 'yes':
    return true
  case 'no':
    return candidate.host === previous.host
  default:
    return false
  }
}


const isOriginalYearFactBlocked = (
    candidate:  GekanatorQuestion['condition'],
    previous:   GekanatorQuestion['condition'],
    answer:     GekanatorAnswerValue): boolean => {
  if (candidate.type !== 'original-year' || previous.type !== 'original-year')
    return false

  switch (answer)
  {
  case 'yes':
    return true
  case 'no':
    return candidate.year === previous.year
  default:
    return false
  }
}


const isOriginalMonthFactBlocked = (
    candidate:  GekanatorQuestion['condition'],
    previous:   GekanatorQuestion['condition'],
    answer:     GekanatorAnswerValue): boolean => {
  switch (answer)
  {
  case 'yes':
    if (previous.type === 'original-month')
      {
	if (candidate.type === 'original-month')
	  return true

	if (candidate.type === 'original-month-day')
	  return monthForCondition (candidate) !== previous.month

	return false
      }

    if (previous.type === 'original-month-day')
      return candidate.type === 'original-month'
	  || candidate.type === 'original-month-day'

    return false
  case 'no':
    if (previous.type === 'original-month')
      {
	if (candidate.type === 'original-month')
	  return candidate.month === previous.month

	if (candidate.type === 'original-month-day')
	  return monthForCondition (candidate) === previous.month

	return false
      }

    if (previous.type === 'original-month-day')
      return candidate.type === 'original-month-day'
	  && candidate.monthDay === previous.monthDay

    return false
  default:
    return false
  }
}


const isFactQuestionBlocked = (
    candidate:  GekanatorQuestion['condition'],
    previous:   GekanatorQuestion['condition'],
    answer:     GekanatorAnswerValue): boolean => {
  if (!(answer === 'yes' || answer === 'no'))
    return false

  return isSourceFactBlocked (candidate, previous, answer)
      || isOriginalYearFactBlocked (candidate, previous, answer)
      || isOriginalMonthFactBlocked (candidate, previous, answer)
}


export const isQuestionHardFilteredAfterAnswers = (
    question:  GekanatorQuestion,
    answers:   GekanatorAnswerLog[]): boolean => answers.some (answer => {
  const previous = answer.questionCondition
  if (previous === undefined)
    return false

  return isQuestionRedundantAfterAnswers (question, [answer])
      || isFactQuestionBlocked (question.condition, previous, answer.answer)
})
