/* eslint-disable no-nested-ternary */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Tabs from '@arcblock/ux/lib/Tabs';
import Toast from '@arcblock/ux/lib/Toast';
import { api, formatError, usePaymentContext } from '@blocklet/payment-react';
import type { InferFormType, TPaymentLink } from '@blocklet/payment-types';
import { AddOutlined, Fullscreen, FullscreenExit } from '@mui/icons-material';
import { Box, Button, Stack, Typography } from '@mui/material';
import { useEffect, useRef, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';
import { dispatch } from 'use-bus';

import { useSetState } from 'ahooks';
import DrawerForm from '../../../../components/drawer-form';
import AfterPay from '../../../../components/payment-link/after-pay';
import BeforePay from '../../../../components/payment-link/before-pay';
import PaymentLinkPreview from '../../../../components/payment-link/preview';
import { ProductsProvider } from '../../../../contexts/products';
import { useSessionContext } from '../../../../contexts/session';

type PaymentLink = InferFormType<TPaymentLink> & {
  include_free_trial: boolean;
};

export default function CreatePaymentLink() {
  const { t } = useLocaleContext();
  const [params] = useSearchParams();
  const { session } = useSessionContext();
  const [current, setCurrent] = useState('beforePay');
  const [stashed, setStashed] = useState(0);
  const { settings } = usePaymentContext();
  const fullScreenRef = useRef(null);
  const [errors, triggerError] = useSetState({});

  const methods = useForm<PaymentLink>({
    shouldUnregister: false,
    mode: 'onChange',
    defaultValues: {
      name: '',
      line_items: [],
      currency_id: settings.baseCurrency.id,
      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',
      },
      invoice_creation: {
        enabled: true,
      },
      phone_number_collection: {
        enabled: false,
      },
      billing_address_collection: 'auto',
      include_free_trial: false,
      subscription_data: {
        description: '',
        trial_period_days: 0,
        no_stake: false,
      },
      nft_mint_settings: {
        enabled: false,
        factory: '',
      },
      cross_sell_behavior: 'auto',
      metadata: [], // FIXME:
      custom_fields: [], // FIXME:
      submit_type: 'auto', // FIXME:
    },
  });

  const changes = methods.watch([
    'line_items',
    'allow_promotion_codes',
    'include_free_trial',
    'subscription_data',
    'billing_address_collection',
    'phone_number_collection',
    'currency_id',
    'metadata',
  ]);

  useEffect(() => {
    api.post('/api/payment-links/stash', methods.getValues()).then(() => {
      setStashed(stashed + 1);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [JSON.stringify(changes)]);

  const tabs = [
    {
      label: t('admin.paymentLink.beforePay'),
      value: 'beforePay',
      component: BeforePay,
    },
    { label: t('admin.paymentLink.afterPay'), value: 'afterPay', component: AfterPay },
  ];
  const TabComponent = tabs.find((x) => x.value === current)?.component || BeforePay;

  const onSubmit = (data: TPaymentLink) => {
    if (data.line_items.length === 0) {
      Toast.error(t('admin.paymentLink.noProducts'));
      return;
    }
    if (data.after_completion?.type === 'redirect' && !data.after_completion?.redirect?.url) {
      Toast.error(t('admin.paymentLink.noRedirectUrl'));
      return;
    }
    // @ts-ignore
    if (data.include_free_trial && data.subscription_data?.trial_period_days === 0) {
      Toast.error(t('admin.paymentLink.noSubscriptionTrialDays'));
      return;
    }

    if (Object.values(errors).some((v) => v)) {
      return;
    }
    api
      .post('/api/payment-links', data)
      .then(() => {
        Toast.success(t('admin.paymentLink.saved'));
        methods.reset();
        dispatch('drawer.submitted');
        dispatch('paymentLink.created');
      })
      .catch((err: any) => {
        console.error(err);
        Toast.error(formatError(err));
      });
  };

  return (
    <DrawerForm
      icon={<AddOutlined />}
      text={t('admin.paymentLink.add')}
      open={!!params.get('price_id')}
      width={1280}
      addons={
        // @ts-ignore
        <Button variant="contained" size="small" onClick={methods.handleSubmit(onSubmit)}>
          {t('admin.paymentLink.save')}
        </Button>
      }>
      <FormProvider {...methods}>
        <Stack
          spacing={3}
          direction="row"
          sx={{
            alignItems: 'flex-start',
          }}>
          <Stack
            spacing={2}
            sx={{
              flex: 2,
              alignItems: 'flex-start',
            }}>
            <Typography variant="h6" sx={{ mb: 2, fontWeight: 600 }}>
              {t('common.setup')}
            </Typography>
            {/* @ts-ignore */}
            <Tabs
              // @ts-ignore
              tabs={tabs}
              // @ts-ignore
              current={current}
              // @ts-ignore
              onChange={(v: string) => {
                methods.handleSubmit(() => setCurrent(v))();
              }}
              style={{ width: '100%' }}
              scrollButtons="auto"
            />
            <ProductsProvider>
              <TabComponent triggerError={triggerError} />
            </ProductsProvider>
          </Stack>
          <Stack
            sx={{
              flex: 1,
              maxWidth: 680,
            }}>
            <Typography variant="h6" sx={{ mb: 2, fontWeight: 600 }}>
              {t('common.preview')}
            </Typography>
            {stashed && <PaymentLinkPreview id={`plink_${session?.user?.did}`} version={stashed} ref={fullScreenRef} />}
            <Box
              sx={{
                textAlign: 'center',
                mt: 2.5,
              }}>
              <Button
                variant="outlined"
                color="primary"
                onClick={() => (fullScreenRef?.current as any)?.toggleFullscreen()}>
                {(fullScreenRef?.current as any)?.fullscreen ? <FullscreenExit /> : <Fullscreen />}
                {t('common.fullscreen')}
              </Button>
            </Box>
          </Stack>
        </Stack>
      </FormProvider>
    </DrawerForm>
  );
}
