"use client"

import { useReducer } from "react"
import { useIntl } from "react-intl"

import {
  MembershipLevel,
  MembershipLevelEnum,
} from "@/constants/membershipLevels"

import MembershipLevelIcon from "@/components/Levels/Icon"
import Select from "@/components/TempDesignSystem/Select"
import { getSteppedUpLevel } from "@/utils/user"

import LargeTable from "./LargeTable"
import LevelSummary from "./LevelSummary"
import RewardList from "./RewardList"
import YourLevel from "./YourLevelScript"

import styles from "./overviewTable.module.css"

import type { Key } from "react-aria-components"

import {
  ComparisonLevel,
  DesktopSelectColumns,
  LevelWithRewards,
  type MobileColumnHeaderProps,
  OverviewTableActionsEnum,
  type OverviewTableClientProps,
  OverviewTableReducerAction,
} from "@/types/components/overviewTable"

function getLevelNamesForSelect(level: MembershipLevel, levelName: string) {
  const levelToNumber = MembershipLevelEnum[level]
  return [levelToNumber, levelName].join(" - ")
}

function getLevel(
  membershipLevel: MembershipLevel,
  levels: LevelWithRewards[]
) {
  return levels.find((level) => level.level_id === membershipLevel)!
}

function getInitialState({
  activeMembership,
  levels,
}: OverviewTableClientProps) {
  if (!activeMembership) {
    return {
      selectedLevelAMobile: getLevel(MembershipLevelEnum.L1, levels),
      selectedLevelBMobile: getLevel(MembershipLevelEnum.L2, levels),
      selectedLevelADesktop: getLevel(MembershipLevelEnum.L1, levels),
      selectedLevelBDesktop: getLevel(MembershipLevelEnum.L2, levels),
      selectedLevelCDesktop: getLevel(MembershipLevelEnum.L3, levels),
    }
  }
  const level = MembershipLevelEnum[activeMembership]

  switch (level) {
    case MembershipLevelEnum.L6:
      return {
        selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
        selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
        selectedLevelADesktop: getLevel(MembershipLevelEnum.L5, levels),
        selectedLevelBDesktop: getLevel(MembershipLevelEnum.L6, levels),
        selectedLevelCDesktop: getLevel(MembershipLevelEnum.L7, levels),
      }
    case MembershipLevelEnum.L7:
      return {
        selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
        selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
        selectedLevelADesktop: getLevel(MembershipLevelEnum.L6, levels),
        selectedLevelBDesktop: getLevel(MembershipLevelEnum.L7, levels),
        selectedLevelCDesktop: getLevel(MembershipLevelEnum.L1, levels),
      }
    default:
      return {
        selectedLevelAMobile: getLevel(level, levels),
        selectedLevelBMobile: getLevel(getSteppedUpLevel(level, 1), levels),
        selectedLevelADesktop: getLevel(level, levels),
        selectedLevelBDesktop: getLevel(getSteppedUpLevel(level, 1), levels),
        selectedLevelCDesktop: getLevel(getSteppedUpLevel(level, 2), levels),
      }
  }
}

function reducer(state: any, action: OverviewTableReducerAction) {
  switch (action.type) {
    case OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE:
      return {
        ...state,
        selectedLevelAMobile: action.payload,
      }
    case OverviewTableActionsEnum.SET_SELECTED_LEVEL_B_MOBILE:
      return {
        ...state,
        selectedLevelBMobile: action.payload,
      }
    case OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_DESKTOP:
      return {
        ...state,
        selectedLevelADesktop: action.payload,
      }
    case OverviewTableActionsEnum.SET_SELECTED_LEVEL_B_DESKTOP:
      return {
        ...state,
        selectedLevelBDesktop: action.payload,
      }
    case OverviewTableActionsEnum.SET_SELECTED_LEVEL_C_DESKTOP:
      return {
        ...state,
        selectedLevelCDesktop: action.payload,
      }
    default:
      return state
  }
}

export default function OverviewTable({
  activeMembership,
  levels,
}: OverviewTableClientProps) {
  const intl = useIntl()

  const [selectionState, dispatch] = useReducer(
    reducer,
    { activeMembership, levels },
    getInitialState
  )

  function handleSelectChange(actionType: OverviewTableActionsEnum) {
    return (key: Key) => {
      dispatch({
        payload: getLevel(key as MembershipLevel, levels),
        type: actionType,
      })
    }
  }

  const levelOptions = levels.map((level) => ({
    label: getLevelNamesForSelect(level.level_id, level.name),
    value: level.level_id,
  }))

  const activeMembershipLevel = activeMembership ?? null

  function MobileColumnHeader({ column }: MobileColumnHeaderProps) {
    let selectedLevelMobile: ComparisonLevel
    let actionEnumMobile: OverviewTableActionsEnum
    switch (column) {
      case "A":
        selectedLevelMobile = selectionState.selectedLevelAMobile
        actionEnumMobile = OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE
        break
      case "B":
        selectedLevelMobile = selectionState.selectedLevelBMobile
        actionEnumMobile = OverviewTableActionsEnum.SET_SELECTED_LEVEL_B_MOBILE
        break
      default:
        return null
    }
    return (
      <div className={styles.columnHeader}>
        <div className={styles.icon}>
          {activeMembershipLevel === selectedLevelMobile.level_id ? (
            <YourLevel />
          ) : null}
          <MembershipLevelIcon
            level={selectedLevelMobile.level_id}
            color="red"
            height="50"
            width="100"
          />
        </div>
        <LevelSummary
          level={
            levels.find(
              (level) => level.level_id === selectedLevelMobile.level_id
            )!
          }
          showDescription={false}
        />
        <Select
          aria-label={intl.formatMessage({ id: "Level" })}
          name={`reward` + column}
          label={intl.formatMessage({ id: "Level" })}
          items={levelOptions}
          value={selectedLevelMobile.level_id}
          onSelect={handleSelectChange(actionEnumMobile)}
        />
      </div>
    )
  }

  function SelectDesktop({ column }: DesktopSelectColumns) {
    let selectedLevelDesktop: ComparisonLevel
    let actionEnumDesktop: OverviewTableActionsEnum
    switch (column) {
      case "A":
        selectedLevelDesktop = selectionState.selectedLevelADesktop
        actionEnumDesktop =
          OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_DESKTOP
        break
      case "B":
        selectedLevelDesktop = selectionState.selectedLevelBDesktop
        actionEnumDesktop =
          OverviewTableActionsEnum.SET_SELECTED_LEVEL_B_DESKTOP
        break
      case "C":
        selectedLevelDesktop = selectionState.selectedLevelCDesktop
        actionEnumDesktop =
          OverviewTableActionsEnum.SET_SELECTED_LEVEL_C_DESKTOP
        break
      default:
        return null
    }
    return (
      <Select
        aria-label={intl.formatMessage({ id: "Level" })}
        name={`reward` + column}
        label={intl.formatMessage({ id: "Level" })}
        items={levelOptions}
        value={selectedLevelDesktop.level_id}
        onSelect={handleSelectChange(actionEnumDesktop)}
      />
    )
  }
  return (
    <div>
      <div className={styles.mobileColumns}>
        <div className={styles.columnHeaderContainer}>
          <MobileColumnHeader column={"A"} />
          <MobileColumnHeader column={"B"} />
        </div>
        <RewardList
          levels={[
            selectionState.selectedLevelAMobile,
            selectionState.selectedLevelBMobile,
          ]}
        />
      </div>
      <div className={styles.columns}>
        <LargeTable
          levels={[
            selectionState.selectedLevelADesktop,
            selectionState.selectedLevelBDesktop,
            selectionState.selectedLevelCDesktop,
          ]}
          activeLevel={activeMembershipLevel}
          Select={SelectDesktop}
        />
      </div>
      <div className={styles.largeTableContainer}>
        <LargeTable levels={levels} activeLevel={activeMembershipLevel} />
      </div>
    </div>
  )
}
