import * as R from 'ramda'
import React, { memo, useState } from 'react'
import {
  overridesDefaults,
  getCommissions,
  getListCommissionsSchema,
  commissionsList,
} from 'src/pages/Commissions/helper'

import { Table as EditableTable } from 'src/components/editableTable'
import { Select } from 'src/components/inputs'

const SHOW_ALL = {
  code: 'SHOW_ALL',
  display: 'Show all',
}

const ORDER_OPTIONS = [
  {
    code: 'machine',
    display: 'Machine name',
  },
  {
    code: 'cryptoCurrencies',
    display: 'Cryptocurrency',
  },
  {
    code: 'cashIn',
    display: 'Cash-in',
  },
  {
    code: 'cashOut',
    display: 'Cash-out',
  },
  {
    code: 'fixedFee',
    display: 'Fixed fee',
  },
  {
    code: 'minimumTx',
    display: 'Minimum Tx',
  },
]

const getElement = (code, display) => ({
  code: code,
  display: display || code,
})

const sortCommissionsBy = prop => {
  switch (prop) {
    case ORDER_OPTIONS[0]:
      return R.sortBy(R.find(R.propEq('code', R.prop('machine'))))
    case ORDER_OPTIONS[1]:
      return R.sortBy(R.path(['cryptoCurrencies', 0]))
    default:
      return R.sortBy(R.prop(prop.code))
  }
}

const filterCommissions = (coinFilter, machineFilter) =>
  R.compose(
    R.filter(
      it => (machineFilter === SHOW_ALL) | (machineFilter.code === it.machine),
    ),
    R.filter(
      it =>
        (coinFilter === SHOW_ALL) |
        (coinFilter.code === it.cryptoCurrencies[0]),
    ),
  )

const CommissionsList = memo(
  ({ config, localeConfig, currency, data, error, saveOverrides }) => {
    const [machineFilter, setMachineFilter] = useState(SHOW_ALL)
    const [coinFilter, setCoinFilter] = useState(SHOW_ALL)
    const [orderProp, setOrderProp] = useState(ORDER_OPTIONS[0])

    const coins = R.prop('cryptoCurrencies', localeConfig) ?? []

    const getMachineCoins = deviceId => {
      const override = R.prop('overrides', localeConfig)?.find(
        R.propEq('machine', deviceId),
      )

      const machineCoins = override
        ? R.prop('cryptoCurrencies', override)
        : coins

      return R.xprod([deviceId], machineCoins)
    }

    const getMachineElement = it =>
      getElement(R.prop('deviceId', it), R.prop('name', it))

    const cryptoData = R.map(getElement)(coins)

    const machineData = R.sortBy(
      R.prop('display'),
      R.map(getMachineElement)(R.prop('machines', data)),
    )

    const machinesCoinsTuples = R.unnest(
      R.map(getMachineCoins)(machineData.map(R.prop('code'))),
    )

    const commissions = R.map(([deviceId, cryptoCode]) =>
      getCommissions(cryptoCode, deviceId, config),
    )(machinesCoinsTuples)

    const tableData = R.compose(
      sortCommissionsBy(orderProp),
      filterCommissions(coinFilter, machineFilter),
    )(commissions)

    return (
      <div>
        <div className="flex mb-6">
          <Select
            className="mr-5"
            onSelectedItemChange={setMachineFilter}
            label="Machines"
            default={SHOW_ALL}
            items={[SHOW_ALL].concat(machineData)}
            selectedItem={machineFilter}
          />
          <Select
            className="mr-5"
            onSelectedItemChange={setCoinFilter}
            label="Cryptocurrency"
            default={SHOW_ALL}
            items={[SHOW_ALL].concat(cryptoData)}
            selectedItem={coinFilter}
          />
          <Select
            onSelectedItemChange={setOrderProp}
            label="Sort by"
            default={ORDER_OPTIONS[0]}
            items={ORDER_OPTIONS}
            selectedItem={orderProp}
            defaultAsFilter
          />
        </div>
        <div className="flex-1 w-full max-h-[70vh] overflow-y-auto">
          <EditableTable
            error={error?.message}
            name="comissionsList"
            enableEdit
            save={saveOverrides}
            initialValues={overridesDefaults}
            validationSchema={getListCommissionsSchema(localeConfig)}
            data={tableData}
            elements={commissionsList(data, currency)}
            orderedBy={orderProp}
          />
        </div>
      </div>
    )
  },
)

export default CommissionsList
