"use client"

import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  type SortingState,
  useReactTable,
} from "@tanstack/react-table"
import { cx } from "class-variance-authority"
import { useState } from "react"
import { useIntl } from "react-intl"

import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Table from "@scandic-hotels/design-system/Table"
import { TextLink } from "@scandic-hotels/design-system/TextLink"
import { Typography } from "@scandic-hotels/design-system/Typography"

import { OfferPrice } from "./OfferPrice"
import {
  formatPoints,
  hasActiveCampaign,
  type HotelData,
  nameToSort,
} from "./util"

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

interface RewardNightsTableProps {
  hotelData: HotelData[]
}
export function RewardNightsTable({ hotelData }: RewardNightsTableProps) {
  const intl = useIntl()

  const [sorting, setSorting] = useState<SortingState>([
    { id: "destination", desc: false },
  ])

  const columnHelper = createColumnHelper<HotelData>()
  const columns = [
    columnHelper.accessor("name", {
      header: intl.formatMessage({
        id: "rewardNights.table.hotel",
        defaultMessage: "Hotel",
      }),
      sortingFn: (a, b) =>
        nameToSort(a.original.name).localeCompare(nameToSort(b.original.name)),
      cell: ({ row }) => (
        <TextLink href={row.original.url}>{row.original.name}</TextLink>
      ),
    }),

    columnHelper.accessor((row) => `${row.city}, ${row.country}`, {
      id: "destination",
      header: intl.formatMessage({
        id: "rewardNights.table.destination",
        defaultMessage: "Destination",
      }),
      sortingFn: (a, b) => a.original.city.localeCompare(b.original.city),
      cell: ({ row }) => {
        const hotel = row.original
        const hasCampaign = hasActiveCampaign(hotel.rewardNight.campaign)

        return (
          <>
            {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
            {hotel.city}, {hotel.country}
            {hasCampaign ? (
              <OfferPrice {...hotel.rewardNight.campaign} />
            ) : null}
          </>
        )
      },
    }),

    columnHelper.accessor((row) => row.rewardNight.points, {
      id: "points",
      header: intl.formatMessage({
        id: "common.points",
        defaultMessage: "Points",
      }),
      sortingFn: (a, b) =>
        a.original.rewardNight.points - b.original.rewardNight.points,
      cell: ({ row }) => {
        const hotel = row.original
        const hasCampaign = hasActiveCampaign(hotel.rewardNight.campaign)

        return (
          <div className={cx({ [styles.grid]: hasCampaign })}>
            {formatPoints(hotel.rewardNight.points)}

            {hasCampaign ? (
              <Typography
                variant="Body/Paragraph/mdBold"
                className={styles.highlightedText}
              >
                <span>{formatPoints(hotel.rewardNight.campaign.points)}</span>
              </Typography>
            ) : null}
          </div>
        )
      },
    }),
  ]

  const table = useReactTable({
    data: hotelData,
    columns,
    state: { sorting },
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    enableSortingRemoval: false,
  })

  return (
    <Table intent="striped" variant="content" style={{ textWrap: "balance" }}>
      <Table.THead>
        {table.getHeaderGroups().map((headerGroup) => (
          <Table.TR key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <Table.TH
                key={header.id}
                onClick={header.column.getToggleSortingHandler()}
                style={{
                  ...(header.column.getIsSorted() && {
                    color: "var(--Text-Interactive-Secondary)",
                  }),
                  cursor: "pointer",
                  whiteSpace: "nowrap",
                  minWidth: "max-content",
                }}
              >
                {flexRender(
                  header.column.columnDef.header,
                  header.getContext()
                )}
                <MaterialIcon
                  icon="keyboard_arrow_up"
                  color="CurrentColor"
                  className={cx(styles.icon, {
                    [styles.isTransformed]:
                      header.column.getIsSorted() === "desc",
                  })}
                />
              </Table.TH>
            ))}
          </Table.TR>
        ))}
      </Table.THead>

      <Table.TBody>
        {table.getRowModel().rows.map((row) => (
          <Table.TR key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <Table.TD key={cell.id} style={{ alignContent: "flex-start" }}>
                {flexRender(cell.column.columnDef.cell, cell.getContext())}
              </Table.TD>
            ))}
          </Table.TR>
        ))}
      </Table.TBody>
    </Table>
  )
}
