package com.gcsc.connection.apikey.entity;

import com.gcsc.connection.common.entity.BaseEntity;
import com.gcsc.connection.user.entity.SnpUser;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
@Entity
@Table(name = "snp_api_key_request", schema = "common")
public class SnpApiKeyRequest extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "request_id")
    private Long requestId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private SnpUser user;

    @Column(name = "key_name", length = 200, nullable = false)
    private String keyName;

    @Column(name = "purpose", columnDefinition = "TEXT")
    private String purpose;

    @Column(name = "requested_apis", columnDefinition = "TEXT")
    private String requestedApis;

    @Enumerated(EnumType.STRING)
    @Column(name = "status", length = 20, nullable = false)
    private KeyRequestStatus status = KeyRequestStatus.PENDING;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "reviewed_by")
    private SnpUser reviewedBy;

    @Column(name = "reviewed_at")
    private LocalDateTime reviewedAt;

    @Column(name = "review_comment", columnDefinition = "TEXT")
    private String reviewComment;

    @Column(name = "service_ip", length = 100)
    private String serviceIp;

    @Column(name = "service_purpose", length = 50)
    private String servicePurpose;

    @Column(name = "daily_request_estimate")
    private Long dailyRequestEstimate;

    @Column(name = "usage_from_date")
    private LocalDateTime usageFromDate;

    @Column(name = "usage_to_date")
    private LocalDateTime usageToDate;

    @Builder
    public SnpApiKeyRequest(SnpUser user, String keyName, String purpose, String requestedApis,
                            KeyRequestStatus status, String serviceIp, String servicePurpose,
                            Long dailyRequestEstimate, LocalDateTime usageFromDate,
                            LocalDateTime usageToDate) {
        this.user = user;
        this.keyName = keyName;
        this.purpose = purpose;
        this.requestedApis = requestedApis;
        this.status = status != null ? status : KeyRequestStatus.PENDING;
        this.serviceIp = serviceIp;
        this.servicePurpose = servicePurpose;
        this.dailyRequestEstimate = dailyRequestEstimate;
        this.usageFromDate = usageFromDate;
        this.usageToDate = usageToDate;
    }

    public void approve(SnpUser reviewer, String adjustedApis,
                        LocalDateTime adjustedFromDate, LocalDateTime adjustedToDate) {
        this.status = KeyRequestStatus.APPROVED;
        this.reviewedBy = reviewer;
        this.reviewedAt = LocalDateTime.now();
        if (adjustedApis != null) this.requestedApis = adjustedApis;
        if (adjustedFromDate != null) this.usageFromDate = adjustedFromDate;
        if (adjustedToDate != null) this.usageToDate = adjustedToDate;
    }

    public void reject(SnpUser reviewer, String comment) {
        this.status = KeyRequestStatus.REJECTED;
        this.reviewedBy = reviewer;
        this.reviewedAt = LocalDateTime.now();
        this.reviewComment = comment;
    }
}
