import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import {
  api,
  formatError,
  formatPrice,
  formatRecurring,
  formatTime,
  Table,
  useMobile,
  isCreditMetered,
} from '@blocklet/payment-react';
import type { PriceRecurring, TPrice, TPriceExpanded } from '@blocklet/payment-types';
import { ArrowBackOutlined } from '@mui/icons-material';
import { Alert, AlertTitle, Box, Button, CircularProgress, Divider, Stack, Typography } from '@mui/material';
import { styled } from '@mui/system';
import { useRequest, useSetState } from 'ahooks';
import { Link, useNavigate } from 'react-router-dom';

import { dispatch } from 'use-bus';
import Copyable from '../../../../components/copyable';
import Currency from '../../../../components/currency';
import EventList from '../../../../components/event/list';
import InfoMetric from '../../../../components/info-metric';
import InfoRow from '../../../../components/info-row';
import InfoRowGroup from '../../../../components/info-row-group';
import MetadataEditor from '../../../../components/metadata/editor';
import MetadataList from '../../../../components/metadata/list';
import PriceUpsell from '../../../../components/price/upsell';
import EditPrice from '../../../../components/product/edit-price';
import SectionHeader from '../../../../components/section/header';
import { goBackOrFallback } from '../../../../libs/util';
import PriceActions from './actions';

const fetchData = (id: string): Promise<TPriceExpanded> => {
  return api.get(`/api/prices/${id}`).then((res: any) => res.data);
};

export default function PriceDetail(props: { id: string }) {
  const { t, locale } = useLocaleContext();
  const { isMobile } = useMobile();
  const navigate = useNavigate();
  const [state, setState] = useSetState({
    adding: {
      price: false,
    },
    editing: {
      metadata: false,
      price: false,
    },
    loading: {
      metadata: false,
      price: false,
    },
  });

  const { loading, error, data, runAsync } = useRequest(() => fetchData(props.id));

  if (error) {
    return <Alert severity="error">{error.message}</Alert>;
  }

  if (loading || !data) {
    return <CircularProgress />;
  }

  const createUpdater = (key: string) => async (updates: TPrice) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, [key]: true } }));
      await api.put(`/api/prices/${props.id}`, updates).then((res: any) => res.data);
      Toast.success(t('common.saved'));
      dispatch('price.updated');
      runAsync();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
      throw err;
    } finally {
      setState((prev) => ({ loading: { ...prev.loading, [key]: false } }));
    }
  };

  const onUpdateMetadata = createUpdater('metadata');
  const onUpdateAll = createUpdater('price');
  const onChange = (action: string) => {
    if (action === 'remove') {
      navigate('/admin/products');
    } else {
      runAsync();
    }
  };

  const handleEditMetadata = () => {
    setState((prev) => ({ editing: { ...prev.editing, metadata: true } }));
  };

  const renderType = (type: string) => {
    if (type === 'recurring') {
      return t('admin.price.types.recurring');
    }
    if (type === 'one_time') {
      return t('admin.price.types.onetime');
    }
    return type;
  };

  return (
    <Root direction="column" spacing={2.5} sx={{ mb: 4 }}>
      <Box>
        {data.active === false && (
          <Alert severity="warning">
            <AlertTitle>{t('admin.price.archived')}</AlertTitle>
            {t('admin.price.archivedTip')}
          </Alert>
        )}
        {data.locked && (
          <Alert severity="warning" sx={{ mb: 1 }}>
            {t('admin.price.locked')}
          </Alert>
        )}
        <Stack
          className="page-header"
          direction="row"
          sx={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}>
          <Stack
            direction="row"
            onClick={() => goBackOrFallback(`/admin/products/${data.product_id}`)}
            sx={{
              alignItems: 'center',
              fontWeight: 'normal',
              cursor: 'pointer',
            }}>
            <ArrowBackOutlined fontSize="small" sx={{ mr: 0.5, color: 'text.secondary' }} />
            <Typography variant="h6" sx={{ color: 'text.secondary', fontWeight: 'normal' }}>
              {t('admin.products')}
            </Typography>
          </Stack>
          <PriceActions data={data} onChange={onChange} variant="normal" />
        </Stack>
        <Box
          sx={{
            mt: 4,
            mb: 3,
            display: 'flex',

            gap: {
              xs: 2,
              sm: 2,
              md: 5,
            },

            flexWrap: 'wrap',

            flexDirection: {
              xs: 'column',
              sm: 'column',
              md: 'row',
            },

            alignItems: {
              xs: 'flex-start',
              sm: 'flex-start',
              md: 'center',
            },
          }}>
          <Stack
            direction="column"
            sx={{
              gap: 1,
            }}>
            <Typography
              variant="h2"
              sx={{
                fontWeight: 600,
              }}>
              Price for {data.product.name}
            </Typography>
            <Copyable text={props.id} style={{ marginLeft: 4 }} />
          </Stack>
          <Stack
            className="section-body"
            sx={{
              justifyContent: 'flex-start',
              flexWrap: 'wrap',

              'hr.MuiDivider-root:last-child': {
                display: 'none',
              },

              flexDirection: {
                xs: 'column',
                sm: 'column',
                md: 'row',
              },

              alignItems: 'flex-start',

              gap: {
                xs: 1,
                sm: 1,
                md: 3,
              },
            }}>
            <InfoMetric
              label={t('admin.price.amount')}
              value={formatPrice(data, data.currency, data.product.unit_label, 1, true, locale)}
              divider
            />
            <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider />
            <InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
          </Stack>
        </Box>
        <Divider />
      </Box>
      <Stack
        sx={{
          flexDirection: {
            xs: 'column',
            lg: 'row',
          },
          gap: {
            xs: 2.5,
            md: 4,
          },
          '.payment-link-column-1': {
            minWidth: {
              xs: '100%',
              lg: '600px',
            },
          },
          '.payment-link-column-2': {
            width: {
              xs: '100%',
              md: '100%',
              lg: '320px',
            },
            maxWidth: {
              xs: '100%',
              md: '33%',
            },
          },
        }}>
        <Box
          className="payment-link-column-1"
          sx={{
            flex: 1,
            gap: 2.5,
            display: 'flex',
            flexDirection: 'column',
          }}>
          <Box className="section" sx={{ containerType: 'inline-size' }}>
            <SectionHeader title={t('admin.details')}>
              <Button
                variant="text"
                color="inherit"
                size="small"
                sx={{ color: 'text.link' }}
                onClick={() => setState((prev) => ({ editing: { ...prev.editing, price: true } }))}>
                {t('common.edit')}
              </Button>
            </SectionHeader>
            <InfoRowGroup
              sx={{
                display: 'grid',
                gridTemplateColumns: {
                  xs: 'repeat(1, 1fr)',
                  xl: 'repeat(2, 1fr)',
                },
                '@container (min-width: 1000px)': {
                  gridTemplateColumns: 'repeat(2, 1fr)',
                },
                '.info-row-wrapper': {
                  gap: 1,
                  flexDirection: {
                    xs: 'column',
                    xl: 'row',
                  },
                  alignItems: {
                    xs: 'flex-start',
                    xl: 'center',
                  },
                  '@container (min-width: 1000px)': {
                    flexDirection: 'row',
                    alignItems: 'center',
                  },
                },
              }}>
              <InfoRow label={t('admin.price.type')} value={renderType(data.type)} />
              {data.type === 'recurring' && (
                <InfoRow
                  label={t('admin.price.recurring.interval')}
                  value={formatRecurring(data.recurring as PriceRecurring, true, 'per', locale)}
                />
              )}
              <InfoRow label={t('admin.price.lookupKey')} value={data.lookup_key} />
              <InfoRow label={t('admin.price.nickname.label')} value={data.nickname} />
              {state.editing.price && (
                <EditPrice
                  // @ts-ignore
                  price={data}
                  loading={state.loading.price}
                  onSave={onUpdateAll}
                  onCancel={() => setState((prev) => ({ editing: { ...prev.editing, price: false } }))}
                />
              )}
            </InfoRowGroup>
          </Box>

          <Divider />
          {data.metadata?.credit_config && (
            <>
              <Box className="section">
                <SectionHeader title={t('admin.creditProduct.configTitle')} />
                <InfoRowGroup
                  sx={{
                    display: 'grid',
                    gridTemplateColumns: {
                      xs: 'repeat(1, 1fr)',
                      xl: 'repeat(2, 1fr)',
                    },
                    '@container (min-width: 1000px)': {
                      gridTemplateColumns: 'repeat(2, 1fr)',
                    },
                    '.info-row-wrapper': {
                      gap: 1,
                      flexDirection: {
                        xs: 'column',
                        xl: 'row',
                      },
                      alignItems: {
                        xs: 'flex-start',
                        xl: 'center',
                      },
                      '@container (min-width: 1000px)': {
                        flexDirection: 'row',
                        alignItems: 'center',
                      },
                    },
                  }}>
                  {(() => {
                    const creditConfig = data.metadata.credit_config;
                    const isScheduleEnabled = creditConfig.schedule?.enabled;
                    const creditCurrencyItem = data.currency_options?.find(
                      (item: any) => item.currency_id === creditConfig.currency_id
                    );
                    const creditCurrency = creditCurrencyItem ? (creditCurrencyItem as any).currency : null;

                    return (
                      <>
                        {/* 周期性发放的字段 */}
                        {isScheduleEnabled &&
                          creditConfig.schedule?.interval_value &&
                          creditConfig.schedule?.interval_unit && (
                            <InfoRow
                              label={t('admin.creditProduct.schedule.interval.label')}
                              value={`${t('common.every')} ${creditConfig.schedule.interval_value} ${t(`admin.creditProduct.schedule.interval.${creditConfig.schedule.interval_unit}`)}`}
                            />
                          )}
                        {isScheduleEnabled && creditConfig.schedule?.amount_per_grant && (
                          <InfoRow
                            label={t('admin.creditProduct.schedule.amountPerGrant.label')}
                            value={
                              creditCurrency ? (
                                <Stack direction="row" spacing={0.5} alignItems="center">
                                  <span>{creditConfig.schedule.amount_per_grant}</span>
                                  <Currency logo={creditCurrency.logo} name={creditCurrency.symbol} size={16} />
                                </Stack>
                              ) : (
                                creditConfig.schedule.amount_per_grant
                              )
                            }
                          />
                        )}
                        {/* 一次性发放的字段 */}
                        {!isScheduleEnabled && creditConfig.credit_amount && (
                          <InfoRow
                            label={t('admin.creditProduct.creditAmount.label')}
                            value={
                              creditCurrency ? (
                                <Stack direction="row" spacing={0.5} alignItems="center">
                                  <span>{creditConfig.credit_amount}</span>
                                  <Currency logo={creditCurrency.logo} name={creditCurrency.symbol} size={16} />
                                </Stack>
                              ) : (
                                creditConfig.credit_amount
                              )
                            }
                          />
                        )}
                        {/* 过期时间 */}
                        <InfoRow
                          label={t('admin.creditProduct.expirationTime.label')}
                          value={(() => {
                            if (isScheduleEnabled && creditConfig.schedule?.expire_with_next_grant) {
                              return t('admin.creditProduct.expirationTime.expireWithNextGrant');
                            }
                            const durationValue = creditConfig.valid_duration_value;
                            const durationUnit = creditConfig.valid_duration_unit;
                            if (durationValue && durationValue > 0 && durationUnit) {
                              return `${durationValue} ${t(`admin.creditProduct.validDuration.${durationUnit}`)}`;
                            }
                            return '-';
                          })()}
                        />
                        {/* 使用优先级 */}
                        {creditConfig.priority !== undefined && (
                          <InfoRow label={t('admin.creditProduct.priority.label')} value={creditConfig.priority} />
                        )}
                        {/* 关联价格 */}
                        {creditConfig.applicable_prices && creditConfig.applicable_prices.length > 0 && (
                          <InfoRow
                            label={t('admin.creditProduct.associatedPrices.label')}
                            value={creditConfig.applicable_prices.length}
                          />
                        )}
                      </>
                    );
                  })()}
                </InfoRowGroup>
              </Box>
              <Divider />
            </>
          )}
          {isCreditMetered(data) && (
            <>
              <Box className="section">
                <SectionHeader title={t('admin.meters')} />
                <Box className="section-body">
                  <InfoRow
                    label={t('admin.meter.eventName.label')}
                    value={
                      <Link to={`/admin/billing/${data.meter?.id}`} target="_blank">
                        {data.meter?.event_name}
                      </Link>
                    }
                  />
                </Box>
              </Box>
              <Divider />
            </>
          )}
          <Box className="section">
            <SectionHeader title={t('admin.price.currency.list')} />
            <Box className="section-body">
              <TableRoot>
                <Table
                  toolbar={false}
                  footer={false}
                  data={data.currency_options}
                  columns={[
                    {
                      label: t('admin.price.name'),
                      name: 'currency_id',
                      width: 200,
                      options: {
                        // eslint-disable-next-line react/no-unstable-nested-components
                        customBodyRenderLite: (_: any, index: number) => {
                          const item = data.currency_options[index] as any;
                          return <Currency logo={item.currency?.logo} name={item.currency?.symbol} />;
                        },
                      },
                    },
                    {
                      label: t('common.amount'),
                      name: 'unit_amount',
                      options: {
                        customBodyRenderLite: (_: any, index: number) => {
                          const item = data.currency_options[index] as any;
                          return formatPrice(
                            {
                              id: data.id,
                              currency_id: item.currency_id,
                              type: data.type,
                              unit_amount: item.unit_amount,
                              custom_unit_amount: item.custom_unit_amount,
                              recurring: data.recurring,
                            } as TPrice,
                            item.currency,
                            data.product.unit_label,
                            1,
                            true,
                            locale
                          );
                        },
                      },
                    },
                  ]}
                  options={{
                    count: data.currency_options.length,
                    page: 0,
                    rowsPerPage: 20,
                  }}
                  mobileTDFlexDirection="row"
                />
              </TableRoot>
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.events.title')} />
            <Box className="section-body">
              <EventList features={{ toolbar: false }} object_id={data.id} />
            </Box>
          </Box>
        </Box>
        {isMobile && <Divider />}
        <Box className="payment-link-column-2" sx={{ gap: 2.5, display: 'flex', flexDirection: 'column' }}>
          <Box className="section">
            <SectionHeader title={t('admin.price.upsell.title')} />
            <Box className="section-body">
              <PriceUpsell data={data} onChange={runAsync} />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('common.metadata.label')}>
              <Button
                variant="text"
                color="inherit"
                size="small"
                sx={{ color: 'text.link' }}
                disabled={state.editing.metadata}
                onClick={handleEditMetadata}>
                {t('common.edit')}
              </Button>
            </SectionHeader>
            <Box className="section-body">
              <MetadataList data={data.metadata} handleEditMetadata={handleEditMetadata} />
              {state.editing.metadata && (
                <MetadataEditor
                  data={data}
                  loading={state.loading.metadata}
                  onSave={onUpdateMetadata}
                  onCancel={() => setState((prev) => ({ editing: { ...prev.editing, metadata: false } }))}
                />
              )}
            </Box>
          </Box>
        </Box>
      </Stack>
    </Root>
  );
}

const Root = styled(Stack)``;
const TableRoot = styled(Box)`
  @media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
    .MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > .MuiTableCell-root {
      > div {
        width: fit-content;
        flex: inherit;
        font-size: 14px;
      }
    }
  }
`;
