/** @jsxRuntime classic */
/** @jsx jsx */
import { Fragment, useMemo, useState, useRef, useEffect } from 'react';
import { jsx } from '@emotion/react';
import { useColors } from '../../hooks/useColors';
import { useTypography } from '../../hooks/useTypography';
import { ProductCardContainer } from './style';
import { ETypography, ETypographyColor, Icons } from '../../types/theme';
import {
  BnIcon,
  Button,
  Popup,
  SelectOptions,
  Tag,
  Typography,
} from '../../components';
import { ProductPrice } from '../../types/entities/seasons';
import { Pricify } from '../../lib/price';
import {
  DiscountMethodsEnum,
  GroupItemsPricing,
} from '../../types/entities/entitledPrice';
import dayjs from 'dayjs';

interface IAddon {
  price: number;
  name: string;
  prices: ProductPrice[];
  defaultPriceId: number;
}

interface IOption {
  label: string;
  value: string;
}

export interface IProductCardProps {
  withCta?: boolean;
  icon?: Icons;

  state: {
    name?: string;
    description?: string;
    prices?: ProductPrice[];
    isProRated?: boolean;
    entitledPrices?: GroupItemsPricing[];
    downpayment?: number;
    addons?: IAddon[];
    registrationStartDate?: string;
    registrationEndDate?: string;
  };
  defaultPriceTitle?: string;
  moreMenu: {
    options?: IOption[];
    handleActions?: (v: string) => void;
  };
  handlePurchase?: (v?: any) => void;
}

interface IProductToOrder extends ProductPrice {
  ordinal: number;
}

export const ProductCard = ({
  withCta = false,
  icon,
  state: {
    name: title,
    description,
    prices = [],
    registrationStartDate,
    registrationEndDate,
    isProRated,
    downpayment,
    addons = [],
    entitledPrices = [],
  },
  defaultPriceTitle = '',
  moreMenu: { options = [], handleActions = () => {} },
  handlePurchase,
}: IProductCardProps) => {
  const { colors } = useColors();
  const { typography } = useTypography();
  const [height, setHeight] = useState<number>(0);

  const collapsableRef = useRef<HTMLDivElement>(null);

  const [isExpand, setExpand] = useState<boolean>(!withCta);

  const expandToggle = () => setExpand(!isExpand);

  if (
    collapsableRef?.current?.scrollHeight &&
    collapsableRef?.current?.scrollHeight !== height
  ) {
    setHeight(collapsableRef?.current?.scrollHeight);
  }

  const discounts = useMemo(() => {
    const d: number[] = [];
    const uniqueDiscounts: GroupItemsPricing[] = [];
    entitledPrices.forEach((entitledPrice) => {
      if (!d.includes(entitledPrice?.group?.id as number)) {
        uniqueDiscounts.push(entitledPrice);
        d.push(entitledPrice?.group?.id as number);
      }
    });
    return uniqueDiscounts;
  }, [entitledPrices]);

  return (
    <div
      css={ProductCardContainer(
        colors,
        typography,
        isExpand,
        height || null,
        withCta
      )}
    >
      <div className="header">
        <div className="title">
          <BnIcon icon={icon} />
          <Typography
            color={ETypographyColor.primary}
            type={ETypography.body2Accented}
          >
            {title}
          </Typography>
        </div>
        <Typography
          color={ETypographyColor.secondary}
          type={ETypography.caption}
        >
          Registration {dayjs(registrationStartDate).format('MMM DD')} -{' '}
          {dayjs(registrationEndDate).format('MMM DD, YYYY')}
        </Typography>
        {withCta && (
          <div className="more-menu">
            <MoreMenu options={options} handleActions={handleActions} />
          </div>
        )}
      </div>
      <div className="divider" />
      <div className="body">
        <div className="collapsable" ref={collapsableRef}>
          <div className="description">
            <Typography
              color={ETypographyColor.secondary}
              type={ETypography.caption}
            >
              {description}
            </Typography>
          </div>
          <div className="prices">
            {prices
              .sort(
                (a, b) =>
                  dayjs(a.startDate).valueOf() - dayjs(b.startDate).valueOf()
              )
              .map((price) => {
                let newPrice: IProductToOrder = { ...price, ordinal: 1 };
                if (dayjs().valueOf() > dayjs(price.endDate).valueOf()) {
                  newPrice['ordinal'] = 10;
                }
                return newPrice;
              })
              .sort((a: IProductToOrder, b: IProductToOrder) => {
                return a.ordinal - b.ordinal;
              })
              .map((price, index) => {
                return (
                  <PriceLine
                    isDisabled={
                      dayjs().valueOf() > dayjs(price.endDate).valueOf()
                    }
                    state={price}
                    key={index}
                    defaultPriceTitle={defaultPriceTitle}
                  />
                );
              })}
          </div>
          {isProRated && (
            <div className="prorated">
              <BnIcon icon={Icons.check} />
              <Typography
                color={ETypographyColor.secondary}
                type={ETypography.captionAccented}
              >
                Prorated
              </Typography>
            </div>
          )}
          {discounts.length > 0 && <div className="divider" />}
          {discounts.length > 0 && (
            <div className="discounts">
              <Typography
                color={ETypographyColor.primary}
                type={ETypography.captionAccented}
              >
                Discounts
              </Typography>
              {discounts.map((discount, index) => {
                return (
                  <DiscountLine
                    key={index}
                    name={discount?.group?.name as string}
                    amount={discount?.discountValue as number}
                    type={discount?.discountMethod as DiscountMethodsEnum}
                  />
                );
              })}
            </div>
          )}
          {downpayment !== 0 ? (
            <div className="paymentPlan">
              <Typography
                color={ETypographyColor.primary}
                type={ETypography.captionAccented}
              >
                Payment plan
              </Typography>
              <div className="deposit">
                <Typography
                  color={ETypographyColor.primary}
                  type={ETypography.captionAccented}
                >
                  Deposit
                </Typography>
                <Typography
                  color={ETypographyColor.primary}
                  type={ETypography.body2}
                >
                  {Pricify(downpayment)}
                </Typography>
              </div>
              {/* <Typography
                color={ETypographyColor.secondary}
                type={ETypography.caption}
              >
                payment due Aug 12, 2021
              </Typography> */}
            </div>
          ) : (
            <div style={{ marginBottom: '12px' }} />
          )}
          {addons.length > 0 && (
            <Fragment>
              <div className="divider" />
              <div className="discounts">
                <Typography
                  color={ETypographyColor.primary}
                  type={ETypography.captionAccented}
                >
                  Addons
                </Typography>
                {addons.map((addon: IAddon, index) => {
                  let price = addon.price;
                  if (!addon.price) {
                    addon.prices.forEach((p) => {
                      if (p.id === addon.defaultPriceId) {
                        price = Number(p.price);
                      }
                    });
                  }
                  return (
                    <DiscountLine
                      type={DiscountMethodsEnum.AMOUNT}
                      name={addon.name}
                      amount={price}
                      key={index}
                    />
                  );
                })}
              </div>
            </Fragment>
          )}
        </div>
        {withCta && (
          <button className="show-button" onClick={expandToggle}>
            <Typography
              color={ETypographyColor.primary}
              type={ETypography.body2Link}
            >
              {isExpand ? 'See less' : 'See all'}
            </Typography>
          </button>
        )}
      </div>
      {withCta && (
        <Fragment>
          <div className="divider" />
          <div className="footer">
            <Button
              type="button"
              theme="secondary"
              sizer="XS"
              onClick={handlePurchase}
            >
              Purchase
            </Button>
          </div>
        </Fragment>
      )}
    </div>
  );
};

const MoreMenu = ({
  options,
  handleActions,
}: {
  options: IOption[];
  handleActions: (v: string) => void;
}) => {
  const [isOpen, setOpen] = useState<boolean>(false);

  return (
    <Popup
      placement="bottom-start"
      padding={0}
      trigger={isOpen}
      onOpenChange={(v) => setOpen(v)}
      body={
        <SelectOptions options={options} onSelect={handleActions} value={''} />
      }
    >
      <Button sizer="S" theme="basic">
        <BnIcon icon={Icons.more} />
      </Button>
    </Popup>
  );
};

const DiscountLine = ({
  name,
  amount,
  type,
}: {
  name: string;
  amount: number;
  type: DiscountMethodsEnum;
}) => {
  return (
    <div className="discount-line">
      <Typography color={ETypographyColor.secondary} type={ETypography.caption}>
        {name}
      </Typography>
      <Typography color={ETypographyColor.secondary} type={ETypography.body2}>
        {type === DiscountMethodsEnum.AMOUNT
          ? Pricify(Number(amount))
          : `${amount}%`}
      </Typography>
    </div>
  );
};

export const PriceLine = ({
  state,
  defaultPriceTitle,
  isDisabled,
}: {
  state: ProductPrice;
  defaultPriceTitle: string;
  isDisabled: boolean;
}) => {
  if (
    state.name.toLowerCase().includes('late fee') ||
    state.name.toLowerCase().includes('early bird')
  ) {
    return (
      <div className="price-line">
        <div className="left-side">
          <div>
            {state.name.toLowerCase().includes('late fee') ? (
              <Tag title="Late Fee" color={isDisabled ? 'gray' : 'red'} />
            ) : (
              <Tag title="Early Bird" color={isDisabled ? 'gray' : 'green'} />
            )}
            <Typography
              color={
                isDisabled
                  ? ETypographyColor.disabled
                  : ETypographyColor.secondary
              }
              type={ETypography.caption}
            >
              {state.discountValue &&
                `(
              ${
                state.discountMethod === DiscountMethodsEnum.PERCENT
                  ? `${state.discountValue}%`
                  : `$${state.discountValue}`
              }
              )`}
            </Typography>
          </div>
          <Typography
            color={
              isDisabled
                ? ETypographyColor.disabled
                : ETypographyColor.secondary
            }
            type={ETypography.caption}
          >
            {`${dayjs(state.startDate).format('MMM DD')} - 
              ${dayjs(state.endDate).format('MMM DD, YYYY')}`}
          </Typography>
        </div>
        <Typography
          color={
            isDisabled ? ETypographyColor.disabled : ETypographyColor.primary
          }
          type={ETypography.body2}
        >
          {Pricify(Number(state.price))}
        </Typography>
      </div>
    );
  } else {
    return (
      <div className="price-line">
        <Typography
          color={ETypographyColor.primary}
          type={ETypography.body2Accented}
        >
          {defaultPriceTitle}
        </Typography>
        <Typography color={ETypographyColor.primary} type={ETypography.body2}>
          {Pricify(Number(state.price))}
        </Typography>
      </div>
    );
  }
};
