import {
  createProduct,
  deleteProduct,
  getProductDetail,
  getProductList,
  updateProduct,
  updateProductStatus,
} from '@/services/product';
import {
  ExclamationCircleOutlined,
  PlusOutlined,
  ShoppingCartOutlined,
} from '@ant-design/icons';
import {
  ActionType,
  PageContainer,
  ProFormInstance,
  ProTable,
} from '@ant-design/pro-components';
import { Access, useAccess, useIntl, useRequest } from '@umijs/max';
import { Button, message, Modal, Space, theme } from 'antd';
import React, { useMemo, useRef, useState } from 'react';
import { createProductColumns } from './columns';
import ProductFormModal from './components/ProductFormModal';
import ProductSearch from './components/ProductSearch';
import {
  getCategoryOptions,
  getStatusValueEnum,
  hasCoreFieldChanged,
} from './constants';
import type {
  ProductFormValues,
  ProductItem,
  ProductListResponse,
  ProductSearchValues,
  ProductStatus,
  ProductStatusUpdatePayload,
} from './data';

const ProductList: React.FC = () => {
  const [messageApi, messageContextHolder] = message.useMessage();
  const [modalApi, modalContextHolder] = Modal.useModal();
  const intl = useIntl();
  const access = useAccess();
  const { token } = theme.useToken();
  const actionRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance<ProductFormValues>>();

  const [searchValues, setSearchValues] = useState<ProductSearchValues>({});
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [modalOpen, setModalOpen] = useState<boolean>(false);
  const [editingId, setEditingId] = useState<string>();
  const [currentRow, setCurrentRow] = useState<ProductItem | undefined>();
  const [detailLoading, setDetailLoading] = useState<boolean>(false);

  const statusEnum = useMemo(() => getStatusValueEnum(intl), [intl]);
  const categoryOptions = useMemo(
    () =>
      (getCategoryOptions(intl) as
        | { label: string; value: string }[]
        | undefined) || [],
    [intl],
  );

  const { run: runGetList } = useRequest<
    ProductListResponse,
    [ProductSearchValues & { current?: number; pageSize?: number }]
  >(
    async (params) => {
      const response = await getProductList(params);
      if (Array.isArray(response)) {
        return {
          data: response,
          total: response.length,
          success: true,
        };
      }
      return response as ProductListResponse;
    },
    { manual: true },
  );
  const { run: runCreate, loading: createLoading } = useRequest(createProduct, {
    manual: true,
  });
  const { run: runUpdate, loading: updateLoading } = useRequest(updateProduct, {
    manual: true,
  });
  const { run: runDelete, loading: deleteLoading } = useRequest(deleteProduct, {
    manual: true,
  });
  const { run: runUpdateStatus, loading: updateStatusLoading } = useRequest(
    updateProductStatus,
    { manual: true },
  );

  const openCreateModal = () => {
    setEditingId(undefined);
    setCurrentRow(undefined);
    formRef.current?.resetFields();
    formRef.current?.setFieldsValue({ status: 'draft' });
    setModalOpen(true);
  };

  const openEditModal = async (record: ProductItem) => {
    setCurrentRow(record);
    setEditingId(record.id);
    setModalOpen(true);
    formRef.current?.setFieldsValue(record);

    try {
      setDetailLoading(true);
      const detail = (await getProductDetail(record.id)) as ProductItem;
      formRef.current?.setFieldsValue(detail);
      setCurrentRow(detail);
    } catch {
      messageApi.error(
        intl.formatMessage({
          id: 'common.error.loadDetail',
          defaultMessage: '详情加载失败',
        }),
      );
    } finally {
      setDetailLoading(false);
    }
  };

  const handleDelete = (record: ProductItem) => {
    if (!access.canDeleteProduct(record)) {
      messageApi.warning(
        intl.formatMessage({
          id: 'pages.product.delete.denied',
          defaultMessage: '仅草稿和已下架商品可删除',
        }),
      );
      return;
    }

    modalApi.confirm({
      title: intl.formatMessage({
        id: 'common.confirm.delete',
        defaultMessage: '确认删除吗？',
      }),
      icon: <ExclamationCircleOutlined />,
      content: record.name,
      okType: 'danger',
      okButtonProps: { loading: deleteLoading, disabled: deleteLoading },
      cancelButtonProps: { disabled: deleteLoading },
      okText: intl.formatMessage({ id: 'common.ok', defaultMessage: '确定' }),
      cancelText: intl.formatMessage({
        id: 'common.cancel',
        defaultMessage: '取消',
      }),
      async onOk() {
        try {
          await runDelete(record.id);
          messageApi.success(
            intl.formatMessage({
              id: 'common.success.delete',
              defaultMessage: '删除成功',
            }),
          );
          actionRef.current?.reload();
        } catch {
          messageApi.error(
            intl.formatMessage({
              id: 'common.error.delete',
              defaultMessage: '删除失败',
            }),
          );
        }
      },
    });
  };

  const handleBatchStatus = async (
    status: Extract<ProductStatus, 'online' | 'offline'>,
  ) => {
    if (selectedRowKeys.length === 0) {
      messageApi.warning(
        intl.formatMessage({
          id: 'pages.product.batch.empty',
          defaultMessage: '请先选择商品',
        }),
      );
      return;
    }

    const payload: ProductStatusUpdatePayload = {
      ids: selectedRowKeys.map((key) => String(key)),
      status,
    };

    try {
      await runUpdateStatus(payload);
      messageApi.success(
        intl.formatMessage({
          id: 'pages.product.batch.success',
          defaultMessage: '批量状态更新成功',
        }),
      );
      setSelectedRowKeys([]);
      actionRef.current?.reload();
    } catch {
      messageApi.error(
        intl.formatMessage({
          id: 'common.error.update',
          defaultMessage: '更新失败',
        }),
      );
    }
  };

  const columns = useMemo(
    () =>
      createProductColumns({
        intl,
        statusEnum,
        categoryOptions,
        canEdit: Boolean(access.canEditProduct),
        canDelete: access.canDeleteProduct,
        errorColor: token.colorError,
        onEdit: openEditModal,
        onDelete: handleDelete,
      }),
    [
      access.canDeleteProduct,
      access.canEditProduct,
      categoryOptions,
      handleDelete,
      intl,
      openEditModal,
      statusEnum,
      token.colorError,
    ],
  );

  return (
    <>
      {messageContextHolder}
      {modalContextHolder}
      <PageContainer
        title={intl.formatMessage({
          id: 'pages.product.title',
          defaultMessage: '商品管理列表',
        })}
      >
        <ProductSearch
          intl={intl}
          categoryOptions={categoryOptions}
          statusEnum={statusEnum}
          onFinish={setSearchValues}
        />

        <ProTable<ProductItem, ProductSearchValues>
          actionRef={actionRef}
          rowKey="id"
          columns={columns}
          params={searchValues}
          search={false}
          headerTitle={
            <Space>
              <ShoppingCartOutlined style={{ color: token.colorPrimary }} />
              <span>
                {intl.formatMessage({
                  id: 'pages.product.table.title',
                  defaultMessage: '商品列表',
                })}
              </span>
            </Space>
          }
          rowSelection={{
            selectedRowKeys,
            onChange: (keys) => setSelectedRowKeys(keys),
          }}
          toolBarRender={() => [
            <Access
              key="batch-online"
              accessible={Boolean(access.canBatchUpdateProductStatus)}
              fallback={null}
            >
              <Button
                onClick={() => handleBatchStatus('online')}
                loading={updateStatusLoading}
                disabled={updateStatusLoading || selectedRowKeys.length === 0}
              >
                {intl.formatMessage({
                  id: 'pages.product.batch.online',
                  defaultMessage: '批量上架',
                })}
              </Button>
            </Access>,
            <Access
              key="batch-offline"
              accessible={Boolean(access.canBatchUpdateProductStatus)}
              fallback={null}
            >
              <Button
                onClick={() => handleBatchStatus('offline')}
                loading={updateStatusLoading}
                disabled={updateStatusLoading || selectedRowKeys.length === 0}
              >
                {intl.formatMessage({
                  id: 'pages.product.batch.offline',
                  defaultMessage: '批量下架',
                })}
              </Button>
            </Access>,
            <Access
              key="create"
              accessible={Boolean(access.canManageProduct)}
              fallback={null}
            >
              <Button
                type="primary"
                icon={<PlusOutlined />}
                onClick={openCreateModal}
              >
                {intl.formatMessage({
                  id: 'pages.product.add',
                  defaultMessage: '新增商品',
                })}
              </Button>
            </Access>,
          ]}
          request={async (params) => {
            const response = (await runGetList(params)) as
              | ProductListResponse
              | ProductItem[];
            const normalized = Array.isArray(response)
              ? { data: response, success: true, total: response.length }
              : response;
            return {
              data: normalized.data,
              success: normalized.success,
              total: normalized.total,
            };
          }}
        />

        <ProductFormModal
          intl={intl}
          open={modalOpen}
          editingId={editingId}
          currentRow={currentRow}
          categoryOptions={categoryOptions}
          statusEnum={statusEnum}
          canViewCostPrice={Boolean(access.canViewCostPrice)}
          formRef={formRef}
          submitting={createLoading || updateLoading || detailLoading}
          onOpenChange={setModalOpen}
          onFinish={async (values) => {
            let compareBase = currentRow;

            if (editingId) {
              try {
                compareBase = (await getProductDetail(
                  editingId,
                )) as ProductItem;
              } catch {
                compareBase = currentRow;
              }
            }

            const mergedValues = compareBase
              ? ({ ...compareBase, ...values } as ProductFormValues)
              : values;
            const coreChanged =
              compareBase?.status === 'online' &&
              hasCoreFieldChanged(compareBase, mergedValues);

            if (coreChanged) {
              messageApi.warning(
                intl.formatMessage({
                  id: 'pages.product.edit.coreDenied',
                  defaultMessage: '已上架商品修改核心字段前需先下架',
                }),
              );
              return false;
            }

            try {
              if (editingId) {
                await runUpdate({ ...values, id: editingId });
                messageApi.success(
                  intl.formatMessage({
                    id: 'common.success.update',
                    defaultMessage: '更新成功',
                  }),
                );
              } else {
                await runCreate(values);
                messageApi.success(
                  intl.formatMessage({
                    id: 'common.success.add',
                    defaultMessage: '添加成功',
                  }),
                );
              }
              actionRef.current?.reload();
              setSelectedRowKeys([]);
              setEditingId(undefined);
              setCurrentRow(undefined);
              return true;
            } catch {
              messageApi.error(
                intl.formatMessage({
                  id: 'common.error.update',
                  defaultMessage: '更新失败',
                }),
              );
              return false;
            }
          }}
        />
      </PageContainer>
    </>
  );
};

export default ProductList;
