import {
  EligibleForReturn,
  EligibleForReturnState,
  ReturnProcess,
  ReturnProcessQuestion,
  ReturnProcessQuestionKey,
} from '../../models';
import {
  ItemConditionAnswer,
  ReturnReasonAnswer,
  YesNoAnswer,
} from '../../questions';
import {
  parseISO,
  differenceInCalendarDays,
  differenceInCalendarMonths,
} from 'date-fns';

// #4978
export const isTolinoEligibleForReturn = (
  returnProcess: ReturnProcess,
  questions: ReturnProcessQuestion[],
): EligibleForReturn | undefined => {
  const answers = returnProcess.answers;
  const date = returnProcess.receiptDate;

  // Check if question exists before evaluating its answer
  if (questions.find((q) => q.key === ReturnProcessQuestionKey.ItemCondition)) {
    const itemCondition = answers[ReturnProcessQuestionKey.ItemCondition];

    const receiptOlderThan100Days = date
      ? differenceInCalendarDays(new Date(), parseISO(date)) >= 100
      : undefined;

    if (itemCondition === ItemConditionAnswer.OVP && receiptOlderThan100Days) {
      return {
        state: EligibleForReturnState.NotEligible,
        reason: 'Keine Retoure möglich',
      };
    }
  }

  // Check if question exists before evaluating its answer
  if (questions.find((q) => q.key === ReturnProcessQuestionKey.ItemDamaged)) {
    const itemDamaged = answers[ReturnProcessQuestionKey.ItemDamaged];

    if (itemDamaged === ReturnReasonAnswer.DamagedByCustomer) {
      return {
        state: EligibleForReturnState.NotEligible,
        reason: 'Keine Retoure möglich',
      };
    }

    // #5286 Anpassung des Tolino-Rückgabeflows (+ siehe Kommentare)
    const displayDamaged =
      answers[ReturnProcessQuestionKey.DisplayDamaged] === YesNoAnswer.Yes;
    const receivedDamaged = itemDamaged === ReturnReasonAnswer.ReceivedDamaged;
    const receiptOlderThan6Months = date
      ? differenceInCalendarMonths(new Date(), parseISO(date)) >= 6
      : undefined;
    const receiptOlderThan24Months = date
      ? differenceInCalendarMonths(new Date(), parseISO(date)) >= 24
      : undefined;

    const isEligible =
      receiptOlderThan6Months &&
      !receiptOlderThan24Months &&
      receivedDamaged &&
      !displayDamaged;

    if (!isEligible) {
      return {
        state: EligibleForReturnState.NotEligible,
        reason: 'Keine Retoure möglich',
      };
    }
  }

  return { state: EligibleForReturnState.Eligible };
};

// #4978
export const isElektronischeGeraeteEligibleForReturn = (
  returnProcess: ReturnProcess,
  questions: ReturnProcessQuestion[],
): EligibleForReturn | undefined => {
  const answers = returnProcess.answers;
  const date = returnProcess.receiptDate;

  // Check if question exists before evaluating its answer
  if (questions.find((q) => q.key === ReturnProcessQuestionKey.ItemCondition)) {
    const itemCondition = answers[ReturnProcessQuestionKey.ItemCondition];

    const receiptOlderThan100Days = date
      ? differenceInCalendarDays(new Date(), parseISO(date)) >= 100
      : undefined;

    if (itemCondition === ItemConditionAnswer.OVP && receiptOlderThan100Days) {
      return {
        state: EligibleForReturnState.NotEligible,
        reason: 'Keine Retoure möglich',
      };
    }
  }
  return { state: EligibleForReturnState.Eligible };
};

// #4978
export const isTonDatentraegerEligibleForReturn = (
  returnProcess: ReturnProcess,
  questions: ReturnProcessQuestion[],
): EligibleForReturn | undefined => {
  const answers = returnProcess.answers;

  // Check if questions exist before evaluating their answers
  if (
    questions.find((q) => q.key === ReturnProcessQuestionKey.ItemCondition) &&
    questions.find((q) => q.key === ReturnProcessQuestionKey.ItemDefective)
  ) {
    const itemCondition = answers[ReturnProcessQuestionKey.ItemCondition];
    const itemDefective = answers[ReturnProcessQuestionKey.ItemDefective];
    if (
      itemCondition === ItemConditionAnswer.Damaged &&
      itemDefective === YesNoAnswer.No
    ) {
      return {
        state: EligibleForReturnState.NotEligible,
        reason: 'Keine Retoure möglich',
      };
    }
  }

  return { state: EligibleForReturnState.Eligible };
};
