/* eslint-disable no-nested-ternary */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Checkbox, FormControlLabel, Stack, TextField, Typography } from '@mui/material';
import { useEffect, useRef, useState } from 'react';
import { Controller, useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';

import { get } from 'lodash';
import { findCurrency, usePaymentContext } from '@blocklet/payment-react';
import { useProductsContext } from '../../contexts/products';
import { getProductByPriceId, isPriceAligned } from '../../libs/util';
import CreateProduct from '../product/create';
import LineItem from './item';
import ProductSelect from './product-select';

export default function BeforePay({
  triggerError = () => {},
}: {
  triggerError?: (keys: { [key: string]: boolean }) => void;
}) {
  const { t } = useLocaleContext();
  const [params, setParams] = useSearchParams();
  const { settings } = usePaymentContext();
  const { products, refresh } = useProductsContext();
  const {
    control,
    setValue,
    getValues,
    formState: { errors },
  } = useFormContext();
  const items = useFieldArray({ control, name: 'line_items' });
  const includeFreeTrial = useWatch({ control, name: 'include_free_trial' });
  const [state, setState] = useState({ creating: false });
  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) {
      items.append({
        price_id: priceId,
        quantity: 1,
        adjustable_quantity: { enabled: false, maximum: 99, minimum: 0 },
      });
      const product = getProductByPriceId(products, priceId);
      if (product) {
        const price = product.prices.find((x) => x.id === priceId);
        const currency = findCurrency(settings.paymentMethods, price?.currency_id ?? '');
        if (currency) {
          setValue('currency_id', currency.id);
        }
        if (price && price.type === 'recurring') {
          setValue('invoice_creation.enabled', true);
        }
      }
      setTimeout(() => {
        if (containerRef.current) {
          containerRef.current.scrollTo({
            top: containerRef.current.scrollHeight,
            behavior: 'smooth',
          });
        }
      }, 0);
    }
  };

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

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

  useEffect(() => {
    const hasDifferentCurrencyOrRecurring = items.fields.some((_, index) => {
      const priceAlignResult = isPriceAligned(items.fields as any[], products, index);
      return !priceAlignResult.currency || !priceAlignResult.recurring;
    });
    triggerError({ line_items: hasDifferentCurrencyOrRecurring });
  }, [items.fields, products]);

  return (
    <Stack spacing={2} sx={{ width: '100%' }}>
      <Typography variant="h6" sx={{ fontWeight: 600 }}>
        {t('admin.paymentLink.products')} ({getValues().line_items.length})
      </Typography>
      <Stack spacing={2} sx={{ width: '100%' }}>
        <Stack direction="column" sx={{ maxHeight: 500, width: '100%', overflowY: 'auto', gap: 2 }} ref={containerRef}>
          {items.fields.map((item, index) => {
            // @ts-ignore
            const product = getProductByPriceId(products, item.price_id);
            if (!product) {
              return null;
            }

            return (
              <LineItem
                key={item.id}
                // @ts-ignore
                valid={isPriceAligned(items.fields, products, index).aligned}
                prefix={`line_items.${index}`}
                product={product}
                onRemove={() => items.remove(index)}
                onUpdate={refresh}
              />
            );
          })}
          {items.fields.some((_, index) => !isPriceAligned(items.fields as any[], products, index).recurring) && (
            <Typography
              color="error"
              sx={{
                fontSize: 'small',
              }}>
              {t('admin.paymentLink.recurringNotAligned')}
            </Typography>
          )}
          {items.fields.some((_, index) => !isPriceAligned(items.fields as any[], products, index).currency) && (
            <Typography
              color="error"
              sx={{
                fontSize: 'small',
              }}>
              {t('admin.paymentLink.currencyNotAligned')}
            </Typography>
          )}
        </Stack>

        <ProductSelect
          mode={items.fields.length ? 'waiting' : 'selecting'}
          onSelect={onProductSelected}
          hasSelected={(price) => items.fields.some((x: any) => x.price_id === price.id)}
        />
        {state.creating && <CreateProduct onCancel={() => setState({ creating: false })} onSave={onProductCreated} />}
      </Stack>
      <Typography variant="h6" sx={{ fontWeight: 600 }}>
        {t('common.options')}
      </Typography>
      <Controller
        name="billing_address_collection"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().billing_address_collection === 'required'}
                {...field}
                onChange={(_, checked) => setValue(field.name, checked ? 'required' : 'auto')}
              />
            }
            label={t('admin.paymentLink.requireBillingAddress')}
          />
        )}
      />
      <Controller
        name="phone_number_collection.enabled"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().phone_number_collection.enabled}
                {...field}
                onChange={(_, checked) => setValue(field.name, checked)}
              />
            }
            label={t('admin.paymentLink.requirePhoneNumber')}
          />
        )}
      />
      <Controller
        name="allow_promotion_codes"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().allow_promotion_codes}
                {...field}
                onChange={(_, checked) => setValue(field.name, checked)}
              />
            }
            label={t('admin.paymentLink.allowPromotionCodes')}
          />
        )}
      />
      <Controller
        name="cross_sell_behavior"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().cross_sell_behavior === 'required'}
                {...field}
                onChange={(_, checked) => setValue(field.name, checked ? 'required' : 'auto')}
              />
            }
            label={t('admin.paymentLink.requireCrossSell')}
          />
        )}
      />
      <Controller
        name="include_free_trial"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().include_free_trial}
                {...field}
                onChange={(_, checked) => {
                  setValue(field.name, checked);
                  if (checked) {
                    setValue('subscription_data.trial_period_days', 30);
                  } else {
                    setValue('subscription_data.trial_period_days', 0);
                  }
                }}
              />
            }
            label={t('admin.paymentLink.includeFreeTrial')}
          />
        )}
      />
      <Controller
        name="subscription_data.no_stake"
        control={control}
        render={({ field }) => (
          <FormControlLabel
            control={
              <Checkbox
                checked={getValues().subscription_data?.no_stake || false}
                {...field}
                onChange={(_, checked) => setValue(field.name, checked)}
              />
            }
            label={t('admin.paymentLink.noStakeRequired')}
          />
        )}
      />
      <Controller
        name="metadata"
        control={control}
        render={({ field }) => {
          const metadata = field.value || {};
          const isChecked = metadata.show_product_features === 'true';

          return (
            <FormControlLabel
              control={
                <Checkbox
                  checked={isChecked}
                  onChange={(_, checked) => {
                    const newMetadata = { ...metadata };
                    newMetadata.show_product_features = checked ? 'true' : 'false';
                    field.onChange(newMetadata);
                  }}
                />
              }
              label={t('admin.paymentLink.showProductFeatures')}
            />
          );
        }}
      />
      <Controller
        name="metadata"
        control={control}
        render={({ field }) => {
          const metadata = field.value || {};
          const isChecked = metadata.allow_skip_payment_method === 'true';

          return (
            <FormControlLabel
              control={
                <Checkbox
                  checked={isChecked}
                  onChange={(_, checked) => {
                    const newMetadata = { ...metadata };
                    newMetadata.allow_skip_payment_method = checked ? 'true' : 'false';
                    field.onChange(newMetadata);
                  }}
                />
              }
              label={t('admin.paymentLink.allowSkipPaymentMethod')}
            />
          );
        }}
      />
      {includeFreeTrial && (
        <Controller
          name="subscription_data.trial_period_days"
          control={control}
          rules={{
            required: t('payment.checkout.required'),
            validate: (val) => {
              if (val <= 0) {
                return t('admin.paymentLink.freeTrialDaysPositive');
              }
              return true;
            },
          }}
          render={({ field }) => (
            <TextField
              {...field}
              size="small"
              helperText={get(errors, 'subscription_data.trial_period_days')?.message as string}
              error={!!get(errors, 'subscription_data.trial_period_days')}
              slotProps={{
                input: { endAdornment: t('common.days') },
              }}
            />
          )}
        />
      )}
    </Stack>
  );
}
