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

import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.SqlUtils;
import com.cpop.core.utils.StringUtils;
import com.cpop.system.business.bo.StoreRunOffBo;
import com.cpop.system.business.bo.StoreSignRenewPageBo;
import com.cpop.system.business.bo.StoreSignRenewXmlBo;
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.StoreSignRenewPageVo;
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.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 2024/3/7
     * @return Page<StorePageVo>
     */
    @Override
    public Page<StoreSignRenewPageVo> getStoreSignRenewPage(StoreSignRenewPageBo bo) {
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (StringUtils.isNotBlank(bo.getAddrOrName())){
            queryWrapper.and(STORE.LICENSE_ADDR.like(bo.getAddrOrName()).or(STORE.LICENSE_FIRM_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(dateFormat(STORE_RENEW.CREATE_TIME, "%Y-%m-%d").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(StoreSignRenewPageVo::getCreateTime), STORE.PERSON_CHARGE_NAME, STORE.PERSON_CHARGE_PHONE, STORE.STORE_NAME)
                                .select(STORE_SIGN.EXPIRE_DATE, STORE_SIGN.ID)
                                .select(STORE.LICENSE_ADDR, STORE.LICENSE_FIRM_NAME, STORE.LICENSE_USERNAME)
                                .select(STORE_RENEW.CREATE_TIME, STORE_RENEW.AMOUNT)
                                .from(STORE_RENEW)
                                .leftJoin(STORE).on(STORE.ID.eq(STORE_RENEW.STORE_ID))
                                .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                                .leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID)),
                        StoreSignRenewPageVo.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(StoreSignRenewPageVo::getCreateTime), STORE.PERSON_CHARGE_NAME, STORE.PERSON_CHARGE_PHONE, STORE.STORE_NAME)
                        .select(STORE.LICENSE_ADDR, STORE.LICENSE_FIRM_NAME, STORE.LICENSE_USERNAME)
                        .select(STORE_RENEW.CREATE_TIME, STORE_RENEW.AMOUNT)
                        .leftJoin(STORE).on(STORE.ID.eq(STORE_SIGN.STORE_ID))
                        .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                        .leftJoin(STORE_RENEW).on(STORE_RENEW.STORE_ID.eq(STORE.ID)),
                StoreSignRenewPageVo.class);
    }

    /**
     * 机构/店铺流失
     * @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> getSignRenewXml(StoreSignRenewXmlBo bo) {
        return SpringUtils.getBean(StoreRenewService.class).listAs(QueryWrapper.create()
                        .select(BRAND.BRAND_NAME)
                        .select(STORE.CREATE_TIME.as(StoreRenewDto::getCreateTime), STORE.PERSON_CHARGE_NAME, STORE.PERSON_CHARGE_PHONE, STORE.STORE_NAME)
                        .select(STORE_SIGN.EXPIRE_DATE, STORE_SIGN.ID)
                        .select(STORE.LICENSE_ADDR, STORE.LICENSE_FIRM_NAME, STORE.LICENSE_USERNAME)
                        .select(STORE_RENEW.CREATE_TIME, STORE_RENEW.AMOUNT)
                        .leftJoin(STORE).on(STORE.ID.eq(STORE_RENEW.STORE_ID))
                        .leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
                        .leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID))
                        .and(dateFormat(STORE_RENEW.CREATE_TIME, "%Y-%m-%d").between(bo.getStartDate(), bo.getEndDate()))
                        .and(BRAND.BRAND_NAME.like(bo.getBrandOrStore()).or(STORE.STORE_NAME.like(bo.getBrandOrStore()))),
                StoreRenewDto.class);
    }
}
