import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Checkbox, FormControlLabel, MenuItem, Select, Stack, Typography } from '@mui/material';
import { useSetState } from 'ahooks';
import { useEffect, useRef } from 'react';
import { Controller, useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';

import { useProductsContext } from '../../contexts/products';
import { getProductByPriceId, groupPricingTableItems, isPriceCurrencyAligned } from '../../libs/util';
import ProductSelect from '../payment-link/product-select';
import CreateProduct from '../product/create';
import ProductItem from './product-item';

export default function PricingTableProductSettings({
  triggerError = () => {},
}: {
  triggerError?: (keys: { [key: string]: boolean }) => void;
}) {
  const { t } = useLocaleContext();
  const [params, setParams] = useSearchParams();
  const { products, refresh } = useProductsContext();
  const { control, setValue, getValues } = useFormContext();
  const items = useFieldArray({ control, name: 'items' });
  const [state, setState] = useSetState({ creating: false });
  const highlight = useWatch({ control, name: 'highlight' });
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (items.fields.length) {
      const selected: any[] = items.fields.map((x: any) => getProductByPriceId(products, x.price_id));
      const name = selected.length > 1 ? `${selected[0].name} and ${selected.length - 1} more` : selected[0].name;
      setValue('name', name);
    } else {
      setValue('name', '');
    }
  }, [items.fields, setValue, products]);

  const onProductSelected = (priceId: string) => {
    if (priceId === 'add') {
      setState({ creating: true });
    } else if (priceId) {
      const product = getProductByPriceId(products, priceId);
      if (product) {
        const price = product?.prices.find((x) => x.id === priceId);
        items.append({
          price_id: priceId,
          product_id: product.id,
          currency_id: price?.currency_id,
          is_highlight: false,
          highlight_text: 'popular',
          adjustable_quantity: {
            enabled: false,
            maximum: 1,
            minimum: 0,
          },
          after_completion: {
            type: 'hosted_confirmation',
            hosted_confirmation: {
              custom_message: '',
            },
            redirect: {
              url: '',
            },
          },
          allow_promotion_codes: false,
          customer_creation: 'always',
          consent_collection: {
            promotions: 'none',
            terms_of_service: 'none',
          },
          phone_number_collection: {
            enabled: false,
          },
          billing_address_collection: 'auto',
          include_free_trial: false,
          subscription_data: {
            description: '',
            trial_period_days: 0,
          },
          nft_mint_settings: {
            enabled: false,
            factory: '',
          },
          custom_fields: [],
          submit_type: 'auto',
          cross_sell_behavior: 'auto',
        });
      }
      setTimeout(() => {
        if (containerRef.current) {
          containerRef.current.scrollTo({
            top: containerRef.current.scrollHeight,
            behavior: 'smooth',
          });
        }
      }, 0);
    }
  };

  useEffect(() => {
    if (params.get('price_id') && products.length && getValues().items.length === 0) {
      onProductSelected(params.get('price_id') as string);
      params.set('price_id', '');
      setParams(params);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [products.length]);

  const onProductCreated = () => {
    setState({ creating: false });
    refresh();
  };

  const grouped = groupPricingTableItems(items.fields);

  useEffect(() => {
    const hasDifferentCurrency = items.fields.some(
      (_, index) => !isPriceCurrencyAligned(items.fields as any[], products, index)
    );
    triggerError({ items: hasDifferentCurrency });
  }, [items.fields, products]);

  return (
    <Stack
      spacing={2}
      sx={{
        alignItems: 'flex-start',
      }}>
      <Typography variant="h6" sx={{ mb: 2, fontWeight: 600 }}>
        {t('admin.paymentLink.products')}
      </Typography>
      <Stack spacing={2} sx={{ width: '100%' }}>
        <Stack direction="column" sx={{ maxHeight: 800, width: '100%', overflowY: 'auto', gap: 2 }} ref={containerRef}>
          {grouped.map((item) => {
            const [productId, prices] = item;
            // @ts-ignore
            const product = products.find((x) => x.id === productId);
            if (!product) {
              return null;
            }

            return (
              <ProductItem
                key={productId}
                // @ts-ignore
                valid={prices.every((x) => isPriceCurrencyAligned(items.fields, products, x.index))}
                product={product}
                prices={prices}
                onUpdate={refresh}
                onRemove={(i: number) => items.remove(i)}
              />
            );
          })}
          {items.fields.some((_, index) => !isPriceCurrencyAligned(items.fields as any[], products, index)) && (
            <Typography
              color="error"
              sx={{
                fontSize: 'small',
              }}>
              {t('admin.paymentLink.currencyNotAligned')}
            </Typography>
          )}
        </Stack>

        <ProductSelect
          mode={items.fields.length ? 'waiting' : 'selecting'}
          onSelect={onProductSelected}
          hasSelected={(price) => price.type !== 'recurring' || items.fields.some((x: any) => x.price_id === price.id)}
        />
        {state.creating && <CreateProduct onCancel={() => setState({ creating: false })} onSave={onProductCreated} />}
      </Stack>
      <Typography variant="h6" sx={{ mb: 2, fontWeight: 600 }}>
        {t('admin.pricingTable.display')}
      </Typography>
      {grouped.length > 0 && (
        <Stack direction="column" spacing={2}>
          <Controller
            name="highlight"
            control={control}
            render={({ field }) => (
              <FormControlLabel
                label={t('admin.pricingTable.highlight')}
                control={
                  <Checkbox
                    checked={getValues().highlight}
                    {...field}
                    onChange={(_, checked) => {
                      setValue(field.name, checked);
                      if (checked && !getValues().highlight_product_id && grouped[0]) {
                        setValue('highlight_product_id', grouped[0][0]);
                      }
                    }}
                  />
                }
              />
            )}
          />
          {highlight && (
            <Stack
              direction="row"
              spacing={0.5}
              sx={{
                alignItems: 'center',
              }}>
              <Controller
                name="highlight_product_id"
                control={control}
                render={({ field }) => (
                  <Select {...field} size="small">
                    {grouped.map(([productId]) => {
                      const product = products.find((x) => x.id === productId);
                      if (!product) {
                        return null;
                      }

                      return (
                        <MenuItem key={productId} value={productId}>
                          {product.name}
                        </MenuItem>
                      );
                    })}
                  </Select>
                )}
              />
              <Typography>as</Typography>
              <Controller
                name="highlight_text"
                control={control}
                render={({ field }) => (
                  <Select {...field} size="small">
                    <MenuItem key="deal" value="deal">
                      Best deal
                    </MenuItem>
                    <MenuItem key="popular" value="popular">
                      Most popular
                    </MenuItem>
                    <MenuItem key="recommended" value="recommended">
                      Recommended
                    </MenuItem>
                  </Select>
                )}
              />
            </Stack>
          )}
        </Stack>
      )}
    </Stack>
  );
}
