import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { FormInput, FormLabel, Collapse, usePaymentContext } from '@blocklet/payment-react';
import {
  FormControl,
  Select,
  MenuItem,
  Typography,
  Box,
  FormHelperText,
  Stack,
  Radio,
  RadioGroup,
  FormControlLabel,
  Switch,
  Autocomplete,
  TextField,
} from '@mui/material';
import { useFormContext, useWatch, Controller } from 'react-hook-form';
import { InfoOutlined } from '@mui/icons-material';
import { useRequest } from 'ahooks';
import { useState, useMemo } from 'react';
import GraphQLClient from '@ocap/client';

import type { TMeter, TPaymentCurrency } from '@blocklet/payment-types';
import MetadataForm from '../metadata/form';

export type TokenConfig = { name: string; symbol: string; tokenFactoryAddress: string };

type Props = {
  mode?: 'create' | 'edit';
  tokenConfig?: TokenConfig;
  onTokenConfigChange?: (next: TokenConfig) => void;
  paymentCurrency?: TPaymentCurrency;
};

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

function MeterForm({
  mode = 'create',
  tokenConfig = undefined,
  onTokenConfigChange = undefined,
  paymentCurrency = undefined,
}: Props) {
  const { t } = useLocaleContext();
  const {
    register,
    control,
    formState: { errors },
  } = useFormContext<TMeterForm>();

  // 监听聚合方法的变化，用于显示动态帮助信息
  const aggregationMethod = useWatch({
    control,
    name: 'aggregation_method',
    defaultValue: 'sum',
  });

  const creditMode = useWatch({
    control,
    name: 'mode',
    defaultValue: 'OffChain',
  });

  const [tokenType, setTokenType] = useState<'new' | 'existing'>(tokenConfig?.tokenFactoryAddress ? 'existing' : 'new');

  const isEditing = mode === 'edit';
  const { settings } = usePaymentContext();

  // Check if current currency already has token_config
  const hasTokenConfig = !!paymentCurrency?.token_config;

  // Get GraphQL client for arcblock chain
  const arcblockClient = useMemo(() => {
    const arcblockMethod = settings.paymentMethods?.find((m) => m.type === 'arcblock') as any;
    const apiHost = arcblockMethod?.api_host;
    return apiHost ? new GraphQLClient(apiHost) : null;
  }, [settings.paymentMethods]);

  // Fetch tokens created by blocklet owner
  const { data: tokens = [] } = useRequest(
    async () => {
      if (!arcblockClient || !window.blocklet?.appId) {
        return [];
      }
      const result = await arcblockClient.listTokens({
        issuerAddress: window.blocklet.appId,
      });
      return result?.tokens || [];
    },
    {
      refreshDeps: [creditMode, arcblockClient],
      ready: creditMode === 'OnChain' && !hasTokenConfig && !!arcblockClient,
    }
  );

  const getAggregationDescription = (method: string) => {
    const map: Record<string, string> = {
      sum: t('admin.meter.aggregationMethod.sumDescription'),
      count: t('admin.meter.aggregationMethod.countDescription'),
      last: t('admin.meter.aggregationMethod.lastDescription'),
    };
    return map[method] || '';
  };

  return (
    <Box sx={{ maxWidth: 600 }}>
      {/* Header Section */}
      <Box sx={{ mb: 4 }}>
        <Typography
          variant="body2"
          sx={{
            color: 'text.secondary',
          }}>
          {isEditing ? t('admin.meter.editDescription') : t('admin.meter.basicInfoDescription')}
        </Typography>
      </Box>
      <Stack spacing={4}>
        {/* Meter Name */}
        <Box>
          <FormInput
            name="name"
            rules={{
              required: t('admin.meter.name.required'),
              maxLength: {
                value: 64,
                message: t('common.maxLength', { len: 64 }),
              },
            }}
            label={t('admin.meter.name.label')}
            placeholder={t('admin.meter.name.placeholder')}
            error={!!errors.name}
            helperText={errors.name?.message}
            autoFocus
            inputProps={{ maxLength: 64 }}
          />
          <FormHelperText sx={{ mt: 1 }} color="text.secondary">
            {t('admin.meter.name.help')}
          </FormHelperText>
        </Box>

        {/* Event Name - Only in create mode */}
        {!isEditing && (
          <Box>
            <FormInput
              name="event_name"
              rules={{
                required: t('admin.meter.eventName.required'),
                maxLength: {
                  value: 64,
                  message: t('common.maxLength', { len: 64 }),
                },
              }}
              label={t('admin.meter.eventName.label')}
              placeholder={t('admin.meter.eventName.placeholder')}
              error={!!errors.event_name}
              helperText={errors.event_name?.message}
              inputProps={{
                maxLength: 64,
                style: { fontFamily: 'monospace' },
              }}
            />
            <Box sx={{ mt: 1, display: 'flex', alignItems: 'center', gap: 1 }}>
              <InfoOutlined color="info" sx={{ fontSize: 'small' }} />
              <Typography
                variant="caption"
                sx={{
                  color: 'text.secondary',
                }}>
                {t('admin.meter.eventName.help')}
              </Typography>
            </Box>
          </Box>
        )}

        {/* Event Name - Read-only in edit mode */}
        {isEditing && (
          <Box>
            <FormInput
              name="event_name"
              label={t('admin.meter.eventName.label')}
              disabled
              inputProps={{
                style: { fontFamily: 'monospace' },
              }}
            />
            <FormHelperText sx={{ mt: 1 }} color="text.secondary">
              {t('admin.meter.eventName.editHelp')}
            </FormHelperText>
          </Box>
        )}

        {/* Aggregation Method - Only in create mode */}
        {!isEditing && (
          <Box>
            <FormControl fullWidth error={!!errors.aggregation_method}>
              <FormLabel sx={{ color: 'text.primary' }}>{t('admin.meter.aggregationMethod.label')}</FormLabel>
              <Select
                {...register('aggregation_method', { required: t('admin.meter.aggregationMethod.required') })}
                label=""
                defaultValue="sum">
                <MenuItem value="sum">{t('admin.meter.aggregationMethod.sum')}</MenuItem>
                <MenuItem value="count" disabled>
                  {t('admin.meter.aggregationMethod.count')}
                </MenuItem>
                <MenuItem value="last" disabled>
                  {t('admin.meter.aggregationMethod.last')}
                </MenuItem>
              </Select>
            </FormControl>
            <FormHelperText sx={{ mt: 1 }} color="text.secondary">
              {getAggregationDescription(aggregationMethod)}
            </FormHelperText>
          </Box>
        )}

        {/* Aggregation Method - Read-only in edit mode */}
        {isEditing && (
          <Box>
            <FormInput
              name="aggregation_method"
              label={t('admin.meter.aggregationMethod.label')}
              disabled
              value={t(`admin.meter.aggregationMethod.${aggregationMethod}`)}
            />
            <FormHelperText sx={{ mt: 1 }} color="text.secondary">
              {t('admin.meter.aggregationMethod.editHelp')}
            </FormHelperText>
          </Box>
        )}

        {/* Unit - Only in create mode */}
        {!isEditing && (
          <Box>
            <FormInput
              name="unit"
              rules={{
                required: t('admin.meter.unit.required'),
                maxLength: {
                  value: 32,
                  message: t('common.maxLength', { len: 32 }),
                },
              }}
              label={t('admin.meter.unit.label')}
              placeholder={t('admin.meter.unit.placeholder')}
              error={!!errors.unit}
              helperText={errors.unit?.message}
              inputProps={{ maxLength: 32 }}
            />
            <FormHelperText sx={{ mt: 1 }} color="text.secondary">
              {t('admin.meter.unit.help')}
            </FormHelperText>
          </Box>
        )}

        {/* Unit - Read-only in edit mode */}
        {isEditing && (
          <Box>
            <FormInput name="unit" label={t('admin.meter.unit.label')} disabled />
            <FormHelperText sx={{ mt: 1 }} color="text.secondary">
              {t('admin.meter.unit.editHelp')}
            </FormHelperText>
          </Box>
        )}

        {/* Description */}
        <Box>
          <FormInput
            name="description"
            rules={{
              maxLength: {
                value: 255,
                message: t('common.maxLength', { len: 255 }),
              },
            }}
            label={t('admin.meter.description.label')}
            placeholder={t('admin.meter.description.placeholder')}
            multiline
            minRows={3}
            maxRows={5}
            inputProps={{ maxLength: 255 }}
          />
          <FormHelperText sx={{ mt: 1 }} color="text.secondary">
            {t('admin.meter.description.help')}
          </FormHelperText>
        </Box>

        {/* On-chain token configuration */}
        <Box sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
          <Controller
            name="mode"
            control={control}
            render={({ field }) => (
              <Stack direction="row" justifyContent="space-between" alignItems="center">
                <Box>
                  <Typography variant="subtitle1" sx={{ fontWeight: 600 }}>
                    {t('admin.meter.creditMode.onchain')}
                  </Typography>
                  <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
                    {t('admin.meter.creditMode.onChainDescription')}
                  </Typography>
                </Box>
                <Switch
                  checked={hasTokenConfig ? field.value !== 'OffChain' : field.value === 'OnChain'}
                  onChange={(e) => field.onChange(e.target.checked ? 'OnChain' : 'OffChain')}
                />
              </Stack>
            )}
          />

          {(hasTokenConfig || creditMode === 'OnChain') && (
            <Box sx={{ mt: 3, pt: 3, borderTop: '1px solid', borderColor: 'divider' }}>
              <Typography variant="subtitle2" sx={{ mb: 2 }}>
                {t('admin.meter.creditMode.tokenConfiguration')}
              </Typography>
              {!hasTokenConfig && (
                <RadioGroup
                  value={tokenType}
                  onChange={(e) => {
                    setTokenType(e.target.value as any);
                    onTokenConfigChange?.({ name: '', symbol: '', tokenFactoryAddress: '' });
                  }}
                  row>
                  <FormControlLabel
                    value="new"
                    control={<Radio />}
                    label={t('admin.meter.creditMode.createNewToken')}
                  />
                  <FormControlLabel
                    value="existing"
                    control={<Radio />}
                    label={t('admin.meter.creditMode.useExistingToken')}
                  />
                </RadioGroup>
              )}
              {!hasTokenConfig && tokenType === 'new' && tokenConfig && onTokenConfigChange ? (
                <Box sx={{ mt: 2 }}>
                  <TextField
                    value={tokenConfig.name}
                    onChange={(e) => onTokenConfigChange({ ...tokenConfig, name: e.target.value })}
                    fullWidth
                    label={t('admin.meter.creditMode.tokenName')}
                    inputProps={{ maxLength: 64 }}
                    sx={{ mb: 2 }}
                  />
                  <TextField
                    value={tokenConfig.symbol}
                    onChange={(e) => onTokenConfigChange({ ...tokenConfig, symbol: e.target.value.toUpperCase() })}
                    fullWidth
                    label={t('admin.meter.creditMode.tokenSymbol')}
                    inputProps={{ maxLength: 6, style: { textTransform: 'uppercase', fontFamily: 'monospace' } }}
                  />
                </Box>
              ) : (
                <Box sx={{ mt: 2 }}>
                  {hasTokenConfig && paymentCurrency?.token_config ? (
                    <TextField
                      fullWidth
                      label={t('admin.meter.creditMode.selectToken')}
                      value={`${paymentCurrency.token_config.symbol} (${paymentCurrency.token_config.name})`}
                      disabled
                    />
                  ) : (
                    <Autocomplete
                      options={tokens}
                      getOptionLabel={(o: any) => (typeof o === 'string' ? o : `${o.symbol} (${o.name})`)}
                      value={
                        tokens.find((f: any) => f.tokenFactoryAddress === tokenConfig?.tokenFactoryAddress) || null
                      }
                      onChange={(_, v: any) =>
                        onTokenConfigChange?.({
                          name: v?.name || '',
                          symbol: v?.symbol || '',
                          tokenFactoryAddress: v?.tokenFactoryAddress || '',
                        })
                      }
                      renderInput={(params) => (
                        <TextField {...params} label={t('admin.meter.creditMode.selectToken')} />
                      )}
                      renderOption={(props, o: any) => (
                        <li {...props}>
                          <Box>
                            <Typography variant="body1">{o.symbol}</Typography>
                            <Typography variant="caption" color="text.secondary">
                              {o.name}
                            </Typography>
                          </Box>
                        </li>
                      )}
                    />
                  )}
                </Box>
              )}
            </Box>
          )}
        </Box>

        {/* Metadata Section */}
        <Collapse trigger={t('common.metadata.label')}>
          <Box sx={{ mb: 2 }}>
            <Typography
              variant="body2"
              sx={{
                color: 'text.secondary',
              }}>
              {t('common.metadata.description')}
            </Typography>
          </Box>
          <MetadataForm />
        </Collapse>
      </Stack>
    </Box>
  );
}

export default MeterForm;
