package com.unicorn.hgzero.notification.dto.response;

import com.unicorn.hgzero.notification.domain.Notification;
import com.unicorn.hgzero.notification.domain.NotificationRecipient;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 알림 응답 DTO
 *
 * 단일 알림 정보 조회 시 사용
 * 알림 기본 정보 및 수신자 목록 포함
 *
 * @author 준호 (Backend Developer)
 * @version 1.0
 * @since 2025-10-23
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(description = "알림 응답")
public class NotificationResponse {

    @Schema(description = "알림 ID", example = "550e8400-e29b-41d4-a716-446655440000")
    private String notificationId;

    @Schema(description = "이벤트 ID (중복 방지용)", example = "meeting-created-20250123-001")
    private String eventId;

    @Schema(description = "참조 대상 ID", example = "meeting-001")
    private String referenceId;

    @Schema(description = "참조 유형", example = "MEETING")
    private String referenceType;

    @Schema(description = "알림 유형", example = "INVITATION")
    private String notificationType;

    @Schema(description = "알림 제목", example = "회의 초대: 주간 회의")
    private String title;

    @Schema(description = "알림 내용", example = "주간 진행 상황 공유 및 이슈 논의")
    private String message;

    @Schema(description = "알림 상태", example = "SENT")
    private String status;

    @Schema(description = "발송 채널", example = "EMAIL")
    private String channel;

    @Schema(description = "발송 완료 건수", example = "5")
    private Integer sentCount;

    @Schema(description = "발송 실패 건수", example = "0")
    private Integer failedCount;

    @Schema(description = "생성 일시", example = "2025-01-23T10:00:00")
    private LocalDateTime createdAt;

    @Schema(description = "발송 완료 일시", example = "2025-01-23T10:05:00")
    private LocalDateTime sentAt;

    @Schema(description = "수신자 목록")
    private List<RecipientInfo> recipients;

    /**
     * Entity를 DTO로 변환
     *
     * @param notification 알림 엔티티
     * @return 알림 응답 DTO
     */
    public static NotificationResponse from(Notification notification) {
        return NotificationResponse.builder()
            .notificationId(notification.getNotificationId())
            .eventId(notification.getEventId())
            .referenceId(notification.getReferenceId())
            .referenceType(notification.getReferenceType().name())
            .notificationType(notification.getNotificationType().name())
            .title(notification.getTitle())
            .message(notification.getMessage())
            .status(notification.getStatus().name())
            .channel(notification.getChannel().name())
            .sentCount(notification.getSentCount())
            .failedCount(notification.getFailedCount())
            .createdAt(notification.getCreatedAt())
            .sentAt(notification.getSentAt())
            .recipients(notification.getRecipients().stream()
                .map(RecipientInfo::from)
                .collect(Collectors.toList()))
            .build();
    }

    /**
     * 수신자 정보 DTO
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    @Schema(description = "수신자 정보")
    public static class RecipientInfo {

        @Schema(description = "수신자 ID", example = "550e8400-e29b-41d4-a716-446655440001")
        private String recipientId;

        @Schema(description = "수신자 사용자 ID", example = "user-001")
        private String recipientUserId;

        @Schema(description = "수신자 이름", example = "홍길동")
        private String recipientName;

        @Schema(description = "수신자 이메일", example = "hong@example.com")
        private String recipientEmail;

        @Schema(description = "발송 상태", example = "SENT")
        private String status;

        @Schema(description = "재시도 횟수", example = "0")
        private Integer retryCount;

        @Schema(description = "발송 일시", example = "2025-01-23T10:05:00")
        private LocalDateTime sentAt;

        @Schema(description = "실패 사유", example = "")
        private String errorMessage;

        /**
         * Entity를 DTO로 변환
         *
         * @param recipient 수신자 엔티티
         * @return 수신자 정보 DTO
         */
        public static RecipientInfo from(NotificationRecipient recipient) {
            return RecipientInfo.builder()
                .recipientId(recipient.getRecipientId())
                .recipientUserId(recipient.getRecipientUserId())
                .recipientName(recipient.getRecipientName())
                .recipientEmail(recipient.getRecipientEmail())
                .status(recipient.getStatus().name())
                .retryCount(recipient.getRetryCount())
                .sentAt(recipient.getSentAt())
                .errorMessage(recipient.getErrorMessage())
                .build();
        }
    }
}
