import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { api, formatError, formatTime, useMobile } from '@blocklet/payment-react';
import { ArrowBackOutlined, EditOutlined } 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 { useNavigate } from 'react-router-dom';
import { useForm, FormProvider } from 'react-hook-form';

import type { TPaymentCurrency, TMeter } from '@blocklet/payment-types';
import Copyable from '../../../../components/copyable';
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 MeterActions from '../../../../components/meter/actions';
import SectionHeader from '../../../../components/section/header';
import { goBackOrFallback } from '../../../../libs/util';
import MeterEventsList from '../../../../components/meter/events-list';
import MeterProducts from '../../../../components/meter/products';
import MeterForm, { type TokenConfig } from '../../../../components/meter/form';
import DrawerForm from '../../../../components/drawer-form';

const getMeter = (id: string): Promise<TMeter & { paymentCurrency: TPaymentCurrency }> => {
  return api.get(`/api/meters/${id}`).then((res: any) => res.data);
};

export default function MeterDetail(props: { id: string }) {
  const { t } = useLocaleContext();
  const { isMobile } = useMobile();
  const navigate = useNavigate();

  // 获取聚合方法的简洁描述
  const getAggregationMethodHint = (method: string) => {
    switch (method) {
      case 'sum':
        return t('admin.meter.aggregationMethod.sumHint');
      case 'count':
        return t('admin.meter.aggregationMethod.countHint');
      case 'last':
        return t('admin.meter.aggregationMethod.lastHint');
      default:
        return '';
    }
  };
  const [state, setState] = useSetState({
    editing: {
      metadata: false,
      meter: false,
    },
    loading: {
      metadata: false,
      meter: false,
    },
    creating: {
      product: false,
      creditProduct: false,
    },
    tokenConfig: { name: '', symbol: '', tokenFactoryAddress: '' } as TokenConfig,
  });

  type TMeterForm = TMeter & {
    mode?: 'OffChain' | 'OnChain';
  };

  const methods = useForm<TMeterForm>({
    defaultValues: {
      name: '',
      event_name: '',
      aggregation_method: 'sum',
      unit: '',
      description: '',
      metadata: {},
      mode: 'OffChain',
    },
  });

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

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

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

  const onUpdateMetadata = async (updates: any) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, metadata: true } }));
      await api.put(`/api/meters/${props.id}`, updates);
      Toast.success(t('common.saved'));
      runAsync();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
    } finally {
      setState((prev) => ({ loading: { ...prev.loading, metadata: false } }));
    }
  };

  const onChange = (action?: string) => {
    if (action === 'delete') {
      navigate('/admin/billing/meters');
    } else {
      runAsync();
    }
  };

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

  const handleEditMeter = () => {
    const hasTokenConfig = !!data.paymentCurrency?.token_config;
    // 设置表单默认值
    methods.reset({
      name: data.name,
      event_name: data.event_name,
      aggregation_method: data.aggregation_method,
      unit: data.unit,
      description: data.description || '',
      metadata: data.metadata || {},
      mode: hasTokenConfig ? 'OnChain' : 'OffChain',
    });
    setState((prev) => ({
      editing: { ...prev.editing, meter: true },
      tokenConfig: { name: '', symbol: '', tokenFactoryAddress: '' },
    }));
  };

  const onUpdateMeter = async (formData: TMeterForm) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, meter: true } }));

      const currencyId = data.paymentCurrency?.id;
      const hasTokenConfig = !!data.paymentCurrency?.token_config;

      // If enabling on-chain and no token_config yet
      if (currencyId && !hasTokenConfig && formData.mode === 'OnChain') {
        let { tokenFactoryAddress } = state.tokenConfig;

        // Create new token if not using existing
        if (!tokenFactoryAddress && state.tokenConfig.symbol) {
          const { data: factory } = await api.post('/api/credit-tokens', {
            name: state.tokenConfig.name,
            symbol: state.tokenConfig.symbol,
          });
          tokenFactoryAddress = factory.address;
        }

        // Update currency with token_config
        if (tokenFactoryAddress) {
          await api.put(`/api/payment-currencies/${currencyId}/token-config`, {
            token_factory_address: tokenFactoryAddress,
          });
        }
      }

      // If disabling on-chain and has token_config, remove it
      if (currencyId && hasTokenConfig && formData.mode === 'OffChain') {
        await api.delete(`/api/payment-currencies/${currencyId}/token-config`);
      }

      // Clean up frontend-only fields before sending
      delete formData.mode;

      // Update meter basic info
      await api.put(`/api/meters/${props.id}`, formData);

      Toast.success(t('admin.meter.saved'));
      setState((prev) => ({ editing: { ...prev.editing, meter: false } }));
      runAsync();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
    } finally {
      setState((prev) => ({ loading: { ...prev.loading, meter: false } }));
    }
  };

  return (
    <Root direction="column" spacing={2.5} sx={{ mb: 4 }}>
      <Box>
        {data.status === 'inactive' && (
          <Alert severity="warning" sx={{ mb: 2 }}>
            <AlertTitle>{t('admin.meter.inactive')}</AlertTitle>
            {t('admin.meter.inactiveTip')}
          </Alert>
        )}
        <Stack
          className="page-header"
          direction="row"
          sx={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}>
          <Stack
            direction="row"
            onClick={() => goBackOrFallback('/admin/meters')}
            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.meters')}
            </Typography>
          </Stack>
          <MeterActions data={data} variant="normal" onChange={onChange} />
        </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="row"
            sx={{
              justifyContent: 'space-between',
              alignItems: 'center',
            }}>
            <Stack
              direction="row"
              spacing={1}
              sx={{
                alignItems: 'center',
              }}>
              <Stack
                direction="column"
                sx={{
                  alignItems: 'flex-start',
                  justifyContent: 'space-around',
                }}>
                <Typography
                  variant="h2"
                  sx={{
                    color: 'text.primary',
                  }}>
                  {data.name}
                </Typography>
                <Typography
                  variant="subtitle1"
                  sx={{
                    color: 'text.lighter',
                  }}>
                  {data.event_name} • {data.unit}
                </Typography>
              </Stack>
            </Stack>
          </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('common.id')} value={<Copyable text={props.id} style={{ marginLeft: 4 }} />} divider />
            <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider />
            {data.paymentCurrency?.recharge_config?.base_price_id && (
              <InfoMetric
                label={t('admin.meter.rechargePackage.priceId')}
                tip={t('admin.meter.rechargePackage.tooltip', {
                  name: data.paymentCurrency.name,
                })}
                value={
                  <Button
                    variant="text"
                    size="small"
                    onClick={() => navigate(`/admin/products/${data.paymentCurrency.recharge_config!.base_price_id}`)}
                    sx={{ p: 0, minWidth: 'auto', textAlign: 'left', ml: 0.5, color: 'text.link' }}>
                    {data.paymentCurrency.recharge_config!.base_price_id}
                  </Button>
                }
                divider
              />
            )}
          </Stack>
        </Box>
        <Divider />
      </Box>
      <Stack
        sx={{
          flexDirection: {
            xs: 'column',
            lg: 'row',
          },
          gap: {
            xs: 2.5,
            md: 4,
          },
          '.meter-column-1': {
            minWidth: {
              xs: '100%',
              lg: '600px',
            },
          },
          '.meter-column-2': {
            width: {
              xs: '100%',
              md: '100%',
              lg: '320px',
            },
            maxWidth: {
              xs: '100%',
              md: '33%',
            },
          },
        }}>
        <Box
          className="meter-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' }}
                disabled={state.editing.meter}
                onClick={handleEditMeter}>
                {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.meter.name.label')} value={data.name} />
              <InfoRow label={t('admin.meter.eventName.label')} value={data.event_name} />
              <InfoRow label={t('admin.meter.aggregationMethod.label')} value={data.aggregation_method} />
              <InfoRow label={t('admin.meter.unit.label')} value={data.unit} />
              <InfoRow label={t('admin.meter.description.label')} value={data.description || '-'} />
              <InfoRow label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
            </InfoRowGroup>
          </Box>
          <Divider />

          <Box className="section">
            <SectionHeader title={t('admin.meter.events.title')} />
            <Box className="section-body">
              <MeterEventsList meterId={data.id} paymentCurrency={data.paymentCurrency} />
            </Box>
          </Box>
          <Divider />

          <Box className="section">
            <Box
              sx={{
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
              }}>
              <SectionHeader title={t('admin.meter.products.title')} />
            </Box>
            <Box className="section-body">
              <MeterProducts meterId={data.id} meter={data} />
            </Box>
          </Box>
        </Box>
        {isMobile && <Divider />}
        <Box className="meter-column-2" sx={{ gap: 2.5, display: 'flex', flexDirection: 'column' }}>
          <Box className="section">
            <SectionHeader title={t('admin.meter.usageGuide.title')} />
            <Box className="section-body">
              <Alert severity="info" sx={{ mb: 2 }}>
                <Typography variant="body2">
                  {t('admin.meter.usageGuide.tip', {
                    eventName: data.event_name,
                    aggregationMethodHint: getAggregationMethodHint(data.aggregation_method),
                    unit: data.unit,
                  })}
                </Typography>
              </Alert>
            </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>
      {/* 编辑计量器表单 */}
      {state.editing.meter && (
        <DrawerForm
          icon={<EditOutlined />}
          text={t('admin.meter.edit')}
          open={state.editing.meter}
          onClose={() => setState((prev) => ({ editing: { ...prev.editing, meter: false } }))}
          width={640}
          addons={
            <Button
              variant="contained"
              size="small"
              disabled={state.loading.meter}
              onClick={methods.handleSubmit(onUpdateMeter)}>
              {t('admin.meter.save')}
            </Button>
          }>
          <FormProvider {...methods}>
            <MeterForm
              mode="edit"
              paymentCurrency={data.paymentCurrency}
              tokenConfig={state.tokenConfig}
              onTokenConfigChange={(next) => setState({ tokenConfig: next })}
            />
          </FormProvider>
        </DrawerForm>
      )}
    </Root>
  );
}

const Root = styled(Stack)``;
