import React, { Ref, useMemo } from 'react';
import { Spreadsheet, SpreadsheetRef } from 'media-plan-v2/components';
import { Id } from 'backend-api/models';
import { useDispatch, useSelector } from 'react-redux';
import { setSpreadsheetValidationModel } from 'media-plan-v2/actions';
import {
  useCampaignStatuses,
  useGenders,
  useGoals,
  usePerformanceObjectives,
  useProjectCurrencyCode,
  useTaxonomy,
  useTerritories,
} from 'hooks';
import { getEmptyColumnConfig, getColumnsValidationConfig, getInitialConfig } from './transducers';
import {
  approvalRequestsLoadingStateSelector,
  mediaPlanModeSelector,
  mediaPlanSelector,
} from 'media-plan-v2/selectors';
import { useMediaPlanAccessMode } from 'media-plan-v2/hooks';
import { dateFormatSelector } from 'common/selectors';
import { LoadingState } from 'common/types';

interface Props {
  projectId: Id;
  mediaPlanId?: Id;
  fetchMediaPlan(mediaPlanId: number): void;
  className?: string;
  isLoading: boolean;
}

export const SpreadsheetContainer = React.memo(
  React.forwardRef(
    ({ projectId, fetchMediaPlan, mediaPlanId, isLoading, className }: Props, ref: Ref<SpreadsheetRef>) => {
      const dispatch = useDispatch();

      const performanceObjectives = usePerformanceObjectives();
      const currencyCode = useProjectCurrencyCode() || 'USD'; // HOTFIX: BE bug
      const goals = useGoals();
      const taxonomy = useTaxonomy();
      const genders = useGenders();
      const countries = useTerritories();
      const mediaPlanMode = useSelector(mediaPlanModeSelector);
      const accessMode = useMediaPlanAccessMode(projectId, mediaPlanMode);
      const dateFormat = useSelector(dateFormatSelector);
      const statuses = useCampaignStatuses();

      const { loading: loadingState } = useSelector(mediaPlanSelector);
      const approvalRequestsLoading = useSelector(approvalRequestsLoadingStateSelector);

      const columnsDefinitions = useMemo(() => {
        if (!performanceObjectives || !currencyCode || !goals || !taxonomy || !genders || !countries || !statuses)
          return undefined;

        if (loadingState !== LoadingState.Finished) {
          return getEmptyColumnConfig();
        }

        dispatch(
          setSpreadsheetValidationModel(
            getColumnsValidationConfig({
              performanceObjectives,
              currencyCode,
              goals,
              taxonomy,
              genders,
              countries,
              dateFormat,
              statuses,
              projectId,
            })
          )
        );

        return getInitialConfig({
          performanceObjectives,
          currencyCode,
          goals,
          taxonomy,
          genders,
          countries,
          dateFormat,
          statuses,
          projectId,
        });
      }, [
        performanceObjectives,
        currencyCode,
        goals,
        taxonomy,
        genders,
        countries,
        statuses,
        loadingState,
        dispatch,
        dateFormat,
        projectId,
      ]);

      return (
        <div className={className}>
          <Spreadsheet
            ref={ref}
            projectId={projectId}
            onRefresh={fetchMediaPlan}
            mediaPlanId={mediaPlanId || -1}
            columnsDefinitions={columnsDefinitions}
            accessMode={accessMode}
            mediaPlanMode={mediaPlanMode}
            taxonomy={taxonomy}
            isLoading={isLoading}
            hasError={loadingState === LoadingState.Failed || approvalRequestsLoading === LoadingState.Failed}
            currencyCode={currencyCode}
          />
        </div>
      );
    }
  )
);
