package com.zt.plat.module.base.service.materialgradeext;

import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
import com.zt.plat.module.base.controller.admin.materialgradeext.vo.MaterialGradeExtPageReqVO;
import com.zt.plat.module.base.controller.admin.materialgradeext.vo.MaterialGradeExtRespVO;
import com.zt.plat.module.base.controller.admin.materialgradeext.vo.MaterialGradeExtSaveReqVO;
import com.zt.plat.module.base.dal.dao.materialgradeext.MaterialGradeExtMapper;
import com.zt.plat.module.base.dal.dataobject.materialgradeext.MaterialGradeExtDO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

import static com.zt.plat.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static com.zt.plat.framework.common.util.date.LocalDateTimeUtils.buildTime;
import static com.zt.plat.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static com.zt.plat.framework.test.core.util.AssertUtils.assertPojoEquals;
import static com.zt.plat.framework.test.core.util.AssertUtils.assertServiceException;
import static com.zt.plat.framework.test.core.util.RandomUtils.randomPojo;
import static com.zt.plat.framework.test.core.util.RandomUtils.randomLongId;
import static com.zt.plat.module.base.enums.ErrorCodeConstants.MATERIAL_GRADE_EXT_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.*;

@Import(MaterialGradeExtServiceImpl.class)
class MaterialGradeExtServiceImplTest extends BaseDbUnitTest {

    @Resource
    private MaterialGradeExtServiceImpl materialGradeExtService;

    @Resource
    private MaterialGradeExtMapper materialGradeExtMapper;

    private MaterialGradeExtSaveReqVO buildSaveReqVO(Long id) {
        MaterialGradeExtSaveReqVO reqVO = randomPojo(MaterialGradeExtSaveReqVO.class, o -> {
            o.setId(id);
            o.setCompanyCode("C001");
            o.setCompanyName("公司A");
            o.setMaterialCode("M001");
            o.setMaterialName("物料A");
            o.setChineseBrand("中文牌号");
            o.setEnglishBrand("EN-BRAND");
            o.setSpecificationModel("SPC-1");
            o.setLineType("single");
            o.setPackageDesc("箱装");
        });
        return reqVO;
    }

    @Test
    void create_success() {
        MaterialGradeExtSaveReqVO reqVO = buildSaveReqVO(null);

        MaterialGradeExtRespVO respVO = materialGradeExtService.create(reqVO);

        assertNotNull(respVO.getId());
        MaterialGradeExtDO db = materialGradeExtMapper.selectById(respVO.getId());
        assertPojoEquals(reqVO, db, "id", "createTime", "updateTime", "creator", "updater", "deleted",
                "tenantId", "deptId", "deptName", "companyId", "creatorName", "updaterName", "postId");
    }

    @Test
    void update_success() {
        MaterialGradeExtDO db = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C001");
            o.setMaterialCode("M001");
            o.setCreateTime(LocalDateTime.now());
        });
        materialGradeExtMapper.insert(db);

        MaterialGradeExtSaveReqVO reqVO = buildSaveReqVO(db.getId());
        reqVO.setCompanyCode("C002");
        reqVO.setMaterialCode("M002");
        reqVO.setLineType("double");

        materialGradeExtService.update(reqVO);

        MaterialGradeExtDO updated = materialGradeExtMapper.selectById(db.getId());
        assertPojoEquals(reqVO, updated, "createTime", "updateTime", "creator", "updater", "deleted",
                "tenantId", "deptId", "deptName", "companyId", "creatorName", "updaterName", "postId");
    }

    @Test
    void update_notExists() {
        MaterialGradeExtSaveReqVO reqVO = buildSaveReqVO(randomLongId());

        assertServiceException(() -> materialGradeExtService.update(reqVO), MATERIAL_GRADE_EXT_NOT_EXISTS);
    }

    @Test
    void delete_success() {
        MaterialGradeExtDO db = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C001");
            o.setMaterialCode("M001");
        });
        materialGradeExtMapper.insert(db);

        materialGradeExtService.delete(db.getId());

        assertNull(materialGradeExtMapper.selectById(db.getId()));
    }

    @Test
    void delete_notExists() {
        assertServiceException(() -> materialGradeExtService.delete(randomLongId()), MATERIAL_GRADE_EXT_NOT_EXISTS);
    }

    @Test
    void deleteByIds_success() {
        MaterialGradeExtDO db1 = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C001");
            o.setMaterialCode("M001");
        });
        MaterialGradeExtDO db2 = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C002");
            o.setMaterialCode("M002");
        });
        materialGradeExtMapper.insert(db1);
        materialGradeExtMapper.insert(db2);

        materialGradeExtService.deleteByIds(Arrays.asList(db1.getId(), db2.getId()));

        assertNull(materialGradeExtMapper.selectById(db1.getId()));
        assertNull(materialGradeExtMapper.selectById(db2.getId()));
    }

    @Test
    void get_success() {
        MaterialGradeExtDO db = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C001");
            o.setMaterialCode("M001");
        });
        materialGradeExtMapper.insert(db);

        MaterialGradeExtRespVO result = materialGradeExtService.get(db.getId());

        assertPojoEquals(db, result, "createTime", "updateTime", "creator", "updater", "deleted",
                "tenantId", "deptId", "deptName", "companyId", "creatorName", "updaterName", "postId");
    }

    @Test
    void getPage_filterSuccess() {
        MaterialGradeExtDO target = randomPojo(MaterialGradeExtDO.class, o -> {
            o.setCompanyCode("C001");
            o.setCompanyName("公司A");
            o.setMaterialCode("M001");
            o.setMaterialName("物料A");
            o.setChineseBrand("ZH");
            o.setEnglishBrand("EN");
            o.setSpecificationModel("SPC");
            o.setLineType("single");
            o.setPackageDesc("包装A");
            o.setCreateTime(buildTime(2024, 1, 2));
        });
        materialGradeExtMapper.insert(target);

        materialGradeExtMapper.insert(cloneIgnoreId(target, o -> o.setCompanyCode("X")));
        materialGradeExtMapper.insert(cloneIgnoreId(target, o -> o.setMaterialCode("Y")));
        materialGradeExtMapper.insert(cloneIgnoreId(target, o -> o.setChineseBrand("不同")));
        materialGradeExtMapper.insert(cloneIgnoreId(target, o -> o.setLineType("double")));
        materialGradeExtMapper.insert(cloneIgnoreId(target, o -> o.setCreateTime(buildTime(2024, 2, 2))));

        MaterialGradeExtPageReqVO pageReqVO = new MaterialGradeExtPageReqVO();
        pageReqVO.setCompanyCode("C001");
        pageReqVO.setCompanyName("公司");
        pageReqVO.setMaterialCode("M001");
        pageReqVO.setMaterialName("物料");
        pageReqVO.setChineseBrand("ZH");
        pageReqVO.setEnglishBrand("EN");
        pageReqVO.setSpecificationModel("SPC");
        pageReqVO.setLineType("single");
        pageReqVO.setPackageDesc("包装");
        pageReqVO.setCreateTime(buildBetweenTime(2024, 1, 1, 2024, 1, 3));

        PageResult<MaterialGradeExtRespVO> pageResult = materialGradeExtService.getPage(pageReqVO);

        assertEquals(1, pageResult.getTotal());
        assertEquals(1, pageResult.getList().size());
        assertPojoEquals(target, pageResult.getList().get(0), "createTime", "updateTime", "creator", "updater", "deleted",
                "tenantId", "deptId", "deptName", "companyId", "creatorName", "updaterName", "postId");
    }
}