/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { api, formatTime, Table, Status } from '@blocklet/payment-react';
import { CircularProgress, Typography } from '@mui/material';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import useBus from 'use-bus';
import { useLocalStorageState, useRequest } from 'ahooks';

import PromotionCodeModal from './create';
import PromotionCodeActions from './actions';
import Copyable from '../../../../components/copyable';

const fetchPromotionCodes = (
  couponId: string,
  params: Record<string, any> = {}
): Promise<{ list: any[]; count: number }> => {
  const search = new URLSearchParams();
  search.set('coupon_id', couponId);
  Object.keys(params).forEach((key) => {
    const value = params[key];
    // Skip empty strings and undefined values
    if (value !== '' && value !== undefined && value !== null) {
      // Handle object parameters like q
      if (typeof value === 'object') {
        // Only add if object has meaningful content
        if (Object.keys(value).length > 0) {
          search.set(key, JSON.stringify(value));
        }
      } else {
        search.set(key, String(value));
      }
    }
  });
  return api.get(`/api/promotion-codes?${search.toString()}`).then((res: any) => res.data);
};

type SearchProps = {
  active?: boolean;
  pageSize: number;
  page: number;
  q?: any;
};

interface Props {
  couponId: string;
}

export default function PromotionCodesList({ couponId }: Props) {
  const { t } = useLocaleContext();
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [selectedCode, setSelectedCode] = useState<any>(null);
  const [search, setSearch] = useLocalStorageState<SearchProps>(`promotion-codes-${couponId}`, {
    defaultValue: {
      pageSize: 20,
      page: 1,
    },
  });
  const {
    data = { list: [], count: 0 },
    refresh,
    loading,
  } = useRequest(() => fetchPromotionCodes(couponId, search), {
    refreshDeps: [search, couponId],
  });

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

  useEffect(() => {
    refresh();
  }, [search, couponId]);

  const handleActionsChange = (action: string, code?: any) => {
    if (action === 'edit' && code) {
      setSelectedCode(code);
      setEditModalOpen(true);
    } else {
      refresh();
    }
  };

  const handleEditModalClose = () => {
    setEditModalOpen(false);
    setSelectedCode(null);
  };

  const promotionCodeList = data?.list || [];
  if (loading) {
    return <CircularProgress />;
  }

  const columns = [
    {
      label: t('admin.promotionCode.code'),
      name: 'code',
      options: {
        filter: true,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          return (
            <Copyable text={item.code}>
              <Link to={`/admin/products/coupons/promotion-codes/${item.id}`}>
                <Typography sx={{ color: 'text.primary', fontWeight: 500, mr: 1 }}>{item.code}</Typography>
              </Link>
            </Copyable>
          );
        },
      },
    },
    {
      label: t('admin.promotionCode.status'),
      name: 'active',
      options: {
        filter: true,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          const isExpired = item.expires_at && Math.floor(Date.now() / 1000) > item.expires_at;
          const isMaxedOut = item.max_redemptions && item.times_redeemed >= item.max_redemptions;

          let status = t('admin.promotionCode.active');
          let color: 'success' | 'warning' | 'default' = 'success';

          if (!item.active) {
            status = t('admin.promotionCode.inactive');
            color = 'default';
          }
          if (isExpired) {
            status = t('admin.promotionCode.expired');
            color = 'warning';
          } else if (isMaxedOut) {
            status = t('admin.promotionCode.maxedOut');
            color = 'warning';
          }

          return <Status label={status} color={color} />;
        },
      },
    },
    {
      label: t('admin.promotionCode.redemptions'),
      name: 'redemptions',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          const maxRedemptions = item.max_redemptions || t('admin.coupon.unlimited');
          const timesRedeemed = item.times_redeemed || 0;
          return `${timesRedeemed} / ${maxRedemptions}`;
        },
      },
    },
    {
      label: t('admin.promotionCode.expires'),
      name: 'expires_at',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          if (item.expires_at) {
            return formatTime(item.expires_at * 1000);
          }
          return '—';
        },
      },
    },
    {
      label: t('admin.promotionCode.created'),
      name: 'created_at',
      options: {
        filter: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          return formatTime(item.created_at);
        },
      },
    },
    {
      label: t('admin.promotionCode.actions'),
      name: 'actions',
      options: {
        filter: false,
        sort: false,
        customBodyRenderLite: (_: string, index: number) => {
          const item = promotionCodeList?.[index];
          return <PromotionCodeActions data={item} onChange={handleActionsChange} variant="compact" />;
        },
      },
    },
  ];

  const onTableChange = ({ page, rowsPerPage }: any) => {
    if (search!.pageSize !== rowsPerPage) {
      setSearch((x: any) => ({ ...x, pageSize: rowsPerPage, page: 1 }));
    } else if (search!.page !== page + 1) {
      setSearch((x: any) => ({ ...x, page: page + 1 }));
    }
  };

  return (
    <>
      <Table
        hasRowLink={false}
        toolbar={false}
        footer={false}
        data={promotionCodeList}
        columns={columns}
        options={{
          count: data?.count,
          page: search!.page - 1,
          rowsPerPage: search!.pageSize,
          onSearchChange: (text: string) => {
            if (text) {
              setSearch({
                ...search!,
                q: {
                  'like-code': text,
                },
                pageSize: 100,
                page: 1,
              });
            } else {
              setSearch({
                ...search!,
                pageSize: 100,
                page: 1,
                q: undefined,
              });
            }
          },
        }}
        loading={loading}
        onChange={onTableChange}
      />

      <PromotionCodeModal
        open={editModalOpen}
        onClose={handleEditModalClose}
        onSubmit={refresh}
        couponId={couponId}
        promotionCode={selectedCode}
        isEditing
      />
    </>
  );
}
