import moment from 'moment'
const allMonths = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December',
]
/**
 * Get the text to display for a chore's due date
 * @param {string|null} nextDueDate - The next due date of the chore
 * @param {Object} chore - The chore object (needed for nextDueDate null check)
 * @returns {string} The formatted due date text
 */
export const getDueDateChipText = (
  nextDueDate,
  chore,
  timeFormat = 'h:mm A',
) => {
  if (chore?.nextDueDate === null || nextDueDate === null) return 'No Due Date'

  const dueDate = moment(nextDueDate)
  const diff = moment(nextDueDate).diff(moment(), 'hours')

  const calendarFormat = {
    sameDay: `[Today] ${timeFormat}`,
    nextDay: `[Tomorrow] ${timeFormat}`,
    nextWeek: `dddd ${timeFormat}`,
    lastDay: `[Yesterday] ${timeFormat}`,
    lastWeek: `dddd ${timeFormat}`,
    sameElse: `MMM D ${timeFormat}`,
  }

  // if time is 23:59:59, treat as end-of-day (date only, no specific time)
  if (
    dueDate.hours() === 23 &&
    dueDate.minutes() === 59 &&
    dueDate.seconds() === 59
  ) {
    if (diff < 0) {
      // For overdue dates, show calendar format for recent dates (Today/Yesterday);
      // beyond that, use a calendar-day count ("2 days") instead of a weekday name,
      // since a weekday alone doesn't convey how overdue the chore is
      const absDiff = Math.abs(diff)
      if (absDiff <= 24) {
        return moment(nextDueDate).calendar(null, calendarFormat).split(' ')[0]
      }
      if (absDiff <= 48) {
        const daysAgo = moment()
          .startOf('day')
          .diff(dueDate.clone().startOf('day'), 'days')
        return `${daysAgo} day${daysAgo === 1 ? '' : 's'}`
      }
      return dueDate.fromNow()
    }
    // if due in next 48 hours, show calendar format without time (e.g., "Tomorrow")
    if (diff < 48 && diff > 0) {
      return moment(nextDueDate).calendar(null, calendarFormat).split(' ')[0]
    }
    // if due date is after 48 hours, show it in format: Due in 3 days
    return dueDate.fromNow()
  }

  // if due in next 48 hours, we should show it in this format: Tomorrow 11:00
  if (diff < 48 && diff > 0) {
    return moment(nextDueDate).calendar(null, calendarFormat)
  }
  return moment(nextDueDate).fromNow()
}

/**
 * Get the color to use for a chore's due date chip
 * @param {string|null} nextDueDate - The next due date of the chore
 * @param {Object} chore - The chore object (needed for nextDueDate null check)
 * @returns {string} The color name for the chip
 */
export const getDueDateChipColor = (nextDueDate, chore) => {
  if (chore?.nextDueDate === null || nextDueDate === null) return 'neutral'

  const diff = moment(nextDueDate).diff(moment(), 'hours')

  if (diff < 48 && diff > 0) {
    return 'warning'
  }
  if (diff < 0) {
    return 'danger'
  }

  return 'neutral'
}

export const getRecurrentChipText = chore => {
  // if chore.frequencyMetadata is type string then parse it otherwise assigned to the metadata:
  const metadata =
    typeof chore.frequencyMetadata === 'string'
      ? JSON.parse(chore.frequencyMetadata)
      : chore.frequencyMetadata

  const dayOfMonthSuffix = n => {
    if (n >= 11 && n <= 13) {
      return 'th'
    }
    switch (n % 10) {
      case 1:
        return 'st'
      case 2:
        return 'nd'
      case 3:
        return 'rd'
      default:
        return 'th'
    }
  }
  if (chore.frequencyType === 'once') {
    return 'Once'
  } else if (chore.frequencyType === 'trigger') {
    return 'Trigger'
  } else if (chore.frequencyType === 'daily') {
    return 'Daily'
  } else if (chore.frequencyType === 'adaptive') {
    return 'Adaptive'
  } else if (chore.frequencyType === 'weekly') {
    return 'Weekly'
  } else if (chore.frequencyType === 'monthly') {
    return 'Monthly'
  } else if (chore.frequencyType === 'yearly') {
    return 'Yearly'
  } else if (chore.frequencyType === 'days_of_the_week') {
    let days = metadata.days
    if (days.length > 4) {
      const allDays = [
        'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday',
      ]
      const selectedDays = days.map(d => moment().day(d).format('dddd'))
      const notSelectedDay = allDays.filter(day => !selectedDays.includes(day))
      const notSelectedShortdays = notSelectedDay.map(d =>
        moment().day(d).format('ddd'),
      )
      return `Daily except ${notSelectedShortdays.join(', ')}`
    } else {
      days = days.map(d => moment().day(d).format('ddd'))
      return days.join(', ')
    }
  } else if (chore.frequencyType === 'day_of_the_month') {
    let months = metadata?.months ? metadata.months : allMonths
    if (months.length > 6) {
      const selectedMonths = months.map(m => moment().month(m).format('MMMM'))
      const notSelectedMonth = allMonths.filter(
        month => !selectedMonths.includes(month),
      )
      const notSelectedShortMonths = notSelectedMonth.map(m =>
        moment().month(m).format('MMM'),
      )
      let result = `Monthly ${chore.frequency}${dayOfMonthSuffix(
        chore.frequency,
      )}`
      if (notSelectedShortMonths.length > 0)
        result += `
        except ${notSelectedShortMonths.join(', ')}`
      return result
    } else {
      let freqData = metadata
      const months = [...freqData.months]
        .sort((a, b) => allMonths.indexOf(a) - allMonths.indexOf(b))
        .map(m => moment().month(m).format('MMM'))
      return `${chore.frequency}${dayOfMonthSuffix(
        chore.frequency,
      )} of ${months.join(', ')}`
    }
  } else if (chore.frequencyType === 'interval') {
    return `Every ${chore.frequency} ${metadata.unit}`
  } else {
    return chore.frequencyType
  }
}
