package cn.iocoder.foodnexus.module.order.service.customerorder;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.framework.security.core.LoginUser;
import cn.iocoder.foodnexus.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.foodnexus.module.customerpermission.core.annotation.CustomerVisible;
import cn.iocoder.foodnexus.module.erp.api.service.ErpCustomerApi;
import cn.iocoder.foodnexus.module.erp.api.service.ErpSupplierApi;
import cn.iocoder.foodnexus.module.erp.api.service.ErpWarehouseApi;
import cn.iocoder.foodnexus.module.erp.service.customerwarehouse.CustomerWarehouseService;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquiresupplierpush.InquireSupplierPushDO;
import cn.iocoder.foodnexus.module.operations.service.inquiresupplierpush.InquireSupplierPushService;
import cn.iocoder.foodnexus.module.order.controller.app.customerOrder.vo.AppCustomerOrderItemSaveReqVO;
import cn.iocoder.foodnexus.module.order.controller.app.customerOrder.vo.AppCustomerOrderSaveReqVO;
import cn.iocoder.foodnexus.module.order.service.customerorderitem.CustomerOrderItemService;
import cn.iocoder.foodnexus.module.product.api.InquireCustomerApi;
import cn.iocoder.foodnexus.module.product.api.dto.CustomerVisibleProductRespDTO;
import cn.iocoder.foodnexus.module.system.annotations.AppSystemAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.foodnexus.module.order.controller.admin.customerorder.vo.*;
import cn.iocoder.foodnexus.module.order.dal.dataobject.customerorder.CustomerOrderDO;
import cn.iocoder.foodnexus.framework.common.pojo.PageResult;
import cn.iocoder.foodnexus.framework.common.pojo.PageParam;
import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;

import cn.iocoder.foodnexus.module.order.dal.mysql.customerorder.CustomerOrderMapper;

import static cn.iocoder.foodnexus.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.foodnexus.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.foodnexus.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.foodnexus.module.order.enums.ErrorCodeConstants.*;

/**
 * 客户总订单 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class CustomerOrderServiceImpl implements CustomerOrderService {

    @Resource
    private CustomerOrderMapper customerOrderMapper;

    @Autowired
    private CustomerOrderItemService customerOrderItemService;

    @Autowired
    private CustomerWarehouseService customerWarehouseService;

    @Autowired
    private InquireCustomerApi inquireCustomerApi;

    @Autowired
    private ErpCustomerApi customerApi;

    @Autowired
    private ErpWarehouseApi warehouseApi;

    @Autowired
    private InquireSupplierPushService inquireSupplierPushService;

    @Autowired
    private ErpSupplierApi supplierApi;

    @Override
    public Long createCustomerOrder(CustomerOrderSaveReqVO createReqVO) {
        // 插入
        CustomerOrderDO customerOrder = BeanUtils.toBean(createReqVO, CustomerOrderDO.class);
        customerOrderMapper.insert(customerOrder);

        // 返回
        return customerOrder.getId();
    }

    @Override
    public void updateCustomerOrder(CustomerOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateCustomerOrderExists(updateReqVO.getId());
        // 更新
        CustomerOrderDO updateObj = BeanUtils.toBean(updateReqVO, CustomerOrderDO.class);
        customerOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteCustomerOrder(Long id) {
        // 校验存在
        validateCustomerOrderExists(id);
        // 删除
        customerOrderMapper.deleteById(id);
    }

    @Override
        public void deleteCustomerOrderListByIds(List<Long> ids) {
        // 删除
        customerOrderMapper.deleteByIds(ids);
        }


    private void validateCustomerOrderExists(Long id) {
        if (customerOrderMapper.selectById(id) == null) {
            throw exception(CUSTOMER_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public CustomerOrderDO getCustomerOrder(Long id) {
        return customerOrderMapper.selectById(id);
    }

    @Override
    public PageResult<CustomerOrderDO> getCustomerOrderPage(CustomerOrderPageReqVO pageReqVO) {
        return customerOrderMapper.selectPage(pageReqVO);
    }

    /**
     * 客户创建订单
     *
     * @param createReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CustomerVisible
    public Long appCreateCustomerOrder(AppCustomerOrderSaveReqVO createReqVO) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        this.validCustomerOrder(createReqVO, loginUser.getId());
        Long customerId = customerApi.queryCustomerIdByUserId(loginUser.getId());
        CustomerVisibleProductRespDTO dto = inquireCustomerApi.queryCustomerIdByCustomerId(customerId);
        Map<Long, CustomerVisibleProductRespDTO.CustomerProduct> customerProductMap = CommonUtil.listConvertMap(dto.getItems(), CustomerVisibleProductRespDTO.CustomerProduct::getProductId);
        for (AppCustomerOrderItemSaveReqVO item : createReqVO.getOrderItems()) {
            if (customerProductMap.containsKey(item.getProductId())) {
                CustomerVisibleProductRespDTO.CustomerProduct customerProduct = customerProductMap.get(item.getProductId());
                item.setOrderItemPrice(customerProduct.getSupplierQuote());
                item.setOrderItemTotal(customerProduct.getSupplierQuote() * item.getOrderItemQuantity());
                InquireSupplierPushDO inquireSupplierPush = inquireSupplierPushService.getInquireSupplierPush(customerProduct.getInquireSupplierId());

                item.setSupplierId(inquireSupplierPush.getSupplierId());
                item.setSupplierName(supplierApi.queryNameById(inquireSupplierPush.getSupplierId()));
            }
        }

        Long customerOrderId = this.createCustomerOrder(BeanUtils.toBean(createReqVO, CustomerOrderSaveReqVO.class));

        customerOrderItemService.createBatch(createReqVO.getOrderItems(), customerOrderId, customerId);

        return customerOrderId;
    }

    private void validCustomerOrder(AppCustomerOrderSaveReqVO createReqVO, Long customerId) {
        if (!warehouseApi.existsById(createReqVO.getWarehouseId())) {
            throw exception(CUSTOMER_ORDER_WAREHOUSE_NOEXISTS);
        }
        if (!warehouseApi.existsById(createReqVO.getWarehouseAreaId())) {
            throw exception(CUSTOMER_ORDER_WAREHOUSE_NOEXISTS);
        }
        if (!customerWarehouseService.exists(createReqVO.getWarehouseAreaId(), customerId)) {
            throw exception(CUSTOMER_WAREHOUSE_NOT_BIND);
        }
    }
}