import React, { useEffect, useState } from 'react';
import * as DataTable from 'app/shared/modules/tables/dataTable/dataTable';
import dataTableHelper, { columnWidth } from 'app/shared/modules/tables/dataTable/dataTable.helper';
import { useSelector, useDispatch } from 'react-redux';
import * as Text from 'app/shared/components/text/text';
import { CellDataType, CellValueType } from 'app/shared/modules/tables/dataTable/dataTable.types';
import { VesselEarnings } from '../store/earnings.types';
import { selectActivePoolId, selectEarnings, selectFilteredAverage, selectPoolAverage } from '../store/earnings.selectors';
import { ROUTER, VesselDetailsEarningsRoute } from 'app/common/routes';
import { history } from 'app/common/store';
import { Sticky } from 'app/shared/components/sticky/sticky';
import { COLUMN_NAMES } from '../configs/earningsTable.config';
import { UI } from 'app/shared/store/ui/ui.constants';
import { persistEarningsPageScroll } from '../store/earnings.actions';

const FIXED_HEADERS_HEIGHT = 206;

const headers = [
  { text: 'SPECS', width: 40.5 },
  { text: 'EARNINGS ($/DAY)', width: 56 },
];

const EarningsTable = () => {
  const vesselsEarnings = useSelector(selectEarnings);
  const poolAverage = useSelector(selectPoolAverage);
  const filteredAverage = useSelector(selectFilteredAverage);
  const pool = useSelector(selectActivePoolId);

  const navigateToVesselDetails = (vesselCode: string, partnerAxCode: string) => {
    history.push(ROUTER.generate(VesselDetailsEarningsRoute, { pool, vesselCode, partnerAxCode }));
  };

  const [ orderedData, setData ] = useState(vesselsEarnings);
  const [ orderMetadata, setOrderMetadata ] = useState({
    columnName: 'Name',
    valueExtractor: (item: VesselEarnings): CellValueType => item.name,
    dataType: 'text' as CellDataType,
    isOrderAscending: true,
  });

  useEffect(() => {
    const sortedData = dataTableHelper
      .reorderData(
        vesselsEarnings, 
        orderMetadata.valueExtractor, 
        orderMetadata.dataType, 
        orderMetadata.isOrderAscending);
    setData([ ...sortedData ]);
  }, [ vesselsEarnings?.length, orderMetadata ]);

  const nameColumnWidth = 12;
  const defaultColumnWidth = (100 - nameColumnWidth) / 9;

  const getHeaderProps = (columnName: string, alignment: 'left' | 'right', width?: number, description?: string) => ({
    text: columnName,
    align: alignment,
    description: description,
    defaultColumnWidth: defaultColumnWidth,
    width: width,
  });

  const getSortingProps = (
    columnName: string, 
    dataType: CellDataType, 
    valueExtractor: (item: VesselEarnings) => CellValueType) => ({
    isColumnSorted: orderMetadata.columnName === columnName,
    isAscendingOrder: orderMetadata.isOrderAscending,
    onClick: () => {
      setOrderMetadata({ columnName, valueExtractor, dataType, isOrderAscending: !orderMetadata.isOrderAscending });
    },
  });

  const getCellProps = <T, >(propsData: { value: T, alignment: 'left' | 'right', width?: number, invertValueMarking?: boolean }) => {
    const { value, alignment, width, invertValueMarking } = propsData;
    return {
      defaultColumnWidth,
      invertValueMarking,
      width: width,
      value: value,
      align: alignment,
    };
  };

  const dispatch = useDispatch();
  return (
    <DataTable.ScrollableContainer>
      <DataTable.ColumnsHeader headers={headers} />
      <Sticky sitckyDisplacement={FIXED_HEADERS_HEIGHT} minimalScreenWidth={UI.BREAK_POINTS.XL}>
        <DataTable.HeaderRow>
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.NAME, 'left', nameColumnWidth)}
            {...getSortingProps(COLUMN_NAMES.NAME, 'text', item => item.name)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.SCRUBBER, 'right')}
            {...getSortingProps(COLUMN_NAMES.SCRUBBER, 'boolean', item => item.hasScrubber)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.POOL_POINTS, 'right')}
            {...getSortingProps(COLUMN_NAMES.POOL_POINTS, 'number', item => item.poolPoints)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.BUNKER_ADJUSTMENT, 'right', undefined, 'Vessel per day bunker adjustment performance compared to virtual pool vessel performance.')}
            {...getSortingProps(COLUMN_NAMES.BUNKER_ADJUSTMENT, 'number', item => item.bunkerAdjustmentPerDay)}
            subtext="MT/DAY" />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.EARNINGS, 'right', undefined, 'The pool point allocated earnings for the period excluding all special adjustments and deductions.')}
            {...getSortingProps(COLUMN_NAMES.EARNINGS, 'number', item => item.earnings)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.BUNKER_ADJUSTMENT, 'right', undefined, 'MT/day multiplied by bunker basket price.')}
            {...getSortingProps(COLUMN_NAMES.BUNKER_ADJUSTMENT, 'number', item => item.bunkerAdjustment)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.SCRUBBER_BONUS, 'right', undefined, 'Scrubber bonus based on difference between compliant and scrubber bunker basket. Paid to vessels with active scrubber onboard.')}
            {...getSortingProps(COLUMN_NAMES.SCRUBBER_BONUS, 'number', item => item.scrubberBonus)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.WAF_DTA_CBP, 'right', undefined, 'Cargo Based Premium and compensation for trading in West Africa and other Difficult Trading Areas. Latest list available under Documents: “Difficult Trading Areas”.')}
            {...getSortingProps(COLUMN_NAMES.WAF_DTA_CBP, 'number', item => item.wafDta)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.SPECIAL_COMPENSATION, 'right', undefined, 'Previous period Bunker Adjustment. Pilot Exceptions and Lakes compensations.')}
            {...getSortingProps(COLUMN_NAMES.SPECIAL_COMPENSATION, 'number', item => item.specialCompensations)} />
          <DataTable.HeaderRowColumn
            {...getHeaderProps(COLUMN_NAMES.TCE, 'right')}
            {...getSortingProps(COLUMN_NAMES.TCE, 'number', item => item.tce)} />
        </DataTable.HeaderRow>
        { poolAverage &&
        <DataTable.DataRow extraClass="c-earnings-table__pool-row c-earnings-table__bold-row">
          <div className="u-display--flex u-flex-column o-gutter-left--small o-gutter-right--small" style={columnWidth(nameColumnWidth)}>
            {poolAverage.names?.map((poolName, index) => (
              <DataTable.Cells.TextCell {...getCellProps({ value: poolName, alignment: 'left', width: 100 })} key={'pool'+index} extraClass="o-gutter--none c-earnings-table__bold-cell" />
            ))}

            <Text.Caption extraClass={'u-margin--none'}><span className="u-color--primary">AVERAGE</span></Text.Caption>
          </div>
          <DataTable.Cells.TextCell {...getCellProps({ value: '-', alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.poolPoints, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.bunkerAdjustmentPerDay, alignment: 'right', invertValueMarking: true })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.earnings, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.bunkerAdjustment, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.scrubberBonus, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.wafDta, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.specialCompensations, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: poolAverage.tce, alignment: 'right' })} />
        </DataTable.DataRow>
        }

        { filteredAverage &&
          <DataTable.DataRow extraClass="c-earnings-table__bold-row">
            <div className="u-display--flex u-flex-column o-gutter-left--small o-gutter-right--small" style={columnWidth(nameColumnWidth)}>
              {filteredAverage.names?.map((poolName, index) => (
                <DataTable.Cells.TextCell
                  {...getCellProps({ value: poolName, alignment: 'left', width: 100 })}
                  key={'pool'+index}
                  extraClass="o-gutter--none c-earnings-table__bold-cell" />
              ))}

              <Text.Caption extraClass={'u-margin--none'}>AVERAGE</Text.Caption>
            </div>
            <DataTable.Cells.TextCell {...getCellProps({ value: '-', alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.poolPoints, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.bunkerAdjustmentPerDay, alignment: 'right', invertValueMarking: true })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.earnings, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.bunkerAdjustment, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.scrubberBonus, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.wafDta, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.specialCompensations, alignment: 'right' })} />
            <DataTable.Cells.NumberCell {...getCellProps({ value: filteredAverage.tce, alignment: 'right' })} />
          </DataTable.DataRow>
        }

      </Sticky>
      { orderedData?.map((item) => (
        <DataTable.DataRow key={item.id} onClick={() => {
          dispatch(persistEarningsPageScroll(window.scrollY));
          navigateToVesselDetails(item.vesselCode, item.partner.abbr);
        }} clickable>
          <div className="u-display--flex u-flex-column o-gutter-left--small o-gutter-right--small" style={columnWidth(nameColumnWidth)}>
            <DataTable.Cells.TextCell {...getCellProps({ value: item.name, alignment: 'left', width: 100 })} extraClass="o-gutter--none" />
            <Text.Caption extraClass={'u-margin--none'}>
              <span className="u-color--dark-grey">{item.partner.abbr}</span>
            </Text.Caption>
          </div>
          <DataTable.Cells.BoolCell {...getCellProps({ value: item.hasScrubber, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.poolPoints, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.bunkerAdjustmentPerDay, alignment: 'right', invertValueMarking: true })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.earnings, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.bunkerAdjustment, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.scrubberBonus, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.wafDta, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.specialCompensations, alignment: 'right' })} />
          <DataTable.Cells.NumberCell {...getCellProps({ value: item.tce, alignment: 'right' })} />
        </DataTable.DataRow>
      ))
      }
    </DataTable.ScrollableContainer>
  );
};

export { EarningsTable };
