package com.boman.web.core.service.excel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.boman.common.core.utils.DateUtils;
import com.boman.common.core.utils.SecurityUtils;
import com.boman.common.core.utils.poi.ExcelUtil;
import com.boman.domain.VaccineInfoOperation;
import com.boman.domain.VaccineInfoUser;
import com.boman.domain.YmjzImportErrorLog;
import com.boman.domain.dto.AjaxResult;
import com.boman.domain.dto.FormDataDto;
import com.boman.domain.utils.ThreadPoolService;
import com.boman.web.core.mapper.StandardlyMapper;
import com.boman.web.core.mapper.VaccineInfoMapper;
import com.boman.web.core.mapper.VaccineInfoUserMapper;
import com.boman.web.core.service.TableServiceCmdService;
import com.boman.web.core.service.vaccineInfo.impl.VaccineInfoServiceImpl;
import com.boman.web.core.service.ymjz.YmjzImportErrorLogService;
import com.boman.web.core.utils.IdUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;

/**
 * @author shiqian
 * @date 2021年06月08日 09:42
 **/
@Service
public class ImportExportExcelServiceImpl implements IImportExportExcelService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ImportExportExcelServiceImpl.class);

    @Resource
    private StandardlyMapper mapper;
    @Resource
    private TableServiceCmdService cmdService;
    @Resource
    private VaccineInfoMapper vaccineInfoMapper;
    @Resource
    private VaccineInfoUserMapper vaccineInfoUserMapper;
    @Resource
    private YmjzImportErrorLogService errorLogService;


    /**
     * 功能描述: 批量导入数据
     *
     * @param tableName tableName
     * @param dataList  需要保存的数据
     * @return void
     */
    @Override
    public AjaxResult importCommonData(String tableName, List<JSONObject> dataList) {
        requireNonNull(tableName, "importCommonData tableName is empty");
        requireNonNull(dataList, "importCommonData dataList is empty");

        List<String> result = new ArrayList<>(dataList.size());
        FormDataDto dto = new FormDataDto();
        dto.setTable(tableName);
        dto.setObjId(-1L);
        for (int i = 0; i < dataList.size(); i++) {
            JSONObject data = dataList.get(i);
            dto.setFixedData(data);
            AjaxResult ajaxResult;
            try {
                ajaxResult = cmdService.objectSave(dto);
            } catch (Exception e) {
                result.add("第" + i + "条导入失败, 失败原因为: " + e.getMessage());
                e.printStackTrace();
                continue;
            }

            if (AjaxResult.checkFail(ajaxResult)) {
                result.add("第" + i + "条导入失败, 数据为: " + data.toJSONString());
            }
        }

        return AjaxResult.success("成功", result);
    }

    @Override
    public String importYmjz(MultipartFile file) throws Exception {
        ExcelUtil<VaccineInfoOperation> util = new ExcelUtil<>(VaccineInfoOperation.class);
        Sheet sheet = util.importExcel4Ymjz("", file.getInputStream());
        int rows = sheet.getPhysicalNumberOfRows();
        String username = SecurityUtils.getUsername();
        ThreadPoolService.execute(() -> {
            // 往data中赋值
            for (int i = 1; i < rows; i++) {
                saveRel(sheet.getRow(i), i, username);
            }
        });

        String msg = "数据导入中，系统将自动处理数据，%s后请查看结果。";
        if (rows <= 1000) {
            msg = String.format(msg, "20分钟");
        } else if (rows >= 5000 && rows <= 10000) {
            msg = String.format(msg, "1小时");
        } else if (rows > 10000 && rows <= 50000) {
            msg = String.format(msg, "2小时");
        } else {
            msg = String.format(msg, "4小时");
        }

        return msg;
    }

    private void saveRel(Row row, int i, String username) {
        // excel 14列
        // 身份证
        String sfz = row.getCell(4).getStringCellValue();
        String[] split = sfz.split("\\**\\**\\**\\**\\*");
        // 受种者编码
        String szzbm = row.getCell(0).getStringCellValue();
        // 受种者姓名
        String szzxm = row.getCell(1).getStringCellValue();
        // 生产厂家
        String sccj = row.getCell(11).getStringCellValue();
        // 接种针次
        String jzjc = row.getCell(12).getStringCellValue();
        // 受种者性别
        String xb = row.getCell(2).getStringCellValue();
        // 出生日期
        String csrq = row.getCell(3).getStringCellValue();
        // 电话号码
        String dhhm = row.getCell(5).getStringCellValue();
        // 住址
        String place = row.getCell(6).getStringCellValue();
        // 工作单位
        String gzdw = row.getCell(7).getStringCellValue();
        // 人群分类
        String rqfl = row.getCell(8).getStringCellValue();
        // 接种单位
        String jzdw = row.getCell(9).getStringCellValue();
        // 接种日期
        String jzsj = row.getCell(13).getStringCellValue();
        VaccineInfoOperation in = mapper.getByCode(szzbm, "%" + split[1] + "%", "%" + szzxm + "%");
        String progress = VaccineInfoServiceImpl.getIsSuccess(sccj, jzjc);
        Date now = new Date();
        if (in == null) {
            in = new VaccineInfoOperation();
            Long maxId = IdUtils.getMaxId("vaccine_info", "id");
            in.setId(maxId);
            in.setUserName(szzxm);
            in.setGender(xb);
            in.setIdCard(sfz);
            in.setPhoneNum(dhhm);
            in.setIsVaccination("是");
            in.setVaccineName(sccj);
            in.setJici(jzjc);
            in.setVaccinationTime(DateUtils.formatDate(jzsj));
            in.setVaccinationPlace(jzdw);
            in.setShouldBe("是");
            in.setProgress(progress);
            in.setShouldSlow("否");
            in.setCode(szzbm);
            in.setBirthday(csrq);
            in.setWorkUnit(gzdw);
            in.setCrowdClassification(rqfl);
            in.setManufacturer(sccj);
            in.setAge(0);
            in.setDeptId(1L);
            in.setStatus("2");
            in.setCreateBy(username);
            in.setUpdateBy(username);
            in.setCreateTime(now);
            in.setUpdateTime(now);
            try {
                vaccineInfoMapper.insertVaccineInfo(in);
            } catch (Exception e) {
                YmjzImportErrorLog log = YmjzImportErrorLog.builder()
                        .id(IdUtils.getMaxId("ymjz_import_error_log", "id"))
                        .username(szzxm).place(place).vaccineName(sccj).jici(jzjc).vaccinationTime(DateUtils.formatDate(jzsj))
                        .vaccinationPlace(jzdw).createBy(username).updateBy(username).createTime(now).updateTime(now).build();
                errorLogService.insertErrorLog(log);
                e.printStackTrace();
            }

            LOGGER.info("count: {}, info insert: [{}]", i, JSON.toJSONString(in));
        } else {
            sfz = in.getIdCard();
            Integer age;
            try {
                age = VaccineInfoServiceImpl.getAge(in.getIdCard());
            } catch (Exception e) {
                age = null;
            }

            VaccineInfoServiceImpl.shouldSlow(in);
            in.setCode(szzbm);
            in.setCrowdClassification(rqfl);
            in.setVaccineName(sccj);
            in.setManufacturer(sccj);
            in.setJici(jzjc);
            in.setVaccinationTime(DateUtils.formatDate(jzsj));
            in.setBirthday(csrq);
            in.setProgress(progress);
            in.setVaccinationPlace(jzdw);
            in.setIdCard(split[1]);
            in.setUserName(szzxm);
            in.setAge(age);
            in.setUpdateTime(now);
            in.setUpdateBy(username);
            try {
                vaccineInfoMapper.update(in);
            } catch (Exception e) {
                YmjzImportErrorLog log = YmjzImportErrorLog.builder()
                        .id(IdUtils.getMaxId("ymjz_import_error_log", "id"))
                        .username(szzxm).place(place).vaccineName(sccj).jici(jzjc).vaccinationTime(DateUtils.formatDate(jzsj))
                        .vaccinationPlace(jzdw).createBy(username).updateBy(username).createTime(now).updateTime(now).build();
                errorLogService.insertErrorLog(log);
                e.printStackTrace();
            }
            LOGGER.info("count: {}, info update: [{}]", i, JSON.toJSONString(in));
        }

        // 防止重复导入
        if (!sfz.contains("\\**")) {
            int count = vaccineInfoUserMapper.countByIdCardAndJici(sfz, jzjc);
            if (count > 0) {
                return;
            }
        }

        Long maxId = IdUtils.getMaxId("vaccine_info_user", "id");
        VaccineInfoUser user = new VaccineInfoUser();
        user.setId(maxId);
        user.setIdCard(sfz);
        user.setVaccineName(sccj);
        user.setJici(jzjc);
        user.setVaccinationTime(DateUtils.formatDate(jzsj));
        user.setVaccinationPlace(jzdw);
        user.setCreateBy(username);
        user.setUpdateBy(username);
        user.setUpdateTime(now);
        user.setCreateTime(now);
        try {
            vaccineInfoUserMapper.insertVaccineInfoUser(user);
        } catch (Exception e) {
            YmjzImportErrorLog log = YmjzImportErrorLog.builder()
                    .id(IdUtils.getMaxId("ymjz_import_error_log", "id"))
                    .username(szzxm).place(place).vaccineName(sccj).jici(jzjc).vaccinationTime(DateUtils.formatDate(jzsj))
                    .vaccinationPlace(jzdw).createBy(username).updateBy(username).createTime(now).updateTime(now).build();
            errorLogService.insertErrorLog(log);
            e.printStackTrace();
        }
        LOGGER.info("count: {}, vaccine user: [{}]", i, JSON.toJSONString(user));
    }
}
