package com.eshore.gringotts.web.domain.entity;

import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.JoinColumn;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
 * @author lanyuanxiaoyao
 * @date 2024-11-29
 */
@Getter
@Setter
@ToString
@Entity
@DynamicUpdate
@EntityListeners(AuditingEntityListener.class)
@Table(name = Constants.TABLE_PREFIX + "check_order")
@NamedEntityGraph(name = "check_order.list", attributeNodes = {
        @NamedAttributeNode(value = "createdUser"),
        @NamedAttributeNode(value = "modifiedUser"),
})
@NamedEntityGraph(name = "check_order.detail", attributeNodes = {
        @NamedAttributeNode(value = "createdUser"),
        @NamedAttributeNode(value = "modifiedUser"),
})
@NoArgsConstructor
public class CheckOrder extends SimpleEntity {
    @Column(nullable = false)
    private String keyword;
    @Column(nullable = false)
    private String description;
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private Type type;
    /**
     * JSON 结构 Map<String, Object>
     */
    @Column(nullable = false)
    private String parameters;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private Target target;
    @Column(nullable = false)
    private String targetClass;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
    @ToString.Exclude
    private User targetUser;
    @Enumerated(EnumType.STRING)
    private User.Role targetRole;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private State state = State.CHECKING;

    public CheckOrder(
            String keyword,
            String description,
            Type type,
            String parameters,
            String targetClass,
            User targetUser
    ) {
        this.keyword = keyword;
        this.description = description;
        this.type = type;
        this.parameters = parameters;
        this.target = Target.USER;
        this.targetClass = targetClass;
        this.targetUser = targetUser;
    }

    public CheckOrder(
            String keyword,
            String description,
            Type type,
            String parameters,
            String targetClass,
            User.Role targetRole
    ) {
        this.keyword = keyword;
        this.description = description;
        this.type = type;
        this.parameters = parameters;
        this.target = Target.ROLE;
        this.targetClass = targetClass;
        this.targetRole = targetRole;
    }

    public enum Operation {
        APPLY,
        REJECT,
    }

    public enum Type {
        CONFIRMATION,
        AUTHENTICATION,
        MARKET,
    }

    public enum Target {
        USER,
        ROLE,
    }

    public enum State {
        CHECKING,
        RETRACT,
        OVER,
    }
}
