package com.unicorn.hgzero.meeting.biz.service;

import com.unicorn.hgzero.common.exception.BusinessException;
import com.unicorn.hgzero.common.exception.ErrorCode;
import com.unicorn.hgzero.meeting.biz.domain.Template;
import com.unicorn.hgzero.meeting.biz.dto.TemplateDTO;
import com.unicorn.hgzero.meeting.biz.usecase.in.template.CreateTemplateUseCase;
import com.unicorn.hgzero.meeting.biz.usecase.in.template.GetTemplateUseCase;
import com.unicorn.hgzero.meeting.biz.usecase.out.TemplateReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.TemplateWriter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 템플릿 Service
 * Template 관련 모든 UseCase 구현
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TemplateService implements
        CreateTemplateUseCase,
        GetTemplateUseCase {

    private final TemplateReader templateReader;
    private final TemplateWriter templateWriter;

    /**
     * 템플릿 생성
     */
    @Override
    @Transactional
    public Template createTemplate(CreateTemplateCommand command) {
        log.info("Creating template: {}", command.name());

        // 템플릿 ID 생성
        String templateId = UUID.randomUUID().toString();

        // 템플릿 도메인 객체 생성
        Template template = Template.builder()
                .templateId(templateId)
                .name(command.name())
                .description(command.description())
                .category(command.category())
                .sections(command.sections())
                .isPublic(command.isPublic() != null ? command.isPublic() : true)
                .createdBy(command.createdBy())
                .build();

        // 템플릿 저장
        Template savedTemplate = templateWriter.save(template);

        log.info("Template created successfully: {}", savedTemplate.getTemplateId());
        return savedTemplate;
    }

    /**
     * ID로 템플릿 조회
     */
    @Override
    @Transactional(readOnly = true)
    public Template getTemplate(String templateId) {
        log.debug("Getting template: {}", templateId);

        return templateReader.findById(templateId)
                .orElseThrow(() -> new BusinessException(ErrorCode.ENTITY_NOT_FOUND));
    }

    /**
     * 카테고리로 템플릿 목록 조회
     */
    @Override
    @Transactional(readOnly = true)
    public List<Template> getTemplatesByCategory(String category) {
        log.debug("Getting templates by category: {}", category);

        return templateReader.findByCategory(category);
    }

    /**
     * 공개 템플릿 목록 조회
     */
    @Override
    @Transactional(readOnly = true)
    public List<Template> getPublicTemplates() {
        log.debug("Getting public templates");

        return templateReader.findByIsPublic(true);
    }

    /**
     * 작성자 ID로 템플릿 목록 조회
     */
    @Override
    @Transactional(readOnly = true)
    public List<Template> getTemplatesByCreator(String createdBy) {
        log.debug("Getting templates by creator: {}", createdBy);

        return templateReader.findByCreatedBy(createdBy);
    }

    /**
     * 이름으로 템플릿 검색
     */
    @Override
    @Transactional(readOnly = true)
    public List<Template> searchTemplatesByName(String name) {
        log.debug("Searching templates by name: {}", name);

        return templateReader.findByNameContaining(name);
    }

    /**
     * 템플릿 목록 조회 (DTO 반환)
     */
    @Transactional(readOnly = true)
    public List<TemplateDTO> getTemplateList(String category, Boolean isActive) {
        log.debug("Getting template list - category: {}, isActive: {}", category, isActive);

        List<Template> templates;
        if (category != null && !category.isEmpty()) {
            templates = templateReader.findByCategory(category);
        } else {
            templates = templateReader.findByIsPublic(true); // 공개 템플릿 기본 조회
        }

        return templates.stream()
                .map(this::convertToTemplateDTO)
                .collect(Collectors.toList());
    }

    /**
     * ID로 템플릿 조회 (DTO 반환)
     */
    @Transactional(readOnly = true)
    public TemplateDTO getTemplateById(String templateId) {
        log.debug("Getting template DTO by id: {}", templateId);

        Template template = templateReader.findById(templateId)
                .orElseThrow(() -> new BusinessException(ErrorCode.ENTITY_NOT_FOUND));

        return convertToTemplateDTO(template);
    }

    /**
     * Template 도메인을 TemplateDTO로 변환
     */
    private TemplateDTO convertToTemplateDTO(Template template) {
        return TemplateDTO.builder()
                .templateId(template.getTemplateId())
                .name(template.getName())
                .description(template.getDescription())
                .templateType("STANDARD") // 임시값
                .sections(List.of()) // 임시로 빈 리스트
                .isActive(template.getIsPublic())
                .createdBy(template.getCreatedBy())
                .createdAt(template.getCreatedAt())
                .updatedAt(template.getLastModifiedAt())
                .category(template.getCategory())
                .active(template.getIsPublic())
                .usageCount(0) // 임시값
                .lastUsedAt(null) // 임시값
                .build();
    }
}
