package com.eactive.eai.custom.statistics.dto;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;

import lombok.Getter;

/**
 * 분단위 통계 집계 키
 * - 동일 분의 동일 차원별로 집계하기 위한 키
 */
@Getter
public class MinuteStatsKey {

	/** 통계 시간 (분 단위, 초는 00) */
	private final LocalDateTime statTime;

	/** API명 */
	private final String apiName;

	/** API Gateway 인스턴스 ID */
	private final String gwInstanceId;

	/** 업무구분코드 */
	private final String bizDivCode;

	/** 클라이언트 ID */
	private final String clientId;

	/** Inbound Adapter */
	private final String inboundAdapter;

	/** Outbound Adapter */
	private final String outboundAdapter;

	public MinuteStatsKey(LocalDateTime statTime, String apiName, String gwInstanceId,
			String bizDivCode, String clientId, String inboundAdapter, String outboundAdapter) {
		// 초와 나노초를 0으로 절사하여 분 단위로 정규화
		this.statTime = statTime.truncatedTo(ChronoUnit.MINUTES);
		this.apiName = apiName;
		this.gwInstanceId = gwInstanceId;
		this.bizDivCode = bizDivCode;
		this.clientId = clientId;
		this.inboundAdapter = inboundAdapter;
		this.outboundAdapter = outboundAdapter;
	}

	/**
	 * TransactionEvent로부터 키 생성
	 */
	public static MinuteStatsKey from(TransactionEvent event, LocalDateTime eventTime) {
		return new MinuteStatsKey(
			eventTime,
			event.getApiName(),
			event.getGwInstanceId(),
			event.getBizDivCode(),
			event.getClientId(),
			event.getInboundAdapter(),
			event.getOutboundAdapter()
		);
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		MinuteStatsKey that = (MinuteStatsKey) o;
		return Objects.equals(statTime, that.statTime) &&
				Objects.equals(apiName, that.apiName) &&
				Objects.equals(gwInstanceId, that.gwInstanceId) &&
				Objects.equals(bizDivCode, that.bizDivCode) &&
				Objects.equals(clientId, that.clientId) &&
				Objects.equals(inboundAdapter, that.inboundAdapter) &&
				Objects.equals(outboundAdapter, that.outboundAdapter);
	}

	@Override
	public int hashCode() {
		return Objects.hash(statTime, apiName, gwInstanceId, bizDivCode,
				clientId, inboundAdapter, outboundAdapter);
	}

	@Override
	public String toString() {
		return String.format("%s|%s|%s|%s|%s|%s|%s",
				statTime, apiName, gwInstanceId, bizDivCode,
				clientId, inboundAdapter, outboundAdapter);
	}
}
