package cn.com.countrygarden.bi.main.service.impl;

import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.dao.MarketingChargeMapper;
import cn.com.countrygarden.bi.main.model.*;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.PreCommService;
import cn.com.countrygarden.bi.main.service.MarketingChargeService;
import cn.com.countrygarden.bi.main.core.AbstractService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
@Transactional
public class MarketingChargeServiceImpl extends AbstractService<MarketingCharge> implements MarketingChargeService {
    private static final Date DATE = new Date();
    private static final LocalDateTime LOCAL_DATE_TIME = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());

    @Resource
    private MarketingChargeMapper mapper;

    @Resource
    private PreCommService preCommService;

    private final Logger logger = LoggerFactory.getLogger(MarketingContractServiceImpl.class);

    public Workbook processingExcelValue(Workbook workbook, MarketingUploadFile uploadFile, TbSysUser sysUser) {
        Sheet sheet = workbook.getSheetAt(0);
        int physicalRows = sheet.getPhysicalNumberOfRows();

        // 第一个sheet第3行起为有效数据
        if (physicalRows < 3 || sheet.getRow(2) == null) {
            return workbook;
        }

        Date date = sheet.getRow(0).getCell(0).getDateCellValue();
        if (date == null) {
            throw new ServiceException("无法解析上传月份");
        }
        String year = new SimpleDateFormat("yyyy").format(date);
        String month = new SimpleDateFormat("MM").format(date);
        Short yearShort = Short.parseShort(year);
        Byte monthByte = Byte.parseByte(month);

        for (int i = 2; i <= physicalRows; i++) {
            Row row = sheet.getRow(i);
            if (row == null) {
                continue;
            }

            Cell organCell = row.getCell(0);
            if (organCell == null || organCell.equals("")) {
                continue;
            }
            String organName = organCell.getStringCellValue().trim();
            if (organName.equals("")) {
                continue;
            }

            Cell commCell = row.getCell(1);
            if (commCell == null || commCell.equals("")) {
                continue;
            }

            String commName = commCell.getStringCellValue().trim();
            if (commName.equals("")) {
                continue;
            }

            PreComm preComm = preCommService.findOrCreate(commName, organName, sysUser);
            if (preComm == null) {
                continue;
            }

            // 更新comm
            preComm.setNcAccount(row.getCell(2).getStringCellValue().trim());
            preComm.setNcNumber(row.getCell(3).getStringCellValue().trim());
            preComm.setDevelopSubject(row.getCell(4).getStringCellValue().trim());
            preComm.setModifiedBy(sysUser.getUserCode());
            preComm.setGmtModified(DATE);
            preCommService.update(preComm);

            MarketingCharge item = new MarketingCharge();
            item.setYear(yearShort);
            item.setMonth(monthByte);
            item.setModifiedBy(sysUser.getUserCode());
            item.setGmtModified(DATE);
            item.setCommId(preComm.getId());
            try {
                item.setChargeArea(BigDecimal.valueOf(row.getCell(5).getNumericCellValue()));
                item.setMemo(row.getCell(6).getStringCellValue().trim());
            } catch (Exception e) {
                logger.error("无法读取数据：" + e.getMessage());
                row.getCell(7).setCellValue("无法读取数据：" + e.getMessage());
                continue;
            }

            MarketingCharge findItem = findByUk(Integer.valueOf(year), Integer.valueOf(month), preComm.getId());
            logger.info("findItem: " + findItem);
            if (findItem == null) {
                item.setGmtCreate(DATE);
                item.setCreateBy(sysUser.getUserCode());
                save(item);
            } else {
                item.setId(findItem.getId());
                item.setIsDelete((byte) 0);
                update(item);
            }
        }

        return workbook;
    }

    public MarketingCharge findByUk(int year, int month, int commId) {
        return mapper.findByUk(new HashMap<String, Object>() {{
            put("year", year);
            put("month", month);
            put("commId", commId);
        }});
    }

    /**
     * 统计本年面积及项目数
     *
     * @return
     */
    public MarketingCharge sumThisYear() {
        return mapper.sum(new HashMap<String, Object>() {{
            put("year", LOCAL_DATE_TIME.getYear());
        }});
    }

    /**
     * 统计本年面积及项目数
     *
     * @return
     */
    public List<MarketingCharge> sumThisYearBySeason() {
        return mapper.sumBy(new HashMap<String, Object>() {{
            put("year", LOCAL_DATE_TIME.getYear());
            put("by", "season");
        }});
    }

    public List<MarketingCharge> rankingByOrgan(int season, int offset, int limit) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        String year = dateFormat.format(DATE);
        Map<String, Object> param = new HashMap<String, Object>() {{
            put("year", year);
            put("season", season);
            put("limit", limit);
            put("offset", offset);
        }};
        switch (season) {
            case 0:
                param.put("after", 1);
                param.put("before", 12);
                break;
            case 1:
                param.put("after", 1);
                param.put("before", 3);
                break;
            case 2:
                param.put("after", 4);
                param.put("before", 6);
                break;
            case 3:
                param.put("after", 7);
                param.put("before", 9);
                break;
            case 4:
                param.put("after", 10);
                param.put("before", 12);
                break;
        }
        return mapper.rankingByOrgan(param);
    }

    /**
     * 后台指标列表
     *
     * @param search
     * @param offset
     * @param limit
     * @return
     */
    public List<MarketingCharge> search(
            int month,
            String search,
            int offset,
            int limit
    ) {
        return mapper.search(new HashMap<String, Object>() {{
            put("year", LOCAL_DATE_TIME.getYear());
            put("month", Math.max(0, month));
            put("search", search);
            put("offset", Math.max(0, offset));
            put("limit", Math.max(0, limit));
        }});
    }

    @Override
    public MarketingCharge findById(Integer id) {
        return mapper.findById(id);
    }

    public boolean softDelete(int id, TbSysUser sysUser) {
        try {
            mapper.softDelete(new HashMap<String, Object>() {{
                put("id", id);
                put("userCode", sysUser.getUserCode());
            }});
        } catch (Exception e) {
            deleteById(id);
        }
        return true;
    }
}
