package com.cpop.system.business.service.impl;

import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.system.business.bo.StoreRenewPageBo;
import com.cpop.system.business.bo.StoreRenewXmlBo;
import com.cpop.system.business.bo.StoreRunOffBo;
import com.cpop.system.business.dto.StoreRenewDto;
import com.cpop.system.business.entity.StoreSign;
import com.cpop.system.business.mapper.StoreSignMapper;
import com.cpop.system.business.service.StoreRenewService;
import com.cpop.system.business.service.StoreSignService;
import com.cpop.system.business.vo.StoreRenewPageVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.cpop.system.business.entity.table.BrandTableDef.BRAND;
import static com.cpop.system.business.entity.table.StoreLicenseTableDef.STORE_LICENSE;
import static com.cpop.system.business.entity.table.StoreRenewTableDef.STORE_RENEW;
import static com.cpop.system.business.entity.table.StoreSignTableDef.STORE_SIGN;
import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
import static com.mybatisflex.core.query.QueryMethods.*;

/**
 * 校区-签约表 服务层实现。
 *
 * @author DB
 * @since 2023-12-13
 */
@Service("storeSignService")
public class StoreSignServiceImpl extends ServiceImpl<StoreSignMapper, StoreSign> implements StoreSignService {

    /**
     * 分页查询校区续费
     * @author DB
     * @since 2023/12/14
     * @param bo 请求参数
     * @return Page<StoreSign>
     */
    @Override
    public Page<StoreRenewPageVo> getStoreRenewPage(StoreRenewPageBo bo) {
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (StringUtils.isNotBlank(bo.getAddrOrName())){
            queryWrapper.and(STORE_LICENSE.LICENSE_ADDR.like(bo.getAddrOrName()).or(STORE_LICENSE.LICENSE_NAME.like(bo.getAddrOrName())));
        }
        if (StringUtils.isNotBlank(bo.getBrandOrStore())){
            queryWrapper.and(BRAND.BRAND_NAME.like(bo.getBrandOrStore()).or(STORE.STORE_NAME.like(bo.getBrandOrStore())));
        }
        switch (bo.getRenewStatus()){
            //待续费
            case 0:
                queryWrapper.and(subDate(STORE_SIGN.EXPIRE_DATE, number(90)).le(now())).and(STORE_SIGN.IS_LOSS.eq(false));
                break;
            //已续费
            case 1:
                if (bo.getStartDate() != null && bo.getEndDate() != null) {
                    queryWrapper.and(STORE_RENEW.RENEW_DATE.between(bo.getStartDate(), bo.getEndDate()));
                }
                return SpringUtils.getBean(StoreRenewService.class).getMapper().paginateAs(Page.of(pageDomain.getPageNum(), pageDomain.getPageSize()),
                        queryWrapper
                                .select(BRAND.BRAND_NAME)
                                .select(STORE.CREATE_TIME.as(StoreRenewPageVo::getCreateTime), STORE.PERSON_CHARGE, STORE.PHONE, STORE.STORE_NAME)
                                .select(STORE_SIGN.EXPIRE_DATE, STORE_SIGN.ID)
                                .select(STORE_LICENSE.LICENSE_ADDR, STORE_LICENSE.LICENSE_NAME, STORE_LICENSE.LICENSE_USER_NAME)
                                .select(STORE_RENEW.RENEW_DATE, STORE_RENEW.RENEW_AMOUNT)
                                .select("cos.name as renewStaffName")
                                .from(STORE_RENEW)
                                .leftJoin(STORE).on(STORE.ID.eq(STORE_RENEW.STORE_ID))
                                .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                                .leftJoin(STORE_LICENSE).on(STORE_LICENSE.STORE_ID.eq(STORE.ID))
                                .leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID))
                                .leftJoin("cp_oam_staff").as("cos").on("`cos`.`id` = cp_sys_store_renew.renew_staff_id"),
                        StoreRenewPageVo.class);
            //已流失
            default:
                queryWrapper.and(STORE_SIGN.IS_LOSS.eq(true));
        }
        return this.mapper.paginateAs(Page.of(pageDomain.getPageNum(), pageDomain.getPageSize()),
                queryWrapper
                        .select(BRAND.BRAND_NAME)
                        .select(STORE.CREATE_TIME.as(StoreRenewPageVo::getCreateTime), STORE.PERSON_CHARGE, STORE.PHONE, STORE.STORE_NAME)
                        .select(STORE_SIGN.EXPIRE_DATE, STORE_SIGN.ID, STORE_SIGN.RUN_OFF_DATE, STORE_SIGN.RUN_OFF_REASON, STORE_SIGN.UPDATE_USER_ID.as(StoreRenewPageVo::getLastUpdateUserId))
                        .select(STORE_LICENSE.LICENSE_ADDR, STORE_LICENSE.LICENSE_NAME, STORE_LICENSE.LICENSE_USER_NAME)
                        .select(STORE_RENEW.RENEW_DATE, STORE_RENEW.RENEW_AMOUNT)
                        .select("cos.name as renewStaffName")
                        .leftJoin(STORE).on(STORE.ID.eq(STORE_SIGN.STORE_ID))
                        .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                        .leftJoin(STORE_LICENSE).on(STORE_LICENSE.STORE_ID.eq(STORE.ID))
                        .leftJoin(STORE_RENEW).on(STORE_RENEW.STORE_ID.eq(STORE.ID))
                        .leftJoin("cp_oam_staff").as("cos").on("`cos`.`id` = `cp_sys_store_renew`.`renew_staff_id`"),
                StoreRenewPageVo.class,
                //子查询
                item -> item.field(StoreRenewPageVo::getLastUpdateStaffName)
                        .queryWrapper(updateStaff -> queryChain()
                                .select("name")
                                .from("cp_oam_staff")
                                .where("cp_oam_staff.user_id = ?", updateStaff.getLastUpdateUserId())));
    }

    /**
     * 机构/店铺流失
     * @author DB
     * @since 2023/12/14
     * @param bo 请求参数
     */
    @Override
    public void runOff(StoreRunOffBo bo) {
        this.updateChain().set(STORE_SIGN.RUN_OFF_REASON, bo.getRunOffReason())
                .set(STORE_SIGN.RUN_OFF_DATE, now())
                .set(STORE_SIGN.IS_LOSS, true)
                .where(STORE_SIGN.ID.eq(bo.getId())).update();
    }

    /**
     * 获取已续费导出数据
     * @author DB
     * @since 2023/12/14
     * @param bo  请求
     * @return List<StoreRenewDto>
     */
    @Override
    public List<StoreRenewDto> getRenewXml(StoreRenewXmlBo bo) {
        return SpringUtils.getBean(StoreRenewService.class).listAs(QueryWrapper.create()
                        .select(BRAND.BRAND_NAME)
                        .select(STORE.CREATE_TIME.as(StoreRenewDto::getCreateTime), STORE.PERSON_CHARGE, STORE.PHONE, STORE.STORE_NAME)
                        .select(STORE_SIGN.EXPIRE_DATE, STORE_SIGN.ID)
                        .select(STORE_LICENSE.LICENSE_ADDR, STORE_LICENSE.LICENSE_NAME, STORE_LICENSE.LICENSE_USER_NAME)
                        .select(STORE_RENEW.RENEW_DATE, STORE_RENEW.RENEW_AMOUNT)
                        .select("cos.name as renewStaffName")
                        .leftJoin(STORE).on(STORE.ID.eq(STORE_RENEW.STORE_ID))
                        .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                        .leftJoin(STORE_LICENSE).on(STORE_LICENSE.STORE_ID.eq(STORE.ID))
                        .leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID))
                        .leftJoin("cp_oam_staff").as("cos").on("cos.id = `cp_sys_store_renew`.`renew_staff_id`")
                        .and(STORE_RENEW.RENEW_DATE.between(bo.getStartDate(), bo.getEndDate()))
                        .and(BRAND.BRAND_NAME.like(bo.getBrandOrStore()).or(STORE.STORE_NAME.like(bo.getBrandOrStore())))
                        .and(STORE_LICENSE.LICENSE_ADDR.like(bo.getAddrOrName()).or(STORE_LICENSE.LICENSE_NAME.like(bo.getAddrOrName()))),
                StoreRenewDto.class);
    }
}
