package thyyxxk.webserver.service.reports;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.Capacity;
import thyyxxk.webserver.constants.GetDateFormat;
import thyyxxk.webserver.dao.his.reports.CovidVaccinateAppointmentDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.querydata.CovidVaccinateAppointment;
import thyyxxk.webserver.entity.querydata.CovidVaccinateFactory;
import thyyxxk.webserver.entity.querydata.CovidVaccinateThreshold;
import thyyxxk.webserver.entity.querydata.ZdCovidVaccinate;
import thyyxxk.webserver.utils.*;

import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 新冠接种预约 服务类
 * </p>
 *
 * @author 肖蟾
 * @since 2021-03-16
 */
@Slf4j
@Service
public class CovidVaccinateAppointmentService {

    private final CovidVaccinateAppointmentDao dao;
    private static final SimpleDateFormat SDF = new SimpleDateFormat(GetDateFormat.DATE);
    private static final int GET_DATE_SECTION = 7;

    @Autowired
    public CovidVaccinateAppointmentService(CovidVaccinateAppointmentDao dao) {
        this.dao = dao;
    }

    /**
     * 通过日期区间 或者 预约的姓名 来查找到数据 需要分页
     *
     * @param param 包含 name姓名  ExecuteDate预约时间  currentPage PageSize
     * @return 指定数据
     */
    public ResultVo<Map<String, Object>> queryCovidVaccinateAppointment(CovidVaccinateAppointment param) {
        IPage<CovidVaccinateAppointment> page = getQueryPage(param);
        Map<String, Object> map = new HashMap<>(Capacity.TWO);
        if (page.getTotal() > 0 || page.getRecords().size() > 0) {
            map.put("total", page.getTotal());
            map.put("data", page.getRecords());
            return ResultVoUtil.success(map);
        }
        return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
    }

    /**
     * 查看 可以预约的厂家信息
     *
     * @return 返回只能预约的厂家信息
     */
    public ResultVo<List<CovidVaccinateFactory>> queryCount() {
        return ResultVoUtil.success(dao.kaiQiYuYueChangJia());
    }

    /**
     * 根据新冠疫苗产品的code来查看，近七天的阈值
     * 如果没有这个日期的话 就插入一条
     *
     * @param code 产品的code
     * @return 返回七天的数据
     */
    public ResultVo<List<CovidVaccinateThreshold>> queryChangJiaDuiYingDeYuZhi(Integer code) throws ParseException {
        chaRuRiQI(code);
        return ResultVoUtil.success(dao.chaKanQiTianYuZhi(code, DateUtil.getOffsetDate(0), DateUtil.getOffsetDate(6)));
    }

    /**
     * 设置每日阈值人数的限制 要判断一下 第一次创建数据库中没有对应的值那么就插入七天的阈值
     * 如果已经有了 就只插入没有的日期  疫苗产品的阈值 在表中取默认值
     *
     * @param code 厂家的产品的 code
     */
    private void chaRuRiQI(Integer code) throws ParseException {
        Date maxDate = dao.changJiaYuZhiDoesItExist(code);
        List<Date> dateList = new ArrayList<>();
        //设置默认插入的阈值
        Date date;
        for (int i = 1; i <= GET_DATE_SECTION; i++) {
            date = SDF.parse(DateUtil.getOffsetDate(i));
            if (maxDate == null) {
                dateList.add(date);
                log.info("新冠疫苗插入默认设置阈值 --> code：{}，插入的日期为：{}", code, DateUtil.formatDatetime(date, GetDateFormat.DATE));
            } else if (maxDate.getTime() < date.getTime()) {
                dateList.add(date);
                log.info("新冠疫苗厂家阈值插入 --> code：{}，添加日期为：{}", code, DateUtil.formatDatetime(date, GetDateFormat.DATE));
            }
        }
        //因为在 查看的时候 也是需要 执行 要判断一下 只有日期为空的时候才会插入
        if (dateList.size() > 0) {
            dao.chaRuMeiYouDeDate(code, dateList);
        }
    }

    /**
     * 导出新冠疫苗的 Excel 表格
     *
     * @param response 返回数据
     * @param param    name姓名  ExecuteDate预约时间  currentPage=1  PageSize=-1 这样写才能导出全部的数据
     */
    public void exportExcel(HttpServletResponse response, CovidVaccinateAppointment param) {
        log.info("导出新冠疫苗excel: {}", JSON.toJSONStringWithDateFormat(param, GetDateFormat.DATE));
        List<CovidVaccinateAppointment> list = getQueryPage(param).getRecords();
        String[] title = {"门诊id", "姓名", "性别", "联系电话", "身份证号", "年龄", "工作单位", "工作性质", "预约接种时间", "产品编码", "产品名称", "疫苗厂商"};
        String[][] content = new String[list.size()][];
        for (int i = 0; i < list.size(); i++) {
            content[i] = new String[title.length];
            CovidVaccinateAppointment pojo = list.get(i);
            content[i][0] = pojo.getPatientId();
            content[i][1] = pojo.getName();
            content[i][2] = pojo.getSex() == 1 ? "男" : "女";
            content[i][3] = pojo.getPhone();
            content[i][4] = pojo.getSocialNo();
            content[i][5] = String.valueOf(pojo.getAge());
            content[i][6] = pojo.getCorpName();
            content[i][7] = pojo.getJobCategoryToString();
            content[i][8] = DateUtil.formatDatetime(pojo.getExecuteDate(), "yyyy-MM-dd");
            content[i][9] = String.valueOf(pojo.getVaccinateCode());
            content[i][10] = pojo.getVaccinateName();
            content[i][11] = pojo.getVaccinateFactory();
        }
        //传三个参数 一个是 固定的 response ，excel的头部信息，excel的内容
        ExcelUtil.exportExcel(response, title, content);
    }

    /**
     * @param param 查询和分页的条件
     * @return 返回分页
     * @description: 根据查询 名字或者预约时间 分页显示在页面中  在这里使用了mybatis-plus的条件构造器
     */
    public IPage<CovidVaccinateAppointment> getQueryPage(CovidVaccinateAppointment param) {
        IPage<CovidVaccinateAppointment> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper<CovidVaccinateAppointment> qw = new QueryWrapper<>();
        if (StringUtil.notBlank(param.getName())) {
            qw.like("a.name", param.getName());
        }
        if (param.getExecuteDate() != null) {
            qw.eq("execute_date", param.getExecuteDate());
        }
        return dao.mybatisPlusQueryXGYM(page, qw);
    }

    /**
     * 插入 新增疫苗种类
     *
     * @param param name：疫苗名字 enableFlag：是否可以预约 bookTip：描述
     * @return 返回自增的主键
     */
    public ResultVo<Integer> xinZengYiMiao(ZdCovidVaccinate param) {
        try {
            dao.xinZengYiMiao(param);
            log.info("插入疫苗 --> 操作人：{},插入信息：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONString(param));
        } catch (Exception e) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("<p style='color:red'>【%s】</p>该疫苗名称已存在，添加失败。", param.getName()));
        }
        return ResultVoUtil.success(param.getId());
    }

    /**
     * 插入对应的 疫苗的厂家
     *
     * @param param 需要插入的字段有 code主键 vaccinateId：对应的疫苗 ID
     *              specification:规格 price：金额，name；名字，enableFlag：是否允许预约
     *              在插入厂家成功的时候要默认给他一个产品的阈值
     */
    public ResultVo<Boolean> xinZengChangJia(List<CovidVaccinateFactory> param) throws ParseException {
        //先判断一遍是否有存在这编码的
        List<Integer> vaccinesId = dao.changJiaCodePanDuan(param);
        for (int i = 0; i < vaccinesId.size(); i++) {
            if (vaccinesId.get(i) != null && vaccinesId.get(i) > 0) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("产品编码为<span style='color:#F56C6C'>【%s】</span>已存在,所属疫苗院内编码为<span style='color:#F56C6C'>【%s】</span>，<span style='color:#F56C6C'>【%s】</span>",
                        param.get(i).getCode(), vaccinesId.get(i), "(๑°3°๑)"));
            }
        }
        //新增厂家的信息
        dao.xinZengChangJia(param);
        for (CovidVaccinateFactory pojo : param) {
            log.info("插入厂家 --> 操作人：{}，信息：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONString(pojo));
            //在新插入厂家的时候我就要默认设置好 阈值
            chaRuRiQI(pojo.getCode());
        }
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "厂家添加成功 φ(゜▽゜*)♪");
    }

    /**
     * 查询全部的疫苗名称
     *
     * @return 返回全部的数据
     */
    public ResultVo<List<ZdCovidVaccinate>> chaKanYiMiao() {
        return ResultVoUtil.success(dao.chaKanYiMiao());
    }

    /**
     * 查询对应疫苗的全部厂家
     *
     * @param id 对应的疫苗
     * @return 对应的数据
     */
    public ResultVo<List<CovidVaccinateFactory>> chaKanChangJia(int id) {
        List<CovidVaccinateFactory> list = dao.chaKanChangJiaXinXi(id);
        list.forEach(item -> {
            if (item.getDate() == null) {
                log.info("疫苗编码为：{}，插入今日阈值", item.getCode());
                dao.chaRuJinRiYuZhi(item.getCode());
            }
        });
        return ResultVoUtil.success(dao.chaKanChangJiaXinXi(id));
    }

    /**
     * 根据id来修改 疫苗的一些字段
     *
     * @param param 修改的字段为 name  enableFlag bookTip 通过id来修改
     */
    public ResultVo<Boolean> xiuGaiYiMiao(ZdCovidVaccinate param) {
        log.info("修改疫苗 --> 操作人：{}，数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONStringWithDateFormat(param, GetDateFormat.DATE));
        dao.xiuGaiYiMiao(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE,
                String.format("<p style='color:#67C23A'>%s</p>修改成功 ＼(☆o☆)／", param.getName()));
    }

    /**
     * 根据code来修改厂家
     *
     * @param param 传入需要修改的值和原本的code
     * @return 返回boolean
     */
    public ResultVo<Boolean> xiuGaiChangJia(CovidVaccinateFactory param) {
        log.info("修改新冠疫苗厂家 --> 操作人：{}，数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONString(param));
        dao.xiuGaiChangJia(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE,
                String.format("<p style='color:teal'>%s</p>厂家信息修改成功 φ(゜▽゜*)♪<br>需刷新页面查看效果。", param.getName()));
    }

    /**
     * 删除厂家一些信息
     *
     * @param code 根据code来删除
     * @return 返回
     */
    public ResultVo<Boolean> shanChuChangJia(Integer code) {
        log.info("删除新冠疫苗厂家 --> 操作人：{}，删除的code：{}", TokenUtil.getInstance().getTokenUserId(), code);
        dao.shanChuChangJia(code);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "删除成功 ＼(☆o☆)／");
    }

    /**
     * 这里是批量修改 新冠阈值的数据
     *
     * @param list 传入多个ID 和 value 阈值
     * @return 通知修改成功
     */
    public ResultVo<Boolean> yiJianXiuGaiRiQi(List<CovidVaccinateThreshold> list) {
        log.info("修改新冠疫苗厂家阈值 --> 操作人：{}，数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONString(list));
        dao.xiuGaiYuZhi(list);
        return ResultVoUtil.success();
    }

    /**
     * 开启或关闭该厂家的预约
     *
     * @param code       厂家编码
     * @param enableFlag 0-关闭  1-开启
     * @return 返回通知
     */
    public ResultVo<Boolean> kaiQiHuoGuanBiYuYue(Integer code, Integer enableFlag) {
        log.info("1-开启或0-关闭 厂家编码为：{} 的预约，操作：{},操作人：{}", code, enableFlag, TokenUtil.getInstance().getTokenUserId());
        dao.kaiQiHuoGuanBiYuYue(code, enableFlag);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE,
                String.format("操作成功 --> %s", enableFlag == 0 ? "<span style='color:red'>关闭预约</span>" :
                        "<span style='color:#67C23A'>开启预约</span>"));
    }
}
