package me.zhengjie.modules.quartz.task;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.dm.dmReadingRoom.domain.DmReadingRoom;
import me.zhengjie.modules.dm.dmReadingRoom.repository.DmReadingRoomRepository;
import me.zhengjie.modules.dm.dmReadingRoomApplay.domain.DmReadingRoomApplay;
import me.zhengjie.modules.dm.dmReadingRoomApplay.service.DmReadingRoomApplayService;
import me.zhengjie.modules.dm.dmReadingRoomConfig.domain.DmReadingRoomConfig;
import me.zhengjie.modules.dm.dmReadingRoomConfig.repository.DmReadingRoomConfigRepository;
import me.zhengjie.modules.dm.dmReadingRoomConfig.service.DmReadingRoomConfigService;
import me.zhengjie.modules.dm.dmReadingRoomConfig.service.dto.DmReadingRoomConfigDto;
import me.zhengjie.modules.dm.dmReadingRoomConfig.service.dto.DmReadingRoomConfigQueryCriteria;
import me.zhengjie.modules.dm.dmtsCollection.domain.DmTsCollection;
import me.zhengjie.modules.dm.dmtsCollection.repository.DmTsCollectionRepository;
import me.zhengjie.modules.dm.dmtsInfo.domain.DmTsInfo;
import me.zhengjie.modules.dm.dmtsInfo.repository.DmTsInfoRepository;
import me.zhengjie.modules.dmuser.domain.DmUser;
import me.zhengjie.modules.dmuser.service.DmUserService;
import me.zhengjie.modules.dmuser.service.dto.DmUserDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.DateUtil;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;

@Slf4j
@Component
@RequiredArgsConstructor
public class ReadRoomTask {



//    @Value("${APPLAY_URL}")
    private String APPLAY_URL;
    private final DmReadingRoomConfigRepository dmReadingRoomConfigRepository; //阅览室配置
    private final DmReadingRoomRepository dmReadingRoomRepository; //阅览室记录
    private final DmReadingRoomApplayService dmReadingRoomApplayService; // 消费记录
    private final DmTsInfoRepository  dmTsInfoRepository; //图书信息
    private final DmTsCollectionRepository dmTsCollectionRepository; // 图书藏
    private final DmUserService dmUserService;



    public void run() throws Exception {
        synchronizationBookInfo();
        synchronizationBookCollection();
        synchronizationReadRoom();
    }

    /**
     * 消费记录  每天一次
     */
    public void ReadRoomApplay(){

        /**
         *  ①首先需要定时查询是否逾期
         *  ②逾期之后算扣款
         *  ③查询配置文件
         *  ④扣款之后要同步扣款接口
         */
        /**
         *  查询逾期的记录
         */
        //新建时间格式化对象SimpleDateFormat
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //格式化当前时间
        String read_end_time = simpleDateFormat.format(new Date());
        // 传入参数进行查询逾期记录
        List<DmReadingRoom> readRoomByOverdue = dmReadingRoomRepository.findReadRoomByOverdue(1, read_end_time);
        /**
         * 开始 算扣款
         */
        //先查询逾期配置文件
         List<DmReadingRoomConfig> dmReadingRoomConfigs = dmReadingRoomConfigRepository.findAll();
         //开始计算逾期金额
        readRoomByOverdue.forEach(item->{
            //根据借阅记录id查询消费总额度记录 由String接收  逾期一天扣一天为了防止多扣款
            BigDecimal sumMoney = dmReadingRoomApplayService.findApplaySumMoneyByRoomId(item.getReadingRoomId());
            if (sumMoney == null){
                sumMoney = BigDecimal.ZERO;
            }
            //开始进行扣费
            /**
             * 条件：
             * ① 配置信息不能为空
             * ② 扣款总金额不能超过配置的上限  将近上限只扣剩下的
             * ③ BigDecimal比较 a.compareTo(b) a < b = -1   a = b = 0   a > b =1
             */
            if (dmReadingRoomConfigs.size()>0 && sumMoney.compareTo(dmReadingRoomConfigs.get(0).getOverdueAmountMax()) == -1 ){
                //算出可以扣几次
                BigDecimal divide = dmReadingRoomConfigs.get(0).getOverdueAmountMax().divide(dmReadingRoomConfigs.get(0).getOverdueAmount(),2, BigDecimal.ROUND_HALF_UP);
                //算出已经扣了几次
                BigDecimal divides = sumMoney.divide(dmReadingRoomConfigs.get(0).getOverdueAmount(),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal bigDecimal = BigDecimal.valueOf(Long.valueOf(item.getOverdueDay().toString()));
                // 剩余可以扣几次
                 BigDecimal subtract =bigDecimal.subtract(divides);
                 //生成扣费记录
                DmReadingRoomApplay  dmReadingRoomApplay = new DmReadingRoomApplay();
                dmReadingRoomApplay.setReadingRoomId(item.getReadingRoomId().toString());//阅览记录id
                if (subtract.compareTo(BigDecimal.ZERO) > 1){
                    //扣款金额
                    BigDecimal multiply = dmReadingRoomConfigs.get(0).getOverdueAmount().multiply(subtract);
                    // 判断  扣款金额 加上 已经扣的金额 是否大于上限金额
                    //一共扣款金额
                    if (multiply.add(sumMoney).compareTo(dmReadingRoomConfigs.get(0).getOverdueAmountMax())<1){  //正好相等
                        dmReadingRoomApplay.setReadomgRoomApplayMoney(multiply);//消费金额
                    }else if (multiply.add(sumMoney).compareTo(dmReadingRoomConfigs.get(0).getOverdueAmountMax()) > 1) { //扣款金额大于上限  上限-扣款金额
                        dmReadingRoomApplay.setReadomgRoomApplayMoney(dmReadingRoomConfigs.get(0).getOverdueAmountMax().subtract((multiply.add(sumMoney))));
                    }else {
                        dmReadingRoomApplay.setReadomgRoomApplayMoney(multiply);
                    }
                }
                dmReadingRoomApplay.setOverdueAmount(dmReadingRoomConfigs.get(0).getOverdueAmount());//逾期金额
                dmReadingRoomApplay.setOverdueAmountMax(dmReadingRoomConfigs.get(0).getOverdueAmountMax());//最大上限金额
                dmReadingRoomApplay.setReadomgRoomApplayType("逾期扣款");//消费类型
                dmReadingRoomApplayService.create(dmReadingRoomApplay);
                //同步扣款接口
//                HttpRequest.post(APPLAY_URL).form("cid",item.getDmUser().getCardId(),"cno",item.getReadingRoomId(),"account",0,"amt",Integer.valueOf((subtract.multiply(BigDecimal.valueOf(100))).toString()),"invoice","222").execute().body();

            }
        });

    }
    /**
     * 逾期提醒
     */
    public void ReadRoomConfigMessage() throws ParseException {
        //先查询逾期配置文件
        List<DmReadingRoomConfig> dmReadingRoomConfig = dmReadingRoomConfigRepository.findAll();
       //查询还未逾期的
        /**
         *  查询逾期的记录
         */
        //新建时间格式化对象SimpleDateFormat
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //格式化当前时间
         Date date = new Date();
        String read_end_time = simpleDateFormat.format(date);
        // 传入参数进行查询未逾期记录
        List<DmReadingRoom> readRoomByOverdueFalse = dmReadingRoomRepository.findReadRoomByOverdue(0, read_end_time);
        // 传入参数进行查询逾期记录
        List<DmReadingRoom> readRoomByOverdueTrue = dmReadingRoomRepository.findReadRoomByOverdue(1, read_end_time);
        // 如果未配置就无须发送消息 直接退出
        if (dmReadingRoomConfig.get(0) == null || !StringUtils.isNotEmpty(dmReadingRoomConfig.get(0).getOverdueTimeMsg())){
            return;
        }

        // 有配置则 拿取配置的逾期配置
        String[] split = dmReadingRoomConfig.get(0).getOverdueTimeMsg().split(",");

        //通知未逾期的

        for (DmReadingRoom err : readRoomByOverdueFalse) {

           if (date.compareTo(err.getReadEndTime())<0){
               int i = DateUtil.daysBetween(err.getReadEndTime(), date);
               for (String s : split) {
                   if (i ==  Integer.valueOf(s) && Integer.valueOf(s)<0){
                       //发送消息
                       switch (dmReadingRoomConfig.get(0).getBorrowMsgType()){
                           case "00":
                               //邮箱
                               log.info("通过邮箱发送通知");
                               break;
                           case "01":
                               //手机APP
                               log.info("通过手机App发送通知");
                               sendApp(err.getDmUser().getCardId(),err.getReadingRoomId().toString(),"您在阅览室借阅的"+err.getBookName()+"将于"+err.getReadEndTime()+"到期,请及时归还");
                               break;
                           case "02":
                               //手机短信
                               log.info("通过手机短信发送通知");
//                               sendMsg(err.getDmUser().getContacts(),"您在阅览室借阅的"+err.getBookName()+"将于"+err.getReadEndTime()+"到期,请及时归还");
                               sendApp(err.getDmUser().getCardId(),err.getReadingRoomId().toString(),"您在阅览室借阅的"+err.getBookName()+"将于"+err.getReadEndTime()+"到期,请及时归还");
                               break;
                       }
                   }
               }
           }


        }

        //通知逾期的
        for (DmReadingRoom  ok : readRoomByOverdueTrue) {
            for (String s : split) {
                if (ok.getOverdueDay() ==  Integer.valueOf(s) && Integer.valueOf(s)>0){

                     List<DmReadingRoomApplay> applayByRoomId = dmReadingRoomApplayService.findApplayNowByRoomId(ok.getReadingRoomId());
                    //发送消息
                    switch (dmReadingRoomConfig.get(0).getBorrowMsgType()){
                        case "00":
                            //邮箱
                            System.out.println("邮箱");
                            break;
                        case "01":
                            //手机
                            System.out.println("手机");
                            sendApp(ok.getDmUser().getCardId(),ok.getReadingRoomId().toString(),"您在阅览室借阅的"+ok.getBookName()+"已逾期,今日将从您的消费账号中扣除"+applayByRoomId.get(0).getReadomgRoomApplayMoney() != null?applayByRoomId.get(0).getReadomgRoomApplayMoney().toString():'0'+"作为逾期罚金。请您及时归还");
                            break;
                        case "02":
                            //短信
                            System.out.println("短信");
                            sendMsg(ok.getDmUser().getContacts(),"您在阅览室借阅的"+ok.getBookName()+"已逾期,今日将从您的消费账号中扣除"+applayByRoomId.get(0).getReadomgRoomApplayMoney() != null?applayByRoomId.get(0).getReadomgRoomApplayMoney().toString():'0'+"作为逾期罚金。请您及时归还");
                            break;
                    }
                }
            }
        }

    }


    public Connection getSqlServerConnection() throws Exception {
        String user = "sa";
        String password = "sa123456!";
        String url = "jdbc:sqlserver://10.208.128.18:1433;DatabaseName=DBLIBRARY;";
//        String password = "123456";
//        String url = "jdbc:sqlserver://localhost:1433;DatabaseName=DBLIBRARY;";
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        return DriverManager.getConnection(url, user, password);
    }

    public  void synchronizationBookCollection() throws Exception {
        Connection conn;
        Statement stmt;
        ResultSet rs;
        String sql = "SELECT 控制号, 登录号, 条形码, 分配地址, 入库时刻 FROM Dblibrary.dbo.v_ts_txm";
        try {
            // 连接数据库
            conn = getSqlServerConnection();
            // 建立Statement对象
            stmt = conn.createStatement();
            // 执行数据库查询语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                Long ts_id = rs.getString("控制号") == null?null:Long.valueOf(rs.getString("控制号"));
                String login_num = rs.getString("登录号") == null?null:rs.getString("登录号"); //图书标识
                String collection_sin = rs.getString("条形码") == null?null:rs.getString("条形码"); //唯一id
                String ts_collection_address = rs.getString("分配地址") == null?null:rs.getString("分配地址");
                Timestamp create_time = rs.getString("入库时刻") == null?null:Timestamp.valueOf(rs.getString("入库时刻"));
                //新建阅览室藏书对象
                 DmTsCollection dmTsCollection = new DmTsCollection();
                dmTsCollection.setCollectionSin(collection_sin);
                dmTsCollection.setTsId(ts_id);
                dmTsCollection.setTsLoginNum(login_num);
                dmTsCollection.setTsCollectionAddress(ts_collection_address);
                dmTsCollection.setCreateTime(create_time);
                dmTsCollectionRepository.save(dmTsCollection);
            }
            if (rs != null) {
                rs.close();
                rs = null;
            }
            if (stmt != null) {
                stmt.close();
                stmt = null;
            }
            if (conn != null) {
                conn.close();
                conn = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.info("数据库连接失败");
        }
    }

    public  void synchronizationBookInfo() throws Exception {
        Connection conn;
        Statement stmt;
        ResultSet rs;
        String sql = "SELECT 控制号, 索取号, 正题名, 责任者, 出版者, 出版地, 出版日期, 页卷数, 标准编号, 获得方式 FROM Dblibrary.dbo.v_ts_info";
        try {
            // 连接数据库
            conn = getSqlServerConnection();
            // 建立Statement对象
            stmt = conn.createStatement();
            // 执行数据库查询语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                Long ts_id = rs.getString("控制号") == null?null:Long.valueOf(rs.getString("控制号"));
                String ts_type_num = rs.getString("索取号") == null?null:rs.getString("索取号");
                String ts_name = rs.getString("正题名") == null?null:rs.getString("正题名");
                String ts_author = rs.getString("责任者") == null?null:rs.getString("责任者");
                String ts_publish_name = rs.getString("出版者") == null?null:rs.getString("出版者");
                String ts_publish_address = rs.getString("出版地") == null?null:rs.getString("出版地");
                String ts_publish_time = rs.getString("出版日期") == null?null:rs.getString("出版日期");
                String ts_total_page = rs.getString("页卷数") == null?null:rs.getString("页卷数");
                String ts_num = rs.getString("标准编号") == null?null:rs.getString("标准编号");
                String ts_acquire_type = rs.getString("获得方式") == null?null:rs.getString("获得方式");
                //新建图书对象
                DmTsInfo dmTsInfo = new DmTsInfo();
                dmTsInfo.setTsPicture(null);
                dmTsInfo.setTsPublishTime(ts_publish_time);
                dmTsInfo.setTsPublishAddress(ts_publish_address);
                dmTsInfo.setTsNum(ts_num);
                dmTsInfo.setTsAcquireType(ts_acquire_type);
                dmTsInfo.setTsTotalPage(ts_total_page);
                dmTsInfo.setTsName(ts_name);
                dmTsInfo.setTsId(ts_id);
                dmTsInfo.setTsPublishName(ts_publish_name);
                dmTsInfo.setTsAuthor(ts_author);
                dmTsInfo.setTsTypeNum(ts_type_num);
                dmTsInfoRepository.save(dmTsInfo);
            }
            if (rs != null) {
                rs.close();
                rs = null;
            }
            if (stmt != null) {
                stmt.close();
                stmt = null;
            }
            if (conn != null) {
                conn.close();
                conn = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.info("数据库连接失败");
        }
    }


    public  void synchronizationReadRoom() throws Exception {
        Connection conn;
        Statement stmt;
        ResultSet rs;
        String sql = "SELECT 标识列, 读者证号, 读者姓名, 控制号, 条形码, 借出时刻, 应还时刻, 实还时刻, 借还标志 FROM Dblibrary.dbo.v_ts_ltxxb";
        try {
            // 连接数据库
            conn = getSqlServerConnection();
            // 建立Statement对象
            stmt = conn.createStatement();
            // 执行数据库查询语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                Long reading_room_id = rs.getString("标识列") == null?null:Long.valueOf(rs.getString("标识列"));
                String borrow_user_card = rs.getString("读者证号") == null?null:rs.getString("读者证号");
                String borrow_user_name = rs.getString("读者姓名") == null?null:rs.getString("读者姓名");
                Long book_id = rs.getString("控制号") == null?null:Long.valueOf(rs.getString("控制号"));
                String collection_sin = rs.getString("条形码") == null?null:rs.getString("条形码");
                Timestamp read_start_time = rs.getString("借出时刻") == null?null:Timestamp.valueOf(rs.getString("借出时刻") );
                Timestamp read_end_time = rs.getString("应还时刻") == null?null:Timestamp.valueOf(rs.getString("应还时刻") );
                Timestamp return_time = rs.getString("实还时刻") == null?null:Timestamp.valueOf(rs.getString("实还时刻") );
                String borrow_status = rs.getString("借还标志") == null?null:rs.getString("借还标志");
                //新建读者用户对象
                 DmUser byCardId = this.dmUserService.findByUserCardId(borrow_user_card);
                //新建阅览室记录对象
                 DmReadingRoom dmReadingRoom = new DmReadingRoom();
                dmReadingRoom.setReadingRoomId(reading_room_id); //主键id
                dmReadingRoom.setDmUser(byCardId);//读者证号
                dmReadingRoom.setBorrowUserName(borrow_user_name);//读者姓名
                DmTsInfo dmTsInfo = new DmTsInfo();
                dmTsInfo.setTsId(book_id);
                dmReadingRoom.setDmTsInfo(dmTsInfo);//关联书籍id
                dmReadingRoom.setCollectionSin(collection_sin);//条形码
                dmReadingRoom.setReadStartTime(read_start_time);//借阅时间啊
                dmReadingRoom.setReadEndTime(read_end_time);//借阅结束时间
                dmReadingRoom.setReturnTime(return_time);//归还时间
                dmReadingRoom.setBorrowStatus(borrow_status);//状态 O  借出   I 归还   不是数字
                // 判断是否逾期
                //  a.compareTo(c)
                // a比c晚 1 a比c早 -1 a相同c 0
                // 已经还了  但是
                 if (dmReadingRoom.getReturnTime() != null && dmReadingRoom.getReturnTime().compareTo(dmReadingRoom.getReadEndTime())<0 && dmReadingRoom.getBorrowStatus().equals("I")){
                     //代表已经还了  计算是否逾期
                     int i = DateUtil.daysBetween(dmReadingRoom.getReadEndTime(), dmReadingRoom.getReturnTime());
                     if (i>0){
                         dmReadingRoom.setOverdueDay(i); //逾期天数
                         dmReadingRoom.setIsOverdue(1);//是否逾期
                     }else {
                         dmReadingRoom.setOverdueDay(0); //逾期天数
                         dmReadingRoom.setIsOverdue(0);//是否逾期
                     }
                 }else

                     if (dmReadingRoom.getReturnTime() == null && dmReadingRoom.getBorrowStatus().equals("O")){
                     //还未还书
                     //如果逾期计算逾期几天了
                     int i = DateUtil.daysBetween(dmReadingRoom.getReadEndTime(), new Timestamp(System.currentTimeMillis()));
                     if (i>0){
                         dmReadingRoom.setOverdueDay(i); //逾期天数
                         dmReadingRoom.setIsOverdue(1);//是否逾期
                     }else {
                         dmReadingRoom.setOverdueDay(0); //逾期天数
                         dmReadingRoom.setIsOverdue(0);//是否逾期
                     }
                 }
                dmReadingRoomRepository.save(dmReadingRoom);


            }
            if (rs != null) {
                rs.close();
                rs = null;
            }
            if (stmt != null) {
                stmt.close();
                stmt = null;
            }
            if (conn != null) {
                conn.close();
                conn = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.info("数据库连接失败");
        }


    }



//    //app通知
    public void sendApp(String userId,String taskId,String sendContent){
        //app通知
        String url = "https://smartpark.caih.com/zkxt/api/thirdparty/v1/message/sendChatMessage";
        Map<String,Object> token = SecurityUtils.getToken("DMERPYT!@#$QWER2021+{:>");
        DmUser user =  dmUserService.findByCardId(userId);
        JSONObject query = new JSONObject();
        query.put("systemName","一卡通");
        query.put("sendId","dm_meeting|task_id|"+taskId);
        query.put("sendUserId",userId);
        JSONObject sendContentJSON = new JSONObject();
        sendContentJSON.put("text",sendContent);
        query.put("sendContent",sendContentJSON);
        query.put("usernames",user.getName());
        JSONObject param = new JSONObject();
        param.put("nonce",token.get("nonce"));
        param.put("timestamp",token.get("timestamp"));
        param.put("query",query);
        HttpRequest.get(url).header("XYTACCESSTOKEN", token.get("token").toString()).body(param.toJSONString()).execute().body();
    }

    //短信通知
    public void sendMsg(String phone,String sendContent){
        //app通知
        String url = "https://smartpark.caih.com/zkxt/api/thirdparty/v1/message/sendMsg";
        Map<String,Object> token = SecurityUtils.getToken("DMERPYT!@#$QWER2021+{:>");
        JSONObject query = new JSONObject();
        query.put("phone",phone);
        query.put("context",sendContent);
        JSONObject param = new JSONObject();
        param.put("nonce",token.get("nonce"));
        param.put("timestamp",token.get("timestamp"));
        param.put("query",query);
        HttpRequest.get(url).header("XYTACCESSTOKEN", token.get("token").toString()).body(param.toJSONString()).execute().body();
    }


}
