package cloud.nstart.terravault.ordinis.domain.idempotency;

import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.annotations.Type;

import java.time.OffsetDateTime;

/**
 * Idempotency key для exactly-once семантики write API. Header
 * {@code Idempotency-Key} от клиента кладётся сюда вместе с request hash и
 * сохранённым response. На повторный запрос с тем же ключом возвращается тот
 * же ответ, не повторяется side-effect (запись + outbox event).
 */
@Entity
@Table(name = "idempotency_keys")
public class IdempotencyKey {

  @Id
  @Column(name = "key", nullable = false, length = 128)
  private String key;

  @Column(name = "request_hash", nullable = false, length = 64)
  private String requestHash;

  @Column(name = "response_status")
  private Integer responseStatus;

  @Type(JsonType.class)
  @Column(name = "response_body", columnDefinition = "jsonb")
  private JsonNode responseBody;

  @Column(name = "created_at", nullable = false)
  private OffsetDateTime createdAt;

  @Column(name = "expires_at", nullable = false)
  private OffsetDateTime expiresAt;

  protected IdempotencyKey() {}

  public IdempotencyKey(String key, String requestHash, OffsetDateTime expiresAt) {
    this.key = key;
    this.requestHash = requestHash;
    this.createdAt = OffsetDateTime.now();
    this.expiresAt = expiresAt;
  }

  public String getKey() { return key; }
  public String getRequestHash() { return requestHash; }
  public Integer getResponseStatus() { return responseStatus; }
  public JsonNode getResponseBody() { return responseBody; }
  public OffsetDateTime getCreatedAt() { return createdAt; }
  public OffsetDateTime getExpiresAt() { return expiresAt; }

  public void setResponse(int status, JsonNode body) {
    this.responseStatus = status;
    this.responseBody = body;
  }
}
