package com.its.api.its.model.entity.link;

import com.its.api.its.global.CodeManager;
import com.its.api.its.model.dto.link.TbLinkDto;
import com.its.api.its.model.entity.node.TbNode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

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

/**
 * 링크정보 Entity Class
 */
@Getter
@NoArgsConstructor
@Builder
@AllArgsConstructor
@ApiModel("링크정보")
@Entity
@Table(name = "TB_LINK")
public class TbLink implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty("링크ID")  // N NUMBER(10)
    @Id
    @Column(name = "LINK_ID", nullable = false, unique = true, columnDefinition = "NUMBER", length = 10)
    private Long linkId;

    @ApiModelProperty("시작노드ID")  // Y NUMBER(10)
    @Column(name = "F_NODE", columnDefinition = "NUMBER", length = 10)
    private Long fNodeId;

    @ApiModelProperty("종료노드ID")  // Y NUMBER(10)
    @Column(name = "T_NODE", columnDefinition = "NUMBER", length = 10)
    private Long tNodeId;

    @ApiModelProperty("도로사용여부")  // N VARCHAR(1)
    @Column(name = "ROAD_USE", nullable = false, length = 1)
    private String roadUse;

    @ApiModelProperty("차로수")  // Y NUMBER(4)
    @Column(name = "LANES", columnDefinition = "NUMBER", length = 4)
    private Integer lanes;

    @ApiModelProperty("도로등급")  // Y VARCHAR(3)
    @Column(name = "ROAD_RANK", length = 3)
    private String roadRank;

    @ApiModelProperty("도로유형")  // Y VARCHAR(3)
    @Column(name = "ROAD_TYPE", length = 3)
    private String roadType;

    @ApiModelProperty("도로번호")  // Y VARCHAR(5)
    @Column(name = "ROAD_NO", length = 5)
    private String roadNo;

    @ApiModelProperty("도로명")  // Y VARCHAR(50)
    @Column(name = "ROAD_NAME", length = 50)
    private String roadName;

    @ApiModelProperty("중용구간여부")  // N VARCHAR(1)
    @Column(name = "MULTI_LINK", length = 1)
    private String multiLink;

    @ApiModelProperty("연결로코드")  // Y VARCHAR(3)
    @Column(name = "LINK_CONNECT", length = 3)
    private String linkConnect;

    @ApiModelProperty("최고제한속도")  // Y NUMBER(4)
    @Column(name = "MAX_SPD", columnDefinition = "NUMBER", length = 4)
    private Integer maxSpd;

    @ApiModelProperty("통행제한차량")  // Y VARCHAR(3)
    @Column(name = "REST_VEH", length = 3)
    private String restVeh;

    @ApiModelProperty("통과제한하중")  // Y NUMBER(5)
    @Column(name = "REST_W", columnDefinition = "NUMBER", length = 5)
    private Integer restW;

    @ApiModelProperty("통과제한높이")  // Y NUMBER(5)
    @Column(name = "REST_H", columnDefinition = "NUMBER", length = 5)
    private Integer restH;

    @ApiModelProperty("연장")  // Y NUMBER(5)
    @Column(name = "LINK_LENG", columnDefinition = "NUMBER", length = 5)
    private Integer linkLeng;

    @ApiModelProperty("비고")  // Y VARCHAR(50)
    @Column(name = "RMRK", length = 50)
    private String rmrk;

    @ApiModelProperty("디폴트 속도")  // Y NUMBER(3)
    @Column(name = "DFLT_SPED", columnDefinition = "NUMBER", length = 3)
    private Integer dfltSped;

    @ApiModelProperty("디폴트 속도 사용 여부")  // Y CHAR(1)
    @Column(name = "DFLT_SPED_USE_YN", columnDefinition = "CHAR", length = 1)
    private String dfltSpedUseYn;

    @ApiModelProperty("구간 등급 코드")  // Y VARCHAR(7)
    @Column(name = "SECT_GRAD_CD", length = 7)
    private String sectGradCd;

    @ApiModelProperty("지역 코드")  // Y VARCHAR(7)
    @Column(name = "AREA_CD", length = 7)
    private String areaCd;

    @ApiModelProperty("파라미터ID")  // Y NUMBER(10)
    @Column(name = "PARA_ID", columnDefinition = "NUMBER", length = 10)
    private Long paraId;

    @ApiModelProperty("삭제 여부")  // Y CHAR(1)
    @Column(name = "DEL_YN", columnDefinition = "CHAR", length = 1)
    private String delYn;

    @OneToOne
    @JoinColumn(insertable=false, updatable=false, name="F_NODE", referencedColumnName = "NODE_ID")
    @NotFound(action = NotFoundAction.IGNORE)
    private TbNode fromNode = new TbNode();

    @OneToOne
    @JoinColumn(insertable=false, updatable=false, name="T_NODE", referencedColumnName = "NODE_ID")
    @NotFound(action = NotFoundAction.IGNORE)
    private TbNode toNode = new TbNode();

    public TbLinkDto toDto() {
        TbLinkDto dto = TbLinkDto.builder()
                .linkId(this.linkId)
                .fNodeId(this.fNodeId)
                .tNodeId(this.tNodeId)
                .roadUse(this.roadUse)
                .lanes(this.lanes)
                .roadRank(this.roadRank)
                .roadType(this.roadType)
                .roadNo(this.roadNo)
                .roadName(this.roadName)
                .multiLink(this.multiLink)
                .linkConnect(this.linkConnect)
                .maxSpd(this.maxSpd)
                .restVeh(this.restVeh)
                .restW(this.restW)
                .restH(this.restH)
                .linkLeng(this.linkLeng)
                .rmrk(this.rmrk)
                .delYn(this.delYn)
                .dfltSped(this.dfltSped)
                .dfltSpedUseYn(this.dfltSpedUseYn)
                .sectGradCd(this.sectGradCd)
                .areaCd(this.areaCd)
                .paraId(this.paraId)
                .build();

        if (this.getFromNode() != null) {
            dto.setFromNodeInfo(this.getFromNode().getNodeName());
            dto.setFromXCrdn(this.getFromNode().getXCrdn());
            dto.setFromYCrdn(this.getFromNode().getYCrdn());
        } else {
            dto.setFromNodeInfo("");
            dto.setFromXCrdn(0.);
            dto.setFromYCrdn(0.);
        }

        if (this.getToNode() != null) {
            dto.setToNodeInfo(this.getToNode().getNodeName());
            dto.setToXCrdn(this.getFromNode().getXCrdn());
            dto.setToYCrdn(this.getFromNode().getYCrdn());
        } else {
            dto.setToNodeInfo("");
            dto.setToXCrdn(0.);
            dto.setToYCrdn(0.);
        }

        dto.setRoadUseDesc(CodeManager.getCodeDesc(CodeManager.ROAD_USE, this.roadUse));
        dto.setRoadRankDesc(CodeManager.getCodeDesc(CodeManager.ROAD_RANK, this.roadRank));
        dto.setRoadTypeDesc(CodeManager.getCodeDesc(CodeManager.ROAD_TYPE, this.roadType));
        dto.setMultiLinkDesc(CodeManager.getCodeDesc(CodeManager.MULTI_LINK, this.multiLink));
        dto.setLinkConnectDesc(CodeManager.getCodeDesc(CodeManager.LINK_CONNECT, this.linkConnect));
        dto.setRestVehDesc(CodeManager.getCodeDesc(CodeManager.REST_VEH, this.restVeh));
        dto.setSectGradDesc(CodeManager.getCodeDesc(CodeManager.SECT_GRAD_CD, this.sectGradCd));

        return dto;
    }

    public TbLink(Long linkId) {
        this.linkId = linkId;
    }

    public void updateInfo(TbLinkDto.TbLinkUpdReq req) {
        this.fNodeId = req.getFNodeId();
        this.tNodeId = req.getTNodeId();
        this.roadUse = req.getRoadUse();
        this.lanes = req.getLanes();
        this.roadRank = req.getRoadRank();
        this.roadType = req.getRoadType();
        this.roadNo = req.getRoadNo();
        this.roadName = req.getRoadName();
        this.multiLink = req.getMultiLink();
        this.linkConnect = req.getLinkConnect();
        this.maxSpd = req.getMaxSpd();
        this.restVeh = req.getRestVeh();
        this.restW = req.getRestW();
        this.restH = req.getRestH();
        this.linkLeng = req.getLinkLeng();
        this.rmrk = req.getRmrk();
        this.delYn = req.getDelYn();
        this.dfltSped = req.getDfltSped();
        this.dfltSpedUseYn = req.getDfltSpedUseYn();
        this.sectGradCd = req.getSectGradCd();
        this.areaCd = req.getAreaCd();
        this.paraId = req.getParaId();
    }
    public void updateName(TbLinkDto.TbLinkNameUpdReq req) {
        this.roadName = req.getRoadName();
    }

}
