package cokr.xit.ens.core.init;

import cokr.xit.ens.biz.iup.code.IupPrcsCd;
import cokr.xit.ens.biz.iup.code.IupSendTypeCd;
import cokr.xit.ens.biz.iup.domain.FsJob;
import cokr.xit.ens.biz.iup.domain.TbInputDataBulkTest;
import cokr.xit.ens.biz.iup.domain.TbInputDataXit;
import cokr.xit.ens.biz.iup.domain.TbInputXit;
import cokr.xit.ens.biz.iup.domain.repository.FsJobRepository;
import cokr.xit.ens.biz.iup.domain.repository.TbInputDataBulkTestRepository;
import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository;
import cokr.xit.ens.biz.iup.domain.repository.TbInputXitRepository;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.TmpltMng;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.OrgMngRepository;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.TmpltMngRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Profile;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

//@Component
@Transactional
@Profile({"local", "local-maria", "local-oracle"})
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;
    @Autowired
    private FsJobRepository fsJobRepository;
    @Autowired
    private TbInputXitRepository tbInputXitRepository;
    @Autowired
    private TbInputDataXitRepository tbInputDataXitRepository;
    @Autowired
    private TbInputDataBulkTestRepository tbInputDataBulkTestRepository;
    @Autowired
    private OrgMngRepository orgMngRepository;
    @Autowired
    private TmpltMngRepository tmpltMngRepository;

    private final String REG_ID = "ENS_SYS";

    private int DATA_UNIT = 100;

    @Override
    public void run(ApplicationArguments args) throws Exception {


        try {
            /**
             * IUP Sample 데이터
             */
            List<FsJob> fsJobList = getFsJob();
            List<TbInputXit> tbInputXitList = getTbInput(fsJobList.get(0));
            fsJobRepository.saveAll(fsJobList);
//            tbInputXitRepository.saveAll(tbInputXitList);
//            tbInputXitList.stream()
////                    .parallel()
//                    .forEach(row ->
//                            tbInputDataXitRepository.saveAll(getTbInputData(row))
//                    );

            /**
             * ENS Sample 데이터
             */
            List<OrgMng> orgMngs = getOrgMng();
            orgMngRepository.saveAll(orgMngs);
            tmpltMngRepository.saveAll(getTmpltMng(orgMngs));

        } catch (Exception e) {
            e.printStackTrace();
        }


        /**
         * Bulk Insert Test - use saveAll
         */
//        tbInputDataBulkTestRepository.saveAll(getTbInputDataBulkTest(100000));
        /**
         * Bulk Insert Test - use save
         */
//        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
//        String today = date.format(new Date());
//
//        for(int i=0; i< 100000; i++){
//            tbInputDataBulkTestRepository.save(getOneTbInputDataBulkTest(i, today));
//        }
    }

    /**
     * IUP
     *
     * @return
     */
    private List<FsJob> getFsJob() {

        return Arrays.asList(
                FsJob.builder().jobCd("E1001").orgCd("0005").jobName("민자고속도로 미납통행료 독촉장").templateCd("CEPHIS_001").useYn("Y").regId(REG_ID).build()
        );
    }


    /**
     * IUP 발송마스터 생성
     *
     * @return
     */
    private List<TbInputXit> getTbInput(FsJob fsJob) {
        List<TbInputXit> list = new ArrayList<>();
        SimpleDateFormat date = new SimpleDateFormat("yyyyMMddHHmmsss");
        for (int i = 1; i <= 4; i++) {
            String today = date.format(new Date());
            list.add(cokr.xit.ens.biz.iup.domain.TbInputXit.builder()
                            .lnkInputId(Long.valueOf(today + ("" + i)))
                            .orgCd("0005")
                            .fsJob(fsJob)
                            .totCnt(Long.valueOf((DATA_UNIT * i)))
                            .prcsCd(IupPrcsCd.TGRG)
                            .errMsg(null)
//                        .runDt()
                            .expiresDt(LocalDateTime.of(2022, 2, 17, 15, 30, 00))
                            .sendType(IupSendTypeCd.NI)
                            .regId(REG_ID)
                            .regDt(LocalDateTime.now())
                            .runDt(LocalDateTime.now())
                            .rcptDt(LocalDateTime.now().toString())
                            .payExpiresDt(LocalDateTime.of(2022, 3, 17, 23, 59, 59))
                            .build()
            );
        }

        return list;
    }

    /**
     * IUP 발송상세 생성
     *
     * @param tbInputXit
     * @return
     */
    private List<TbInputDataXit> getTbInputData(TbInputXit tbInputXit) {
        List<TbInputDataXit> list = new ArrayList<>();

        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
        String today = date.format(new Date());

        for (int i = 0; i < tbInputXit.getTotCnt().intValue(); i++) {
            list.add(TbInputDataXit.builder()
                            .tbInputXit(tbInputXit)
                            .dataId(today + UUID.randomUUID())
//                    .dataId(String.format("%s%012d",today, i))
                            .sid("8611281234567")
                            .name("홍길동" + (i + 1))
                            .birthday("19861128")
                            .gender("1")
                            .msgData("{\"~~@@!!CAR_NO!!@@~~\":\"60러5503\",\"~~@@!!DEGREE!!@@~~\":\"2\",\"~~@@!!FEE!!@@~~\":\"3,200\",\"~~@@!!YYYY!!@@~~\":\"2022\",\"~~@@!!MM!!@@~~\":\"03\",\"~~@@!!DD!!@@~~\":\"17\",\"~~@@!!BANK!!@@~~\":\"우체국\",\"~~@@!!ACCOUNT!!@@~~\":\"8608-90-80973468\",\"~~@@!!HISTORY!!@@~~\":\"-2022-01-08 17:19 (불암산 1,400)\n" +
                                    "-2022-01-08 16:58 (양주 1,800)\",\"~~@@!!CALL_NO!!@@~~\":\"(031)522-6300~1\",\"~~@@!!HOMEPAGE!!@@~~\":\"https://seoulbeltway.co.kr/main/esccar.jsp\"}")
                            .msgDtlData(null)
                            .regId(REG_ID)
                            .regDt(java.sql.Date.valueOf(LocalDate.now()))
                            .payStatusCd("OK")
                            .payUrl(null)
                            .carNo("48나" + i)
                            .build()
            );

        }

        return list;
    }

    /**
     * IUP 발송상세 벌크 insert 생성
     *
     * @return
     */
    private List<TbInputDataBulkTest> getTbInputDataBulkTest(int cnt) {
        List<TbInputDataBulkTest> list = new ArrayList<>();

        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
        String today = date.format(new Date());

        for (int i = 0; i < cnt; i++) {
            list.add(getOneTbInputDataBulkTest(i, today));
        }

        return list;
    }

    private TbInputDataBulkTest getOneTbInputDataBulkTest(int i, String today) {

        return TbInputDataBulkTest.builder()
                .dataId(today + UUID.randomUUID())
                .sid("8611281234567")
                .name("홍길동" + (i + 1))
                .birthday("19861128")
                .gender("1")
                .msgData("{\"~~@@!!CAR_NO!!@@~~\":\"60러5503\",\"~~@@!!DEGREE!!@@~~\":\"2\",\"~~@@!!FEE!!@@~~\":\"3,200\",\"~~@@!!YYYY!!@@~~\":\"2022\",\"~~@@!!MM!!@@~~\":\"03\",\"~~@@!!DD!!@@~~\":\"17\",\"~~@@!!BANK!!@@~~\":\"우체국\",\"~~@@!!ACCOUNT!!@@~~\":\"8608-90-80973468\",\"~~@@!!HISTORY!!@@~~\":\"-2022-01-08 17:19 (불암산 1,400)\n" +
                        "-2022-01-08 16:58 (양주 1,800)\",\"~~@@!!CALL_NO!!@@~~\":\"(031)522-6300~1\",\"~~@@!!HOMEPAGE!!@@~~\":\"https://seoulbeltway.co.kr/main/esccar.jsp\"}")
                .msgDtlData(null)
                .regId(REG_ID)
                .regDt(java.sql.Date.valueOf(LocalDate.now()))
                .payStatusCd("OK")
                .payUrl(null)
                .carNo("48나" + i)
                .build();
    }


    private List<OrgMng> getOrgMng() {

        return Arrays.asList(
                OrgMng.builder()
                        .orgCd("0005")
                        .orgNm("단순미납기관")
                        .kkoBpCsignYn("N")
                        .build()
                , OrgMng.builder()
                        .orgCd("0006")
                        .orgNm("강제징수기관")
                        .kkoBpCsignYn("N")
                        .build()
        );
    }

    private List<TmpltMng> getTmpltMng(List<OrgMng> orgMngs) {
        List<TmpltMng> tmpltMngs = orgMngs.stream()
                .map(orgMng -> TmpltMng.builder()
//                        .orgCd(orgCd)
                        .orgMng(orgMng)
                        .tmpltCd("CEPHIS_001")
                        .title("유료도로 미납통행료 1차 안내문")
                        .message("민자도로 관리지원센터에서 #{TARGET_NAME}님께 발송한 미납통행료 고지서가 도착했습니다.\n" +
                                "\n" +
                                "인천대교 미납통행료 1차 안내문\n" +
                                "\n" +
                                "□ 차량번호: #{CAR_NO}\n" +
                                "□ 노선명: 인천대교\n" +
                                "□ 미납통행일시\n" +
                                "#{HISTORY}\n" +
                                "□ 미납통행료: #{FEE}원\n" +
                                "□ 납부기한: #{YYYY}년 #{MM}월 #{DD}일까지\n" +
                                "□ 납부방법\n" +
                                "- 하단의 (납부하기) 클릭 또는\n" +
                                "- 가상계좌(#{BANK} #{ACCOUNT})\n" +
                                "□ 홈페이지 문의\n" +
                                "- #{HOMEPAGE}\n" +
                                "\n" +
                                "※ 본 모바일 알림톡은 유료도로법에 따라 민자도로 관리지원센터에서 통행료 수납을 위탁 받아 발송한 것이며, 알림톡 수신 시 종이고지서는 발송되지 않습니다.\n" +
                                "\n" +
                                "문의처 : #{REP_CALL_NO}")
                        .useYn("Y")
                        .registId("ENS_SYS")
                        .build())
                .collect(Collectors.toList());
        return tmpltMngs;
    }
}
