package com.its.vms.service;

import com.its.app.utils.Elapsed;
import com.its.app.utils.ItsUtils;
import com.its.vms.config.ApplicationConfig;
import com.its.vms.dao.mapper.VmsFormMapper;
import com.its.vms.domain.enums.eVmsFormType;
import com.its.vms.dto.TbVmsFormColrDto;
import com.its.vms.dto.TbVmsFormDto;
import com.its.vms.dto.TbVmsFormObjectDto;
import com.its.vms.dto.TbVmsSymbLibDto;
import com.its.vms.entity.TbVmsForm;
import com.its.vms.entity.TbVmsFormColr;
import com.its.vms.entity.TbVmsFormObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.File;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@SuppressWarnings("ResultOfMethodCallIgnored")
@Slf4j
@Service
@RequiredArgsConstructor
public class VmsFormService {

    private final ApplicationConfig config;
    private final VmsFormMapper mapper;
    private final VmsSymbService vmsSymbService;

    private final ConcurrentHashMap<Integer, TbVmsFormDto> dataMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<Integer, TbVmsFormColrDto> colrMap = new ConcurrentHashMap<>();

    public TbVmsFormDto find(Integer vmsFormId) {
        return this.dataMap.get(vmsFormId);
    }

    public Color getFormColor(Integer colrCd) {
        if (colrCd == 0) return Color.BLACK;
        if (colrCd == 1) return Color.RED;
        if (colrCd == 2) return Color.GREEN;
        if (colrCd == 3) return Color.YELLOW;
        TbVmsFormColrDto obj = this.colrMap.get(colrCd);
        if (obj != null) {
            return obj.getVmsFormColor();
        }
        if (colrCd == 4) return Color.ORANGE;
        if (colrCd == 5) return new Color(16776960);    // aqua

        return Color.BLACK;
    }

    public void loadDb() {
        loadVmsFormInfo();
        loadVmsFormObjectInfo();
        loadVmsFormColorInfo();
    }

    public void loadVmsFormInfo() {
        Elapsed elapsed = new Elapsed();
        try {
            List<TbVmsForm> result  = this.mapper.selectVmsFormInfo();
            log.info("VmsFormService.loadVmsFormInfo: {} EA", result.size());
            result.forEach(data -> {
                TbVmsFormDto obj = data.toDto();
                String updtDt = "";
                TbVmsFormDto oldObj = this.dataMap.get(obj.getVmsFormId());
                if (oldObj != null) {
                    updtDt = oldObj.getUpdtDt();
                }

                // 정적폼(홍보) 같은 경우 최초 또는 변경되었을 때에만 사용할수 있도록(제어기로 한번만 다운로드 할수 있도록)
                // 체크 플래그를 두어 확인할수 있도록 한다.
                if (obj.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue() && !Objects.equals(obj.getUpdtDt(), updtDt)) {
                    // 새롭게 제어기로 다운로드 해야되는 폼으로 설정
                    obj.setNewForm(true);
                }

                if (obj.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue() && obj.getVmsFormImag() != null) {
                    obj.setLocalFileName(this.config.getFtpStaticDir() + obj.getVmsFormId() + ".bmp");
                    obj.setFtpFileName(ApplicationConfig.FTP_STATIC + obj.getVmsFormId() + ".bmp");
                    File imagFile = new File(obj.getLocalFileName());
                    if (imagFile.exists()) {
                        imagFile.delete();
                    }
                    ItsUtils.saveByteArrayToFile(obj.getLocalFileName(), obj.getVmsFormImag());
                }

                if (obj.getVmsFormExpl() == null) {
                    obj.setVmsFormExpl("");
                }

                this.dataMap.put(obj.getVmsFormId(), obj);
            });
        }
        catch (Exception e) {
            log.error("VmsFormService.loadVmsFormInfo: {}.", e.toString());
        }
        log.info("VmsFormService.loadVmsFormInfo: {} ms.", elapsed.milliSeconds());
    }

    public void loadVmsFormObjectInfo() {
        Elapsed elapsed = new Elapsed();
        try {
            List<TbVmsFormObject> result  = this.mapper.selectVmsFormObjectInfo();
            log.info("VmsFormService.loadVmsFormObjectInfo: {} EA", result.size());
            result.forEach(data -> {
                TbVmsFormObjectDto obj = data.toDto();
                TbVmsFormDto formObj = this.dataMap.get(obj.getVmsFormId());
                if (formObj == null) {
                    log.error("VmsFormService.loadVmsFormObjectInfo: Not Found VMS Form {}.", obj.getVmsFormId());
                    return;
                }

                int objType = obj.getVmsFormObjectTypeCd();

                if (isObjectBitmap(obj.getVmsFormObjectTypeCd())) {
                    // 심벌라이브러리를 참조하는 객체인데 참조하는 심벌라이브러리가 없으면 객체를 추가하지 않는다.
                    TbVmsSymbLibDto vmsSymbLib = this.vmsSymbService.find(obj.getSymbLibNmbr()+"0");
                    if (vmsSymbLib == null) {
                        log.error("VmsFormService.loadVmsFormObjectInfo: VMF Form Object Symbol Library not Found {}, {}.", obj.getVmsFormId(), obj.getSymbLibNmbr());
                        return;
                    }
                    if (objType == 3) {
                        // 소통정보배경 이미지
                        formObj.setTrfBackImgId(vmsSymbLib.getMemSymbLibNmbr());
                    }
                    obj.setBitmapType(vmsSymbLib.getImagType());
                    obj.setBitmapId(vmsSymbLib.getDnldSymbLibNmbr());
                }

                // 폼정보에 오브젝트 객체를 추가
                formObj.getObjects().add(obj);

                if (formObj.getVmsFormTypeCd() == eVmsFormType.eFormTp_figure.getValue()) {
                    // 도형식 소통정보 폼인데 구간 소통정보를 하단에 표출하는 경우
                    // 하나의 폼이 여러개의 소통정보를 표출되도록 하기 위함
                    switch(objType) {
                        //////////////////////// 20200515 추가함(S)
                        case  0://,  ,  @문자열
                        case  1://,  ,  @심볼
                        case  2://,  ,  @이미지
                            if ("F".equals(obj.getTrfcFillCd())) {
                                //하단고정일 경우 도형식하단에 표출할 소통정보가 없을 경우 표출하는 정보임
                                formObj.setBottomFixedText(true);
                            }
                            break;
                        //////////////////////// 20200515 추가함(E)
                        case 11://, '	@구간명
                        case 12://, '	@시점명
                        case 13://, '	@종점명
                        case 14://, '	@소통상황
                        case 15://, '	@통행시간
                        case 16://, '	@통행속도
                        case 17://, '	@소통정보이미지
                        case 18://, '	@지점명
                            formObj.setBottomTrfIfsc(true);
                            break;
                        case 93://, '	@축시점명(순환)
                        case 94://, '	@축종점명(순환)
                        case 95://, '	@축소통상황(순환)
                        case 96://, '	@축통행시간(순환)
                            formObj.setBottomTrfAxis(true);
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        catch (Exception e) {
            log.error("VmsFormService.loadVmsFormObjectInfo: {}.", e.toString());
        }
        log.info("VmsFormService.loadVmsFormObjectInfo: {} ms.", elapsed.milliSeconds());
    }

    public static boolean isObjectBitmap(int objType) {
// 200: //동영상
// 300: //스티리밍영상
//            case 200: //동영상
//            case 300: //스티리밍영상
        return (objType ==   1 || //심볼
                objType ==   2 || //이미지(파일에서 직접입력한것임)
                objType ==   3 || //소통정보배경이미지
                objType ==  17 || //소통정보이미지1
                objType ==  27 || //소통정보이미지2
                objType ==  37 || //소통정보이미지3
                objType ==  47 || //소통정보이미지4
                objType == 200 || //동영상이미지
                objType == 300 || //스트리밍영상이미지
                objType == 406 || //통합대기등급 이미지
                objType == 407 || //미세먼지등급 이미지
                objType == 408 || //초미세먼지등급 이미지
                objType == 413 || //오존등급이미지
                objType == 167);  //우회소통정보이미지
    }

    public static boolean isObjectBitmapId(int objType) {
        return (objType ==   1 || //심볼
                objType ==   2 || //이미지(파일에서 직접입력한것임)
                objType ==  17 || //소통정보이미지1
                objType ==  27 || //소통정보이미지2
                objType ==  37 || //소통정보이미지3
                objType ==  47 || //소통정보이미지4
                objType == 200 || //동영상이미지
                objType == 300 || //스트리밍영상이미지
                objType == 406 || //통합대기등급 이미지
                objType == 407 || //미세먼지등급 이미지
                objType == 408 || //초미세먼지등급 이미지
                objType == 413 || //오존등급이미지
                objType == 167);  //우회소통정보이미지
    }
    public void loadVmsFormColorInfo() {
        Elapsed elapsed = new Elapsed();
        try {
            List<TbVmsFormColr> result  = this.mapper.selectVmsFormColorInfo();
            log.info("VmsFormService.loadVmsFormColorInfo: {} EA", result.size());
            result.forEach(data -> {
                TbVmsFormColrDto obj = data.toDto();
                this.colrMap.put(obj.getVmsFormColrCd(), obj);
            });
        }
        catch (Exception e) {
            log.error("VmsFormService.loadVmsFormInfo: {}.", e.toString());
        }
        log.info("VmsFormService.loadVmsFormColorInfo: {} ms.", elapsed.milliSeconds());
    }

    /**
     * 내부에서 사용하는 심벌 라이브러리 번호를 제어기로 다운로드하는 BitmapId 로 변환한다.
     * @param formId : 10013 -> 1130
     * @return
     */
    public static int getDnldFormNo(Integer formId) {
        int id = formId % 10000;
        return 1000 + (id * 10);
    }

}
