package com.erp.service;

import com.erp.common.BaseService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class MailSentHistoryService extends BaseService {

    private static final String NS = "mailSentHistory.";

    private final CommonService commonService;

    public Map<String, Object> getMailSentHistoryList(Map<String, Object> params) {
        // String "true"/"false" → Boolean 변환 (RequestParam은 String으로 들어옴)
        params.put("include_deleted",
                "true".equals(String.valueOf(params.getOrDefault("include_deleted", "false"))));
        params.put("only_deleted",
                "true".equals(String.valueOf(params.getOrDefault("only_deleted", "false"))));

        // sortBy → SQL 컬럼명 매핑 (동적 ORDER BY 인젝션 방지)
        String sortBy = (String) params.getOrDefault("sort_by", "sent_at");
        String sortColumn = switch (sortBy) {
            case "subject"   -> "subject";
            case "updated_at" -> "updated_date";
            default          -> "sent_at";
        };
        params.put("sort_column", sortColumn);
        String sortOrder = (String) params.getOrDefault("sort_order", "desc");
        params.put("sort_direction", "asc".equalsIgnoreCase(sortOrder) ? "ASC" : "DESC");

        commonService.applyCompanyCodeFilter(params);
        commonService.applyPagination(params);
        int totalCount = sqlSession.selectOne(NS + "getMailSentHistoryListCnt", params);
        List<Map<String, Object>> list = sqlSession.selectList(NS + "getMailSentHistoryList", params);
        return commonService.buildListResponse(list, totalCount, params);
    }

    public Map<String, Object> getMailSentHistoryInfo(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        return sqlSession.selectOne(NS + "getMailSentHistoryInfo", params);
    }

    @Transactional
    public Map<String, Object> saveMailSentHistoryDraft(Map<String, Object> params) {
        String id = Objects.toString(params.get("id"), "").trim();
        if (id.isEmpty()) {
            id = UUID.randomUUID().toString();
            params.put("id", id);
        }
        params.put("status", "draft");
        params.put("is_draft", true);
        if (params.get("sent_at") == null) {
            params.put("sent_at", new Timestamp(System.currentTimeMillis()));
        }

        Map<String, Object> lookupParams = new HashMap<>();
        lookupParams.put("id", id);
        lookupParams.put("company_code", params.get("company_code"));
        Map<String, Object> existing = sqlSession.selectOne(NS + "getMailSentHistoryInfo", lookupParams);

        if (existing != null) {
            sqlSession.update(NS + "updateMailSentHistory", params);
        } else {
            sqlSession.insert(NS + "insertMailSentHistory", params);
        }
        return sqlSession.selectOne(NS + "getMailSentHistoryInfo", lookupParams);
    }

    @Transactional
    public Map<String, Object> updateMailSentHistoryDraft(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        sqlSession.update(NS + "updateMailSentHistory", params);
        return sqlSession.selectOne(NS + "getMailSentHistoryInfo", params);
    }

    @Transactional
    public Map<String, Object> deleteMailSentHistory(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        sqlSession.update(NS + "softDeleteMailSentHistory", params);
        return params;
    }

    @Transactional
    public Map<String, Object> permanentlyDeleteMailSentHistory(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        sqlSession.delete(NS + "permanentDeleteMailSentHistory", params);
        return params;
    }

    @Transactional
    public Map<String, Object> restoreMailSentHistory(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        sqlSession.update(NS + "restoreMailSentHistory", params);
        return params;
    }

    @Transactional
    public Map<String, Object> bulkDeleteMailSentHistory(Map<String, Object> params) {
        @SuppressWarnings("unchecked")
        List<Object> ids = (List<Object>) params.get("ids");
        if (ids == null || ids.isEmpty()) {
            return Map.of("success_count", 0, "fail_count", 0);
        }
        int successCount = sqlSession.update(NS + "bulkSoftDeleteMailSentHistory", params);
        return Map.of("success_count", successCount, "fail_count", Math.max(0, ids.size() - successCount));
    }

    @Transactional
    public Map<String, Object> bulkPermanentDeleteMailSentHistory(Map<String, Object> params) {
        @SuppressWarnings("unchecked")
        List<Object> ids = (List<Object>) params.get("ids");
        if (ids == null || ids.isEmpty()) {
            return Map.of("success_count", 0, "fail_count", 0);
        }
        int successCount = sqlSession.delete(NS + "bulkPermanentDeleteMailSentHistory", params);
        return Map.of("success_count", successCount, "fail_count", Math.max(0, ids.size() - successCount));
    }

    @Transactional
    public Map<String, Object> bulkRestoreMailSentHistory(Map<String, Object> params) {
        @SuppressWarnings("unchecked")
        List<Object> ids = (List<Object>) params.get("ids");
        if (ids == null || ids.isEmpty()) {
            return Map.of("success_count", 0, "fail_count", 0);
        }
        int successCount = sqlSession.update(NS + "bulkRestoreMailSentHistory", params);
        return Map.of("success_count", successCount, "fail_count", Math.max(0, ids.size() - successCount));
    }

    public Map<String, Object> getMailSentHistoryStatistics(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        Map<String, Object> stats = sqlSession.selectOne(NS + "getMailSentHistoryStatistics", params);
        if (stats == null) stats = new HashMap<>();

        long totalSent    = toLong(stats.get("total_sent"));
        long successCount = toLong(stats.get("success_count"));
        long successRate  = totalSent > 0 ? Math.round((double) successCount / totalSent * 100) : 0;
        stats.put("success_rate", successRate);
        return stats;
    }

    /** 메일 발송 후 이력 기록 (내부용) */
    @Transactional
    public Map<String, Object> insertMailSentHistory(Map<String, Object> params) {
        if (params.get("id") == null) {
            params.put("id", UUID.randomUUID().toString());
        }
        if (params.get("sent_at") == null) {
            params.put("sent_at", new Timestamp(System.currentTimeMillis()));
        }
        sqlSession.insert(NS + "insertMailSentHistory", params);
        return params;
    }

    private long toLong(Object val) {
        if (val == null) return 0L;
        if (val instanceof Number n) return n.longValue();
        try { return Long.parseLong(val.toString()); } catch (Exception e) { return 0L; }
    }
}
