/* eslint-disable react/no-unstable-nested-components */
import { getDurableData } from '@arcblock/ux/lib/Datatable';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Status, Table, api, formatTime } from '@blocklet/payment-react';
import { Box, Button, Tooltip, Typography } from '@mui/material';
import { useLocalStorageState, useRequest, useUpdateEffect } from 'ahooks';
import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import useBus from 'use-bus';
import { FlagEmoji } from 'react-international-phone';

import Copyable from '../../../components/copyable';
import TaxRateActions from '../../../components/tax/actions';
import TaxFilterToolbar from '../../../components/tax/filter-toolbar';
import { getTaxCodeInfo, getCountryInfo } from '../../../components/tax/tax-utils';

type SearchProps = {
  page: number;
  pageSize: number;
  active?: string;
  country?: string;
  q?: string;
};

const fetchTaxRates = (params: Record<string, any> = {}): Promise<{ list: any[]; count: number }> => {
  const search = new URLSearchParams();
  Object.keys(params).forEach((key) => {
    const value = params[key];
    if (value === undefined || value === null || value === '') {
      return;
    }
    if (key === 'q' && value) {
      search.set('q', value);
      return;
    }
    search.set(key, String(value));
  });

  return api.get(`/api/tax-rates?${search.toString()}`).then((res: any) => res.data);
};

export default function TaxRatesList() {
  const listKey = 'tax-rates';
  const persisted = getDurableData(listKey);
  const { t } = useLocaleContext();
  const navigate = useNavigate();

  const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
    defaultValue: {
      page: persisted.page ? persisted.page + 1 : 1,
      pageSize: persisted.rowsPerPage || 20,
      active: '',
      country: '',
      q: '',
    },
  });

  const query = useMemo(() => {
    const params: Record<string, any> = {
      page: search?.page,
      pageSize: search?.pageSize,
      sort: '-createdAt', // 按创建时间倒序
    };

    if (search?.active) {
      params.active = search.active === 'active';
    }
    if (search?.country) {
      params.country = search.country;
    }
    if (search?.q) {
      const term = encodeURIComponent(search.q);
      const parts = [
        `like-display_name:${term}`,
        `like-description:${term}`,
        `like-state:${term}`,
        `like-postal_code:${term}`,
        `like-tax_code:${term}`,
        `like-country:${term}`,
        `like-percentage:${term}`,
      ];
      params.q = parts.join(' ');
    }

    return params;
  }, [search]);

  const {
    data = {
      list: [],
      count: 0,
    },
    refresh,
    loading,
  } = useRequest(() => fetchTaxRates(query), {
    refreshDeps: [query],
  });

  useBus('tax-rate.created', () => refresh(), []);
  useBus('tax-rate.updated', () => refresh(), []);
  useBus('tax-rate.deleted', () => refresh(), []);

  useUpdateEffect(() => {
    refresh();
  }, [search?.page, search?.pageSize]);

  const taxRates = data.list || [];
  const { locale } = useLocaleContext();

  const columns = [
    {
      label: t('common.id'),
      name: 'id',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return <Copyable text={item.id} style={{ fontSize: '0.875rem' }} />;
        },
      },
    },
    {
      label: t('admin.taxRate.displayName'),
      name: 'display_name',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return (
            <Button
              variant="text"
              sx={{ p: 0, minWidth: 'unset', textTransform: 'none', textAlign: 'left' }}
              onClick={() => navigate(`/admin/tax/${item.id}`)}>
              {item.display_name}
            </Button>
          );
        },
      },
    },
    {
      label: t('admin.taxRate.location'),
      name: 'location',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          if (!item.country) {
            return '—';
          }

          const countryInfo = getCountryInfo(item.country);
          const parts = [];
          if (item.state) {
            parts.push(item.state);
          }
          if (item.postal_code) {
            parts.push(item.postal_code);
          }

          return (
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
              <FlagEmoji iso2={item.country.toLowerCase()} style={{ width: 24 }} />
              <Typography variant="body2">
                {countryInfo?.name}
                {parts.length > 0 && ` · ${parts.join(' · ')}`}
              </Typography>
            </Box>
          );
        },
      },
    },
    {
      label: t('admin.taxRate.percentage'),
      name: 'percentage',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return `${item.percentage}%`;
        },
      },
    },
    {
      label: t('admin.taxRate.taxCode'),
      name: 'tax_code',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          if (!item.tax_code) {
            return '—';
          }

          const taxCodeInfo = getTaxCodeInfo(item.tax_code, locale);
          if (!taxCodeInfo) {
            return item.tax_code;
          }

          return (
            <Tooltip title={taxCodeInfo.description} arrow>
              <Box>
                <Typography variant="body2" sx={{ fontWeight: 500 }}>
                  {taxCodeInfo.name}
                </Typography>
                <Typography
                  variant="caption"
                  sx={{
                    color: 'text.secondary',
                  }}>
                  {taxCodeInfo.id}
                </Typography>
              </Box>
            </Tooltip>
          );
        },
      },
    },
    {
      label: t('admin.taxRate.relatedInvoiceNum'),
      name: 'invoice_count',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          const count = Number(item.invoice_count) || 0;

          return (
            <Typography
              variant="body2"
              sx={{
                color: count > 0 ? 'text.primary' : 'text.secondary',
              }}>
              {count > 0 ? count : t('admin.taxRate.notUsed')}
            </Typography>
          );
        },
      },
    },
    {
      label: t('common.status'),
      name: 'active',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return (
            <Status
              label={item.active ? t('common.active') : t('common.inactive')}
              color={item.active ? 'success' : 'default'}
            />
          );
        },
      },
    },
    {
      label: t('common.createdAt'),
      name: 'created_at',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return formatTime(item.created_at);
        },
      },
    },
    {
      label: t('common.actions'),
      name: 'actions',
      width: 80,
      options: {
        sort: false,
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = taxRates[index];
          return <TaxRateActions data={item} onChange={() => refresh()} />;
        },
      },
    },
  ];

  const handleTableChange = ({ page, rowsPerPage }: any) => {
    if (search!.pageSize !== rowsPerPage) {
      setSearch((prev) => ({ ...(prev || {}), page: 1, pageSize: rowsPerPage }));
    } else if (search!.page !== page + 1) {
      // @ts-ignore
      setSearch((prev) => ({ ...(prev || {}), page: page + 1 }));
    }
  };

  const handleSearchChange = (value: string) => {
    // @ts-ignore
    setSearch((prev) => ({
      ...(prev || {}),
      q: value,
      page: 1,
    }));
  };

  const handleFilterChange = (key: keyof SearchProps, value: string) => {
    // @ts-ignore
    setSearch((prev) => ({
      ...(prev || {}),
      [key]: value,
      page: 1,
    }));
  };

  const title = (
    <TaxFilterToolbar
      search={search}
      onFilterChange={(key, value) => handleFilterChange(key as keyof SearchProps, value)}
    />
  );

  return (
    <Table
      hasRowLink={false}
      durable={`__${listKey}__`}
      durableKeys={['page', 'rowsPerPage', 'searchText']}
      title={title}
      data={taxRates}
      columns={columns}
      loading={loading}
      options={{
        count: data.count,
        page: (search?.page || 1) - 1,
        rowsPerPage: search?.pageSize || 20,
        onSearchChange: handleSearchChange,
      }}
      onChange={handleTableChange}
      mobileTDFlexDirection="row"
    />
  );
}
