import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { Add } from '@mui/icons-material';

import { SUPPLY_TAG_PAGE_PRICE_MODEL, SUPPLY_TAG_PRICING_TYPE } from '@/modules/marketplace/account/constants';

import * as selectors from '../../redux/selectors';
import * as actions from '../../redux/slices';
import useLocalPagination from '@/modules/marketplace/account/helpers/useLocalPagination';
import { parseNumberWithRound } from '@/modules/marketplace/common/helpers';

import { Form, FormContent, FormGroupTitle, FormRow, FormSection } from '@/modules/@common/Form';
import PricingFormLineItem from '../DemandSettings/components/PricingTab/components/FormLineItem';
import PricingLineItem from '../DemandSettings/components/PricingTab/components/LineItem';
import BaseSettings from './components/BaseSettingsForm';
import FormLineItem from './components/FormLineItem';
import LineItem from './components/LineItem';
import { Button, Divider, Stack, TablePagination } from '@/mui/components';

function SupplyTagSettings(props) {
  const dispatch = useDispatch();

  const pageConfig = useSelector(selectors.pageConfigSelector);

  const supply = useSelector(selectors.supplySelector);
  const { pricing, expenses } = supply;

  const { isCreatingNew, isDuplicate } = pageConfig ?? {};
  const [showNewForm, toggleNewFrom] = useState(false);
  const [showNewExpensesForm, toggleNewExpensesForm] = useState(false);
  const pagination = useLocalPagination(25, 1);
  const paginationExpenses = useLocalPagination(25, 1);

  const onAddNewPrice = (key, data) => {
    const state = supply[key];
    if (isCreatingNew || isDuplicate) {
      dispatch(
        actions.setSupplyTabAction({
          [key]: [
            {
              id: `${state.length}`,
              ...data,
            },
            ...state,
          ],
        }),
      );
    } else {
      // update with server
      dispatch(
        actions.updateSupplyTagAction({
          data: {
            ...data,
          },
          key,
        }),
      );
    }
  };

  const onEditPrice = (key, data) => {
    dispatch(
      actions.setSupplyTabAction({
        [key]: supply[key]?.map((i) => (i.id === data.id ? { ...data } : i)),
      }),
    );
  };

  const onDeletePrice = (key, id) => {
    dispatch(
      actions.setSupplyTabAction({
        [key]: supply[key]?.filter((i) => i.id !== id),
      }),
    );
  };

  useEffect(() => {
    if (isCreatingNew) {
      // All new tags should be created with an open line of Expenses set to 0% - and available for edit
      onAddNewPrice(SUPPLY_TAG_PRICING_TYPE.expenses, {
        value: 0,
        startDate: new Date().getTime(),
        endDate: null,
        status: 'active',
      });
    }
  }, [isCreatingNew]);

  return (
    <Form>
      <FormContent>
        <FormSection>
          <FormGroupTitle>Basic Setting</FormGroupTitle>
          <BaseSettings isAdminMP={props.isAdminMP} />
          <Divider flexItem />
          {props.isAdminMP && (
            <>
              <FormRow label="Line Items" fullWidth justifyContent="flex-end">
                {!!pricing.length && !isDuplicate && (
                  <Button
                    size="small"
                    data-id="add-new-line-item"
                    startIcon={<Add />}
                    onClick={() => {
                      pagination.setCurrentPage(1);
                      toggleNewFrom(true);
                    }}
                    disabled={showNewForm || (isCreatingNew && pricing.length === 1)}
                  >
                    New
                  </Button>
                )}
                {!pricing.length && !showNewForm && (
                  <Button
                    size="small"
                    onClick={() => {
                      toggleNewFrom(true);
                    }}
                    data-id="add-new-line-item"
                    startIcon={<Add />}
                  >
                    Add New Price
                  </Button>
                )}
              </FormRow>
              <FormRow fullWidth>
                <Stack fullWidth>
                  <LineItem
                    id="title"
                    model="Business Model"
                    payment="Payment Terms"
                    startDate="Start Date"
                    endDate="End Date"
                    isLabelRow
                  />
                  {showNewForm && (
                    <FormLineItem
                      isCreatingNew={isCreatingNew}
                      prevStartDate={pricing[0] ? pricing[0].startDate : 0}
                      onSubmit={(data) => {
                        const payment =
                          data.model === SUPPLY_TAG_PAGE_PRICE_MODEL[0].value ||
                          data.model === SUPPLY_TAG_PAGE_PRICE_MODEL[1].value
                            ? parseFloat(data.payment)
                            : parseNumberWithRound(data.payment / 100);
                        toggleNewFrom(false);
                        onAddNewPrice(SUPPLY_TAG_PRICING_TYPE.pricing, { ...data, payment });
                      }}
                      onCancel={() => {
                        toggleNewFrom(false);
                      }}
                    />
                  )}
                  {pricing.slice(pagination.startIndex, pagination.endIndex).map((tag) => (
                    <LineItem
                      isCreatingNew={isCreatingNew}
                      key={tag.startDate}
                      id={tag.id}
                      model={tag.model}
                      payment={
                        tag.model === SUPPLY_TAG_PAGE_PRICE_MODEL[0].value ||
                        tag.model === SUPPLY_TAG_PAGE_PRICE_MODEL[1].value
                          ? tag.payment
                          : parseNumberWithRound(tag.payment * 100)
                      }
                      paymentMask={
                        tag.model === SUPPLY_TAG_PAGE_PRICE_MODEL[0].value ||
                        tag.model === SUPPLY_TAG_PAGE_PRICE_MODEL[1].value
                          ? '$[NUMBER]'
                          : '[NUMBER]%'
                      }
                      startDate={tag.startDate}
                      endDate={tag.endDate}
                      status={tag.status}
                      isDuplicating={isDuplicate}
                      onSubmit={(data) => {
                        const payment =
                          data.model === SUPPLY_TAG_PAGE_PRICE_MODEL[0].value ||
                          data.model === SUPPLY_TAG_PAGE_PRICE_MODEL[1].value
                            ? parseFloat(data.payment)
                            : parseNumberWithRound(data.payment / 100);
                        onEditPrice(SUPPLY_TAG_PRICING_TYPE.pricing, { ...data, payment });
                      }}
                      onDelete={(id) => {
                        onDeletePrice(SUPPLY_TAG_PRICING_TYPE.pricing, id);
                      }}
                    />
                  ))}

                  {!isCreatingNew && !isDuplicate && (
                    <TablePagination
                      component="div"
                      count={pricing.length}
                      rowsPerPageOptions={[25, 50, 100, 200]}
                      rowsPerPage={pagination.itemsPerPage}
                      page={pagination.currentPage}
                      onPageChange={(event, page) => {
                        pagination.setCurrentPage(page);
                      }}
                      onRowsPerPageChange={(event) => {
                        pagination.setItemsPerPage(+event.target.value);
                      }}
                    />
                  )}
                </Stack>
              </FormRow>

              <Divider flexItem />
              <FormRow label="Expenses" fullWidth justifyContent="flex-end">
                {!!expenses.length && !isDuplicate && (
                  <Button
                    size="small"
                    onClick={() => {
                      if (!isCreatingNew) {
                        paginationExpenses.setCurrentPage(1);
                      }
                      toggleNewExpensesForm(true);
                    }}
                    data-id="add-new-line-item"
                    startIcon={<Add />}
                    disabled={showNewExpensesForm || (isCreatingNew && expenses.length === 1)}
                  >
                    New
                  </Button>
                )}
                {!expenses.length && !showNewExpensesForm && (
                  <Button
                    size="small"
                    onClick={() => {
                      toggleNewExpensesForm(true);
                    }}
                    data-id="add-new-line-item"
                    startIcon={<Add />}
                  >
                    Add Expenses
                  </Button>
                )}
              </FormRow>
              <FormRow fullWidth>
                <Stack fullWidth>
                  <PricingLineItem
                    id="title"
                    rate="Expenses %"
                    startDate="Start Date"
                    endDate="End Date"
                    updatedBy="Updated By"
                    itemType={SUPPLY_TAG_PRICING_TYPE.expenses}
                    isLabelRow
                  />
                  {showNewExpensesForm && (
                    <PricingFormLineItem
                      isCreatingNew={isCreatingNew}
                      itemType={SUPPLY_TAG_PRICING_TYPE.expenses}
                      prevStartDate={expenses[0] ? expenses[0].startDate : 0}
                      isZeroAllowed
                      onSubmit={(data) => {
                        toggleNewExpensesForm(false);
                        onAddNewPrice(SUPPLY_TAG_PRICING_TYPE.expenses, {
                          ...data,
                          value: parseNumberWithRound(data.rate / 100),
                        });
                      }}
                      onCancel={() => {
                        toggleNewExpensesForm(false);
                      }}
                    />
                  )}
                  {expenses.slice(paginationExpenses.startIndex, paginationExpenses.endIndex).map((item) => (
                    <PricingLineItem
                      key={item.startDate}
                      id={item.id}
                      rate={parseNumberWithRound(item.value * 100)}
                      startDate={item.startDate}
                      endDate={item.endDate}
                      status={item.status}
                      updatedBy={item.updatedBy}
                      rateMask="[NUMBER]%"
                      isCreatingNew={isCreatingNew}
                      itemType={SUPPLY_TAG_PRICING_TYPE.expenses}
                      isDuplicating={isDuplicate}
                      hideDeleteBtn={isCreatingNew}
                      isZeroAllowed
                      onSubmit={(data) => {
                        onEditPrice(SUPPLY_TAG_PRICING_TYPE.expenses, {
                          ...data,
                          value: parseNumberWithRound(data.rate / 100),
                        });
                      }}
                      onDelete={(id) => {
                        onDeletePrice(SUPPLY_TAG_PRICING_TYPE.expenses, id);
                      }}
                    />
                  ))}
                  {!isCreatingNew && !isDuplicate && !!expenses.length && (
                    <TablePagination
                      component="div"
                      rowsPerPageOptions={[5, 10, 25]}
                      count={expenses.length}
                      rowsPerPage={paginationExpenses.itemsPerPage}
                      page={paginationExpenses.currentPage}
                      onPageChange={(event, page) => {
                        paginationExpenses.setCurrentPage(page);
                      }}
                      onRowsPerPageChange={(event) => {
                        paginationExpenses.setItemsPerPage(+event.target.value);
                      }}
                    />
                  )}
                </Stack>
              </FormRow>
            </>
          )}
        </FormSection>
      </FormContent>
    </Form>
  );
}

SupplyTagSettings.propTypes = {
  isAdminMP: PropTypes.bool.isRequired,
};

export default SupplyTagSettings;
