package com.unicorn.hgzero.ai.infra.gateway.entity;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.hgzero.ai.biz.domain.ProcessedTranscript;
import com.unicorn.hgzero.common.entity.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 처리된 회의록 Entity
 * AI가 처리한 회의록 정보를 데이터베이스에 영속화
 */
@Slf4j
@Entity
@Table(name = "processed_transcripts")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProcessedTranscriptEntity extends BaseTimeEntity {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Id
    @Column(name = "transcript_id", length = 50)
    private String transcriptId;

    @Column(name = "meeting_id", length = 50, nullable = false)
    private String meetingId;

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

    /**
     * 논의사항 목록 (JSON 형식)
     */
    @Column(name = "discussions", columnDefinition = "TEXT")
    private String discussions;

    /**
     * 결정사항 목록 (JSON 형식)
     */
    @Column(name = "decisions", columnDefinition = "TEXT")
    private String decisions;

    /**
     * 보류사항 목록 (콤마 구분)
     */
    @Column(name = "pending_items", columnDefinition = "TEXT")
    private String pendingItems;

    @Column(name = "status", length = 20, nullable = false)
    @Builder.Default
    private String status = "DRAFT";

    /**
     * Entity를 Domain 모델로 변환
     */
    public ProcessedTranscript toDomain() {
        return ProcessedTranscript.builder()
                .transcriptId(this.transcriptId)
                .meetingId(this.meetingId)
                .summary(this.summary)
                .discussions(parseDiscussions(this.discussions))
                .decisions(parseDecisions(this.decisions))
                .pendingItems(parsePendingItems(this.pendingItems))
                .createdAt(this.getCreatedAt())
                .status(this.status)
                .build();
    }

    /**
     * Domain 모델에서 Entity로 변환
     */
    public static ProcessedTranscriptEntity fromDomain(ProcessedTranscript domain) {
        return ProcessedTranscriptEntity.builder()
                .transcriptId(domain.getTranscriptId())
                .meetingId(domain.getMeetingId())
                .summary(domain.getSummary())
                .discussions(formatDiscussions(domain.getDiscussions()))
                .decisions(formatDecisions(domain.getDecisions()))
                .pendingItems(formatPendingItems(domain.getPendingItems()))
                .status(domain.getStatus())
                .build();
    }

    /**
     * 상태 업데이트
     */
    public void updateStatus(String status) {
        this.status = status;
    }

    /**
     * 요약 업데이트
     */
    public void updateSummary(String summary) {
        this.summary = summary;
    }

    // ========================================
    // Private Helper Methods - JSON 변환
    // ========================================

    private static List<ProcessedTranscript.DiscussionItem> parseDiscussions(String json) {
        if (json == null || json.isEmpty()) {
            return new ArrayList<>();
        }
        try {
            return objectMapper.readValue(json,
                new TypeReference<List<ProcessedTranscript.DiscussionItem>>() {});
        } catch (JsonProcessingException e) {
            log.error("Failed to parse discussions JSON: {}", json, e);
            return new ArrayList<>();
        }
    }

    private static String formatDiscussions(List<ProcessedTranscript.DiscussionItem> discussions) {
        if (discussions == null || discussions.isEmpty()) {
            return "";
        }
        try {
            return objectMapper.writeValueAsString(discussions);
        } catch (JsonProcessingException e) {
            log.error("Failed to format discussions to JSON", e);
            return "";
        }
    }

    private static List<ProcessedTranscript.DecisionItem> parseDecisions(String json) {
        if (json == null || json.isEmpty()) {
            return new ArrayList<>();
        }
        try {
            return objectMapper.readValue(json,
                new TypeReference<List<ProcessedTranscript.DecisionItem>>() {});
        } catch (JsonProcessingException e) {
            log.error("Failed to parse decisions JSON: {}", json, e);
            return new ArrayList<>();
        }
    }

    private static String formatDecisions(List<ProcessedTranscript.DecisionItem> decisions) {
        if (decisions == null || decisions.isEmpty()) {
            return "";
        }
        try {
            return objectMapper.writeValueAsString(decisions);
        } catch (JsonProcessingException e) {
            log.error("Failed to format decisions to JSON", e);
            return "";
        }
    }

    private static List<String> parsePendingItems(String items) {
        if (items == null || items.isEmpty()) {
            return new ArrayList<>();
        }
        return Arrays.asList(items.split(","));
    }

    private static String formatPendingItems(List<String> items) {
        if (items == null || items.isEmpty()) {
            return "";
        }
        return String.join(",", items);
    }
}
