import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { api, findCurrency, formatError, formatPrice, usePaymentContext, FormLabel } from '@blocklet/payment-react';
import type { TPrice, TProduct, TProductExpanded } from '@blocklet/payment-types';
import { Box, Checkbox, FormControlLabel, Stack, TextField, Typography } from '@mui/material';
import { useSetState } from 'ahooks';
import { Controller, useFormContext, useWatch } from 'react-hook-form';

import Actions from '../actions';
import ClickBoundary from '../click-boundary';
import InfoCard from '../info-card';
import EditProduct from '../product/edit';

type Props = {
  prefix: string;
  product: TProductExpanded;
  valid: boolean;
  onUpdate: () => void;
  onRemove: () => void;
};

export default function LineItem({ prefix, product, valid, onUpdate, onRemove }: Props) {
  const { t } = useLocaleContext();
  const getFieldName = (name: string) => (prefix ? `${prefix}.${name}` : name);
  const { settings } = usePaymentContext();
  const { control, setValue } = useFormContext();
  const [state, setState] = useSetState({ editing: false, loading: false });
  const adjustable = useWatch({ control, name: getFieldName('adjustable_quantity.enabled') });
  const minQuantity = useWatch({ control, name: getFieldName('adjustable_quantity.minimum') });
  const maxQuantity = useWatch({ control, name: getFieldName('adjustable_quantity.maximum') });

  const adjustableError = Number(minQuantity) >= Number(maxQuantity);

  const onSave = async (updates: TProduct) => {
    try {
      setState({ loading: true });
      await api.put(`/api/products/${product.id}`, updates).then((res: any) => res.data);
      Toast.success(t('common.saved'));
      onUpdate();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
    } finally {
      setState({ loading: false });
    }
  };

  const productCurrency =
    findCurrency(settings.paymentMethods, product.prices[0]?.currency_id ?? '') || settings.baseCurrency;

  return (
    <Box
      sx={{
        p: 2,
        borderWidth: valid ? 1 : 2,
        borderStyle: 'solid',
        borderColor: valid ? 'divider' : 'error.main',
        borderRadius: 2,
        position: 'relative',
      }}>
      <ClickBoundary>
        <Actions
          sx={{ position: 'absolute', top: 0, right: 0 }}
          actions={[
            {
              label: t('admin.product.edit'),
              handler: () => setState({ editing: true }),
              color: 'primary',
            },
            {
              label: t('admin.product.remove'),
              handler: onRemove,
              color: 'error',
            },
          ]}
        />
      </ClickBoundary>
      <Stack
        direction="column"
        sx={{
          alignItems: 'flex-start',
        }}>
        <InfoCard
          logo={product.images[0]}
          name={product.name}
          description={formatPrice(product.prices[0] as TPrice, productCurrency!)}
        />
        <Controller
          name={getFieldName('quantity')}
          control={control}
          render={({ field }) => (
            <Stack
              direction="row"
              sx={{
                alignItems: 'center',
                mt: 1,
              }}>
              <TextField
                sx={{ width: 80, mr: 1 }}
                size="small"
                type="number"
                {...field}
                onChange={(e) => {
                  const intValue = parseInt(e.target.value || '1', 10);
                  if (intValue >= 1) {
                    field.onChange(intValue);
                  }
                }}
                slotProps={{
                  htmlInput: { style: { padding: '4px 8px' } },
                }}
              />
              <FormLabel style={{ marginBottom: 0 }}>{t('common.quantity')}</FormLabel>
            </Stack>
          )}
        />
        <Controller
          name={getFieldName('adjustable_quantity.enabled')}
          control={control}
          render={({ field }) => (
            <FormControlLabel
              sx={{ mt: 1, marginLeft: '20px' }}
              control={
                <Checkbox sx={{ ml: 0.5 }} {...field} onChange={(_, checked) => setValue(field.name, checked)} />
              }
              label={t('admin.paymentLink.adjustableQuantity')}
            />
          )}
        />
        {adjustable && (
          <>
            <Stack
              direction="row"
              sx={{
                alignItems: 'center',
                mt: 1,
                ml: 6,
              }}>
              <Typography sx={{ mr: 0.5 }}>Between</Typography>
              <Controller
                name={getFieldName('adjustable_quantity.minimum')}
                control={control}
                rules={{
                  validate: (value) => {
                    return !maxQuantity || Number(value) < Number(maxQuantity) || 'Minimum must be less than maximum';
                  },
                }}
                render={({ field }) => (
                  <TextField
                    sx={{ width: 40 }}
                    size="small"
                    error={!!adjustableError}
                    {...field}
                    slotProps={{
                      htmlInput: { style: { padding: '4px 8px' } },
                    }}
                  />
                )}
              />
              <Typography sx={{ mx: 0.5 }}>and</Typography>
              <Controller
                name={getFieldName('adjustable_quantity.maximum')}
                control={control}
                rules={{
                  validate: (value) => {
                    return (
                      !minQuantity || Number(value) > Number(minQuantity) || 'Maximum must be greater than minimum'
                    );
                  },
                }}
                render={({ field }) => (
                  <TextField
                    sx={{ width: 40 }}
                    size="small"
                    error={!!adjustableError}
                    {...field}
                    slotProps={{
                      htmlInput: { style: { padding: '4px 8px' } },
                    }}
                  />
                )}
              />
            </Stack>
            {adjustableError && (
              <Typography sx={{ mt: 0.5, ml: 6 }} color="error">
                {t('admin.paymentLink.adjustableQuantityError')}
              </Typography>
            )}
          </>
        )}
      </Stack>
      {state.editing && (
        <EditProduct
          product={product}
          loading={state.loading}
          onSave={onSave}
          onCancel={() => setState({ editing: false })}
        />
      )}
    </Box>
  );
}
