package com.kamco.cd.training.postgres.entity;

import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import java.util.UUID;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_audit_log")
public class AuditLogEntity extends CommonCreateEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "audit_log_uid", nullable = false)
  private Long id;

  @Column(name = "user_uid")
  private Long userUid;

  @Enumerated(EnumType.STRING)
  private EventType eventType;

  @Enumerated(EnumType.STRING)
  private EventStatus eventStatus;

  @Column(name = "menu_uid")
  private String menuUid;

  @Column(name = "ip_address")
  private String ipAddress;

  @Column(name = "request_uri")
  private String requestUri;

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

  @Column(name = "error_log_uid")
  private Long errorLogUid;

  @Column(name = "download_uuid")
  private UUID downloadUuid;

  @Column(name = "login_attempt_id")
  private String loginAttemptId;

  public AuditLogEntity(
      Long userUid,
      EventType eventType,
      EventStatus eventStatus,
      String menuUid,
      String ipAddress,
      String requestUri,
      String requestBody,
      Long errorLogUid,
      UUID downloadUuid,
      String loginAttemptId) {
    this.userUid = userUid;
    this.eventType = eventType;
    this.eventStatus = eventStatus;
    this.menuUid = menuUid;
    this.ipAddress = ipAddress;
    this.requestUri = requestUri;
    this.requestBody = requestBody;
    this.errorLogUid = errorLogUid;
    this.downloadUuid = downloadUuid;
    this.loginAttemptId = loginAttemptId;
  }

  /** 파일 다운로드 이력 생성 */
  public static AuditLogEntity forFileDownload(
      Long userId,
      String requestUri,
      String menuUid,
      String ip,
      int httpStatus,
      UUID downloadUuid) {

    return new AuditLogEntity(
        userId,
        EventType.DOWNLOAD, // 이벤트 타입 고정
        httpStatus < 400 ? EventStatus.SUCCESS : EventStatus.FAILED, // 성공 여부
        menuUid,
        ip,
        requestUri,
        null, // requestBody 없음
        null, // errorLogUid 없음
        downloadUuid,
        null // loginAttemptId 없음
        );
  }

  public AuditLogDto.Basic toDto() {
    return new AuditLogDto.Basic(
        this.id,
        this.userUid,
        this.eventType,
        this.eventStatus,
        this.menuUid,
        this.ipAddress,
        this.requestUri,
        this.requestBody,
        this.errorLogUid,
        super.getCreatedDate());
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(this.id)
        .append("\n")
        .append(this.userUid)
        .append("\n")
        .append(this.eventType)
        .append("\n")
        .append(this.eventStatus)
        .append("\n")
        .append(this.menuUid)
        .append("\n")
        .append(this.ipAddress)
        .append("\n")
        .append(this.requestUri)
        .append("\n")
        .append(this.requestBody)
        .append("\n")
        .append(this.errorLogUid);
    return sb.toString();
  }
}
