import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'clsx';
import dayjs from 'dayjs';
import isSameOrAfterPlugin from 'dayjs/plugin/isSameOrAfter';
import { Check, Clear } from '@mui/icons-material';

import {
  DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_LIST,
  DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_REV_SHARE,
  DEMAND_TAG_PRICING_TYPE,
  SUPPLY_TAG_PRICING_TYPE_EXPENSES,
} from '@/modules/marketplace/account/constants';

import { DateTimePicker, Grid, IconButton, MenuItem, Select, TextField } from '@/mui/components';

import styles from './index.module.scss';

dayjs.extend(isSameOrAfterPlugin);

const getStartDateWhenIsCreatingNewTag = () => new Date().getTime();
const getStartDateWhenIsUpdatingNewTag = (prevStartDate) => new Date(prevStartDate).getTime();
const isPrevStartDateIsSameOrAfterToday = (prevStartDate) => dayjs(prevStartDate).isSameOrAfter(new Date().getTime());
const isShouldDisableCalendarDate = (prevStartDate) => (dateFromCalendar) =>
  dayjs(prevStartDate).add(-1, 'days').isAfter(dateFromCalendar);
const isShouldDisabledSubmit = (prevStartDate, startDate) => {
  if (dayjs(prevStartDate).isSame(new Date().getTime())) {
    return false;
  }
  return dayjs(prevStartDate).isSameOrAfter(startDate);
};

function FormLineItem({
  className = '',
  isCreatingNew = false,
  prevStartDate = 0,
  isZeroAllowed = false,
  isEditableEndDate = false,
  defaultRate = 0,
  ...props
}) {
  const getPrevStartDate = () => {
    if (isPrevStartDateIsSameOrAfterToday(prevStartDate)) {
      return new Date(prevStartDate).getTime();
    }

    return new Date().getTime();
  };

  // eslint-disable-next-line react/prop-types
  const [model$, setModel] = useState(props.defaultModel || DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_LIST[0].value);
  const [rate$, setRate] = useState(defaultRate);
  const [startDate$, setStartDate] = useState(
    isCreatingNew ? getStartDateWhenIsCreatingNewTag() : getStartDateWhenIsUpdatingNewTag(getPrevStartDate()),
  );
  const [endDate$, setEndDate] = useState(null);
  const [isZeroAllowed$, setIsZeroAllowed] = useState(isZeroAllowed || false);

  useEffect(() => {
    if (!isCreatingNew) {
      setStartDate(getStartDateWhenIsUpdatingNewTag(getPrevStartDate()));
    }
  }, [prevStartDate]);

  const handleSubmit = () => {
    const startDate =
      !isCreatingNew && dayjs(getPrevStartDate()).isSameOrAfter(startDate$) ? null : new Date(startDate$).getTime();

    props.onSubmit({
      rate: rate$,
      startDate,
      endDate: endDate$ ? new Date(endDate$).getTime() : null,
      status: 'active',
      ...(props.itemType === DEMAND_TAG_PRICING_TYPE.adServing ? { model: model$ } : {}),
    });
  };

  const handleSetRate = ({ target }) => {
    const rate =
      ((props.itemType === DEMAND_TAG_PRICING_TYPE.fee ||
        props.itemType === SUPPLY_TAG_PRICING_TYPE_EXPENSES ||
        (props.itemType === DEMAND_TAG_PRICING_TYPE.adServing &&
          model$ === DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_REV_SHARE)) &&
        parseFloat(target.value) > 100) ||
      (props.itemType === DEMAND_TAG_PRICING_TYPE.adRequest && parseFloat(target.value) >= 1)
        ? rate$
        : target.value;

    const digitsAfterComma = props.itemType === DEMAND_TAG_PRICING_TYPE.adRequest ? 4 : 2;

    const newRate = rate?.split('.')[1]?.length > digitsAfterComma ? rate.substring(0, rate.length - 1) : rate;

    setRate(newRate);
  };

  const handleSetStartDate = (date) => {
    setStartDate(date);
    if (endDate$ && dayjs(date).isAfter(endDate$)) {
      setEndDate(null);
    }
  };

  const handleSetEndDate = (date) => {
    if (dayjs(date).isAfter(new Date().getTime())) {
      setEndDate(date);
    } else {
      setEndDate(null);
    }
  };

  return (
    <Grid
      container
      alignContent="center"
      justifyContent="flex-start"
      className={classNames(className, styles.Container)}
    >
      {props.itemType === DEMAND_TAG_PRICING_TYPE.adServing && (
        <Grid item xs={2} className={styles.Item}>
          <Select
            value={model$}
            size="small"
            onChange={({ target }) => {
              setModel(target.value);
              setRate(0);
              setIsZeroAllowed(target.value !== DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_REV_SHARE);
            }}
          >
            {DEMAND_TAG_PAGE_AD_SERVING_BUSINESS_MODEL_LIST.map((item) => (
              <MenuItem value={item.value} key={item.value}>
                {item.label}
              </MenuItem>
            ))}
          </Select>
        </Grid>
      )}

      <Grid item xs={2} className={styles.Item}>
        <TextField
          data-id="rate"
          value={rate$}
          type="number"
          placeholder="Rate"
          onChange={handleSetRate}
          variant="outlined"
          size="small"
        />
      </Grid>
      <Grid container item xs={props.itemType === DEMAND_TAG_PRICING_TYPE.adServing ? 7 : 9}>
        <Grid item xs={3} className={styles.Item}>
          <DateTimePicker
            value={dayjs(startDate$)}
            onChange={(date) => {
              handleSetStartDate(date);
            }}
            shouldDisableDate={isShouldDisableCalendarDate(getPrevStartDate())}
            disabled={isCreatingNew || !prevStartDate}
            slotProps={{
              textField: {
                size: 'small',
              },
            }}
          />
        </Grid>

        {isEditableEndDate && (
          <Grid item xs={3} className={styles.Item}>
            <DateTimePicker
              value={endDate$ ? dayjs(endDate$) : undefined}
              onChange={(date) => {
                handleSetEndDate(date);
              }}
              shouldDisableDate={isShouldDisableCalendarDate(getPrevStartDate())}
              disablePast
              disableIgnoringDatePartForTimeValidation
              slotProps={{
                textField: {
                  size: 'small',
                },
              }}
            />
          </Grid>
        )}
      </Grid>

      <Grid item xs={1} className={classNames(styles.Buttons, styles.Item)}>
        <div>
          <IconButton
            disabled={
              (!rate$ && rate$ !== 0) ||
              (!isZeroAllowed$ && +rate$ <= 0) ||
              (isZeroAllowed$ && +rate$ < 0) ||
              (isCreatingNew ? false : isShouldDisabledSubmit(getPrevStartDate(), startDate$))
            }
            onClick={handleSubmit}
          >
            <Check />
          </IconButton>
        </div>

        <div>
          <IconButton onClick={() => props.onCancel()}>
            <Clear />
          </IconButton>
        </div>
      </Grid>
    </Grid>
  );
}

FormLineItem.propTypes = {
  className: PropTypes.string,
  onSubmit: PropTypes.func.isRequired,
  onCancel: PropTypes.func.isRequired,
  isCreatingNew: PropTypes.bool,
  prevStartDate: PropTypes.number,
  itemType: PropTypes.string.isRequired,
  isZeroAllowed: PropTypes.bool,
  isEditableEndDate: PropTypes.bool,
  defaultRate: PropTypes.number,
};

export default FormLineItem;
