package com.its.op.entity.its.scrs;

import com.its.op.dto.its.scrs.TbScSgnlCtlrDto;
import com.its.op.dto.its.scrs.TbScSgnlCtlrPhaseDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import javax.persistence.*;
import java.io.Serializable;

/**
 * 신호 제어기 Entity Class
 */
@Getter
@NoArgsConstructor//(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
@ApiModel("신호 제어기")
@Entity
@Table(name = "TB_SC_SGNL_CTLR")
public class TbScSgnlCtlr implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty("신호 교차로 번호")  // N NUMBER(4)
    @Id
    @Column(name = "SGNL_IXR_NMBR", nullable = false, columnDefinition = "NUMBER", length = 4)
    private Integer sgnlIxrNmbr;

    @ApiModelProperty("X 좌표")  // Y NUMBER(10)
    @Column(name = "X_CRDN", columnDefinition = "NUMBER", length = 10)
    private Long xCrdn;

    @ApiModelProperty("Y 좌표")  // Y NUMBER(10)
    @Column(name = "Y_CRDN", columnDefinition = "NUMBER", length = 10)
    private Long yCrdn;

    @ApiModelProperty("A링 1현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_1PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring1phasCd;

    @ApiModelProperty("A링 2현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_2PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring2phasCd;

    @ApiModelProperty("A링 3현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_3PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring3phasCd;

    @ApiModelProperty("A링 4현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_4PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring4phasCd;

    @ApiModelProperty("A링 5현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_5PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring5phasCd;

    @ApiModelProperty("A링 6현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_6PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring6phasCd;

    @ApiModelProperty("A링 7현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_7PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring7phasCd;

    @ApiModelProperty("A링 8현시 코드")  // Y NUMBER(7)
    @Column(name = "ARING_8PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer aring8phasCd;

    @ApiModelProperty("B링 1현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_1PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring1phasCd;

    @ApiModelProperty("B링 2현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_2PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring2phasCd;

    @ApiModelProperty("B링 3현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_3PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring3phasCd;

    @ApiModelProperty("B링 4현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_4PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring4phasCd;

    @ApiModelProperty("B링 5현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_5PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring5phasCd;

    @ApiModelProperty("B링 6현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_6PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring6phasCd;

    @ApiModelProperty("B링 7현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_7PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring7phasCd;

    @ApiModelProperty("B링 8현시 코드")  // Y NUMBER(7)
    @Column(name = "BRING_8PHAS_CD", columnDefinition = "NUMBER", length = 7)
    private Integer bring8phasCd;

    @OneToOne
    @JoinColumn(insertable=false, updatable=false, name="SGNL_IXR_NMBR", referencedColumnName = "SGNL_IXR_NMBR")
    @NotFound(action = NotFoundAction.IGNORE)
    private TbScSgnlIxrStts stts;

    public TbScSgnlCtlrDto toDto() {
        String xCrdn = String.format("%09d", this.xCrdn);
        String yCrdn = String.format("%09d", this.yCrdn);
        Double x_crdn = (Integer.parseInt(xCrdn) / 1000000.);
        Double y_crdn = (Integer.parseInt(yCrdn) / 1000000.);
        return TbScSgnlCtlrDto.builder()
                .sgnlIxrNmbr(this.sgnlIxrNmbr)
                .xCrdn(x_crdn)
                .yCrdn(y_crdn)
                .aring1phasCd(this.aring1phasCd)
                .aring2phasCd(this.aring2phasCd)
                .aring3phasCd(this.aring3phasCd)
                .aring4phasCd(this.aring4phasCd)
                .aring5phasCd(this.aring5phasCd)
                .aring6phasCd(this.aring6phasCd)
                .aring7phasCd(this.aring7phasCd)
                .aring8phasCd(this.aring8phasCd)
                .bring1phasCd(this.bring1phasCd)
                .bring2phasCd(this.bring2phasCd)
                .bring3phasCd(this.bring3phasCd)
                .bring4phasCd(this.bring4phasCd)
                .bring5phasCd(this.bring5phasCd)
                .bring6phasCd(this.bring6phasCd)
                .bring7phasCd(this.bring7phasCd)
                .bring8phasCd(this.bring8phasCd)
                .build();
    }

    public TbScSgnlCtlr(Integer sgnlIxrNmbr) {
        this.sgnlIxrNmbr = sgnlIxrNmbr;
    }

    public void updateInfo(TbScSgnlCtlrDto.TbScSgnlCtlrUpdReq req) {
        this.xCrdn = (long)(req.getXCrdn() * 1000000L);
        this.yCrdn = (long)(req.getYCrdn() * 1000000L);
        this.aring1phasCd = req.getAring1phasCd();
        this.aring2phasCd = req.getAring2phasCd();
        this.aring3phasCd = req.getAring3phasCd();
        this.aring4phasCd = req.getAring4phasCd();
        this.aring5phasCd = req.getAring5phasCd();
        this.aring6phasCd = req.getAring6phasCd();
        this.aring7phasCd = req.getAring7phasCd();
        this.aring8phasCd = req.getAring8phasCd();
        this.bring1phasCd = req.getBring1phasCd();
        this.bring2phasCd = req.getBring2phasCd();
        this.bring3phasCd = req.getBring3phasCd();
        this.bring4phasCd = req.getBring4phasCd();
        this.bring5phasCd = req.getBring5phasCd();
        this.bring6phasCd = req.getBring6phasCd();
        this.bring7phasCd = req.getBring7phasCd();
        this.bring8phasCd = req.getBring8phasCd();
    }

    public TbScSgnlCtlrPhaseDto toPhaseDto() {
        TbScSgnlCtlrPhaseDto dto = TbScSgnlCtlrPhaseDto.builder()
                .sgnlIxrNmbr(this.sgnlIxrNmbr)
                .build();

        if (this.stts == null) {
            dto.setCntlStts(3); // 통신장애
            return dto;
        }

        dto.setCntlMode(this.stts.getCntlMode());   // 제어모드(0: TRC, 1: TOD, 2: MAN)
        dto.setCntlStts(this.stts.getCntlStts());   // 제어상태(0: 온라인, 1: 오프라인, 2: 트랜스, 3: 통신장애)
        dto.setSpclCntl(this.stts.getSpclCntl());   // 특수제어(0: 없음, 1: 점멸, 2: 소등, 3: 수동, 4: 감응)

        int aRingPhase = -1;
        int bRingPhase = -1;
        switch(this.stts.getPrstAringPhas()) {
            case 1: aRingPhase = this.aring1phasCd; break;
            case 2: aRingPhase = this.aring2phasCd; break;
            case 3: aRingPhase = this.aring3phasCd; break;
            case 4: aRingPhase = this.aring4phasCd; break;
            case 5: aRingPhase = this.aring5phasCd; break;
            case 6: aRingPhase = this.aring6phasCd; break;
            case 7: aRingPhase = this.aring7phasCd; break;
            case 8: aRingPhase = this.aring8phasCd; break;
        }
        switch(this.stts.getPrstBringPhas()) {
            case 1: bRingPhase = this.bring1phasCd; break;
            case 2: bRingPhase = this.bring2phasCd; break;
            case 3: bRingPhase = this.bring3phasCd; break;
            case 4: bRingPhase = this.bring4phasCd; break;
            case 5: bRingPhase = this.bring5phasCd; break;
            case 6: bRingPhase = this.bring6phasCd; break;
            case 7: bRingPhase = this.bring7phasCd; break;
            case 8: bRingPhase = this.bring8phasCd; break;
        }

        return dto;
    }
}
