package com.its.pis.dao.mapper.batch;

import com.its.app.utils.Elapsed;
import com.its.pis.dao.mapper.BatchDaoService;
import com.its.pis.entity.TbPrkPlceStts;
import com.its.pis.websocket.message.c2f.prk_plce_rl_time.PrkColctDeviceInfo;
import com.its.pis.websocket.message.c2f.prk_plce_rl_time.RtArInfr;
import com.its.pis.websocket.message.c2f.prk_plce_rl_time.RtFlrInfr;
import com.its.pis.websocket.message.c2f.prk_plce_rl_time.RtPrvusePrkarInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Repository
public class PrkPlceDao extends BatchDaoService {

    public PrkPlceDao(SqlSessionFactory sqlSessionFactory) {
        super(sqlSessionFactory);
        this.serviceName = "PrkPlceDao";
        this.mapperName  = "";//""com.its.pis.mapper.batchPrkPlceMapper.";
    }

    public List<HashMap<String, Object>> getSttsList(List<TbPrkPlceStts> req) {
        List<HashMap<String, Object>> lists = new ArrayList<>();
        req.forEach(obj -> {
            HashMap<String, Object> param = new HashMap<>();
            param.put("PRK_PLCE_NMBR", obj.getPRK_PLCE_NMBR());
            param.put("UPDT_DT",       obj.getUPDT_DT());
            param.put("CMNC_STTS_CD",  obj.getCMNC_STTS_CD());
            lists.add(param);
        });
        return lists;
    }

    public int updatePrkPlceStts(List<TbPrkPlceStts> req, boolean isHistory) {
        //log.info("{}.updatePrkPlceStts: START. {} EA. History {}", this.serviceName, req.size(), isHistory);
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchUpdatePrkPlceStts";
            total += updateBatch(this.mapper, getSttsList(req));

            sqlSession.commit();
        } catch(Exception e) {
            log.error("updatePrkPlceStts: Exception, {}, {}", req, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.updatePrkPlceStts: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

    public int insertPrkPlceSttsHs(List<TbPrkPlceStts> req) {
        //log.info("{}.insertPrkPlceSttsHs: START. {} EA.", this.serviceName, req.size());
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchInsertPrkPlceSttsHs";
            total += insertBatch(this.mapper, getSttsList(req));

            sqlSession.commit();
        } catch(Exception e) {
            log.error("insertPrkPlceSttsHs: Exception, {}, {}", req, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.insertPrkPlceSttsHs: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

    public int updateRlTimeFlr(String PRK_PLCE_NMBR, String DATA_COLCT_TIME, List<RtFlrInfr> reqList) {
        if (reqList == null || reqList.size() == 0) {
            log.info("{}.updateRlTimeFlr: Data Not Exist.", this.serviceName);
            return 0;
        }
        //log.info("{}.updateRlTimeFlr: START. {} EA.", this.serviceName, reqList.size());
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            List<HashMap<String, Object>> lists = new ArrayList<>();
            reqList.forEach(obj -> {
                HashMap<String, Object> param = new HashMap<>();
                param.put("PRK_PLCE_NMBR",           PRK_PLCE_NMBR);
                param.put("FLR_NO",                  obj.getFlr_no());
                param.put("FLR_PRK_CMPRT_CO",        obj.getFlr_prk_cmprt_co());
                param.put("FLR_REMNDR_PRK_CMPRT_CO", obj.getFlr_remndr_prk_cmprt_co());
                param.put("DATA_COLCT_TIME",         DATA_COLCT_TIME);
                lists.add(param);
            });

            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchUpdateRlTimeFlr";
            total += updateBatch(this.mapper, lists);

            sqlSession.commit();
        } catch(Exception e) {
            log.error("updateRlTimeFlr: Exception, {}, {}", reqList, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.updateRlTimeFlr: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

    public int updateRlTimeAr(String PRK_PLCE_NMBR, List<RtArInfr> reqList) {
        if (reqList == null || reqList.size() == 0) {
            log.info("{}.updateRlTimeAr: Data Not Exist.", this.serviceName);
            return 0;
        }
        //log.info("{}.updateRlTimeAr: START. {} EA.", this.serviceName, reqList.size());
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            List<HashMap<String, Object>> lists = new ArrayList<>();
            reqList.forEach(obj -> {
                HashMap<String, Object> param = new HashMap<>();
                // TODO: 20240830: ArNo값이 NULL 로 들어온다.
                if (obj.getAr_no() == null || obj.getAr_no().isEmpty()) {
                    log.warn("batchUpdateRlTimeAr: RtArInfr.ArNo is Empty: {}, {}", PRK_PLCE_NMBR, obj);
                    obj.setAr_no("A");
                }
                if (obj.getFlr_no() == null || obj.getFlr_no().isEmpty()) {
                    log.warn("batchUpdateRlTimeAr: RtArInfr.FlrNo is Empty: {}, {}", PRK_PLCE_NMBR, obj);
                    obj.setFlr_no("1F");
                }
                param.put("PRK_PLCE_NMBR",          PRK_PLCE_NMBR);
                param.put("FLR_NO",                 obj.getFlr_no());
                param.put("AR_NO",                  obj.getAr_no());
                param.put("AR_PRK_CMPRT_CO",        obj.getAr_prk_cmprt_co());
                param.put("AR_REMNDR_PRK_CMPRT_CO", obj.getAr_remndr_prk_cmprt_co());
                lists.add(param);
            });

            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchUpdateRlTimeAr";
            total += updateBatch(this.mapper, lists);

            sqlSession.commit();
        } catch(Exception e) {
            log.error("updateRlTimeAr: Exception, {}, {}", reqList, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.updateRlTimeAr: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

    public int updateRlTimePrv(String PRK_PLCE_NMBR, List<RtPrvusePrkarInfo> reqList) {
        if (reqList == null || reqList.size() == 0) {
            log.info("{}.updateRlTimePrv: Data Not Exist.", this.serviceName);
            return 0;
        }
        //log.info("{}.updateRlTimePrv: START. {} EA.", this.serviceName, reqList.size());
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            List<HashMap<String, Object>> lists = new ArrayList<>();
            reqList.forEach(obj -> {
                HashMap<String, Object> param = new HashMap<>();
                param.put("PRK_PLCE_NMBR",               PRK_PLCE_NMBR);
                param.put("VHCTY_AR_SE",                  obj.getVhcty_ar_se());
                param.put("VHCTY_AR_PRK_CMPRT_CO",        obj.getVhcty_ar_prk_cmprt_co());
                param.put("VHCTY_AR_REMNDR_PRK_CMPRT_CO", obj.getVhcty_ar_remndr_prk_cmprt_co());
                lists.add(param);
            });

            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchUpdateRlTimePrv";
            total += updateBatch(this.mapper, lists);

            sqlSession.commit();
        } catch(Exception e) {
            log.error("updateRlTimePrv: Exception, {}, {}", reqList, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.updateRlTimePrv: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

    public int updateRlTimeDev(String PRK_PLCE_NMBR, List<PrkColctDeviceInfo> reqList) {
        if (reqList == null || reqList.size() == 0) {
            log.info("{}.updateRlTimeDev: Data Not Exist.", this.serviceName);
            return 0;
        }
        //log.info("{}.updateRlTimeDev: START. {} EA.", this.serviceName, reqList.size());
        Elapsed elapsed = new Elapsed();
        int total = 0;
        SqlSession sqlSession = null;
        try {
            List<HashMap<String, Object>> lists = new ArrayList<>();
            reqList.forEach(obj -> {
                HashMap<String, Object> param = new HashMap<>();
                param.put("PRK_PLCE_NMBR",      PRK_PLCE_NMBR);
                param.put("DEVICE_ID",          obj.getDevice_id());
                param.put("DEVICE_TYPE",        obj.getDevice_type());
                param.put("PRK_UNIT_ID",        obj.getPrk_unit_id());
                param.put("TYPED_PARKING_LOTS", obj.getTyped_parking_lots());
                param.put("OCCUPATION",         obj.getOccupation());
                param.put("CONNECTED",          obj.getConnect());
                lists.add(param);
            });

            sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);

            this.mapper = this.mapperName + "batchUpdateRlTimeDev";
            total += updateBatch(this.mapper, lists);

            sqlSession.commit();
        } catch(Exception e) {
            log.error("updateRlTimeDev: Exception, {}, {}", reqList, e.getMessage());
        }
        finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        if (elapsed.milliSeconds() > 1000) {
            log.info("{}.updateRlTimePrv: ..END. {} EA. {} ms.", this.serviceName, total, elapsed.milliSeconds());
        }
        return total;
    }

}
