"use client"

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

import { Lang } from "@/constants/languages"
import { membershipLevels } from "@/constants/membershipLevels"

import Image from "@/components/Image"
import Select from "@/components/TempDesignSystem/Select"
import useLang from "@/hooks/useLang"
import { getMembership } from "@/utils/user"

import DA from "./data/DA.json"
import DE from "./data/DE.json"
import EN from "./data/EN.json"
import FI from "./data/FI.json"
import NO from "./data/NO.json"
import SV from "./data/SV.json"
import BenefitList from "./BenefitList"
import LargeTable from "./LargeTable"
import LevelSummary from "./LevelSummary"
import YourLevel from "./YourLevelScript"

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

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

import {
  ComparisonLevel,
  DesktopSelectColumns,
  MobileColumnHeaderProps,
  overviewTableActionsEnum,
  OverviewTableProps,
  OverviewTableReducerAction,
} from "@/types/components/loyalty/blocks"
import type { User } from "@/types/user"

const levelsTranslations = {
  [Lang.en]: EN,
  [Lang.sv]: SV,
  [Lang.no]: NO,
  [Lang.da]: DA,
  [Lang.fi]: FI,
  [Lang.de]: DE,
}

function getTranslatedLevel(membershipLevel: membershipLevels, lang: Lang) {
  return levelsTranslations[lang].levels.find(
    (level) => level.level === membershipLevel
  ) as ComparisonLevel
}

function getInitialState({ user, lang }: { user?: User; lang: Lang }) {
  const membership = user?.memberships ? getMembership(user.memberships) : null
  if (!membership?.membershipLevel) {
    return {
      selectedLevelAMobile: getTranslatedLevel(1, lang),
      selectedLevelBMobile: getTranslatedLevel(2, lang),
      selectedLevelADesktop: getTranslatedLevel(1, lang),
      selectedLevelBDesktop: getTranslatedLevel(2, lang),
      selectedLevelCDesktop: getTranslatedLevel(3, lang),
    }
  }
  if (!membership.membershipLevel) return null
  const level = membershipLevels[membership.membershipLevel]

  switch (level) {
    case 6:
      return {
        selectedLevelAMobile: getTranslatedLevel(6, lang),
        selectedLevelBMobile: getTranslatedLevel(7, lang),
        selectedLevelADesktop: getTranslatedLevel(5, lang),
        selectedLevelBDesktop: getTranslatedLevel(6, lang),
        selectedLevelCDesktop: getTranslatedLevel(7, lang),
      }
    case 7:
      return {
        selectedLevelAMobile: getTranslatedLevel(6, lang),
        selectedLevelBMobile: getTranslatedLevel(7, lang),
        selectedLevelADesktop: getTranslatedLevel(6, lang),
        selectedLevelBDesktop: getTranslatedLevel(7, lang),
        selectedLevelCDesktop: getTranslatedLevel(1, lang),
      }
    default:
      return {
        selectedLevelAMobile: getTranslatedLevel(level, lang),
        selectedLevelBMobile: getTranslatedLevel(level + 1, lang),
        selectedLevelADesktop: getTranslatedLevel(level, lang),
        selectedLevelBDesktop: getTranslatedLevel(level + 1, lang),
        selectedLevelCDesktop: getTranslatedLevel(level + 2, lang),
      }
  }
}

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,
}: OverviewTableProps) {
  const intl = useIntl()
  const lang = useLang()
  const levelsData = levelsTranslations[lang]
  const [selectionState, dispatch] = useReducer(
    reducer,
    { activeMembership, lang },
    getInitialState
  )

  function handleSelectChange(actionType: overviewTableActionsEnum) {
    return (key: Key) => {
      if (typeof key === "number") {
        dispatch({
          payload: getTranslatedLevel(key, lang),
          type: actionType,
        })
      }
    }
  }

  const levelOptions = levelsData.levels.map((level) => ({
    label: [level.level, level.name].join(" "),
    value: level.level,
  }))

  let activeMembershipLevel: membershipLevels | null = null
  if (activeMembership?.membershipLevel) {
    activeMembershipLevel = membershipLevels[activeMembership?.membershipLevel]
  }

  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 ? (
            <YourLevel />
          ) : null}
          <Image
            src={selectedLevelMobile.icon}
            alt={selectedLevelMobile.name}
            height={50}
            width={100}
          />
        </div>
        <LevelSummary
          level={
            levelsData.levels.find(
              (level) => level.level === selectedLevelMobile.level
            ) as ComparisonLevel
          }
          showDescription={false}
        />
        <Select
          aria-label={intl.formatMessage({ id: "Level" })}
          name={`benefit` + column}
          label={intl.formatMessage({ id: "Level" })}
          items={levelOptions}
          value={selectedLevelMobile.level}
          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={`benefit` + column}
        label={intl.formatMessage({ id: "Level" })}
        items={levelOptions}
        value={selectedLevelDesktop.level}
        onSelect={handleSelectChange(actionEnumDesktop)}
      />
    )
  }
  return (
    <div>
      <div className={styles.mobileColumns}>
        <div className={styles.columnHeaderContainer}>
          <MobileColumnHeader column={"A"} />
          <MobileColumnHeader column={"B"} />
        </div>
        <BenefitList
          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}>
        {/* Remove `as` once we have real data */}
        <LargeTable
          levels={levelsData.levels as ComparisonLevel[]}
          activeLevel={activeMembershipLevel}
        />
      </div>
    </div>
  )
}
