package dev.sonpx.loyalty.agent.core.workflow;

import dev.sonpx.loyalty.agent.core.classifier.Intent;

import java.util.List;
import java.util.Map;

/**
 * Builds phase-specific prompts for the ConversationWorkflow.
 * Each phase has a targeted prompt that tells the LLM exactly what to ask/do.
 *
 * Design for small models:
 * - Short, clear prompts
 * - Explicit field lists
 * - Vietnamese domain terminology
 */
public class WorkflowPromptBuilder {

    // ========== CAMPAIGN CREATION PROMPTS ==========

    static String campaignBasicInfoPrompt() {
        return """
                Bạn đang giúp người dùng TẠO CHIẾN DỊCH MỚI.
                Hãy hỏi người dùng các thông tin sau (bằng tiếng Việt, thân thiện):
                
                1. Tên chiến dịch
                2. Mô tả chiến dịch (ngắn gọn)
                3. Loại chiến dịch: Base (B) hoặc Tactical (T)
                4. Ngày bắt đầu và ngày kết thúc
                5. Tên người/phòng ban sở hữu (owner)
                
                Hỏi TẤT CẢ các thông tin trên trong MỘT lần. Liệt kê rõ ràng từng mục.
                KHÔNG gọi tool nào. Chỉ hỏi thông tin.""";
    }

    static String campaignConfirmPrompt(Map<String, Object> data) {
        return """
                Bạn đang giúp người dùng TẠO CHIẾN DỊCH MỚI.
                
                Người dùng đã cung cấp các thông tin. Hãy:
                1. Tóm tắt lại thông tin chiến dịch sẽ tạo (dạng danh sách)
                2. Hỏi "Anh/chị xác nhận tạo chiến dịch này không?"
                
                Thông tin đã thu thập:
                """ + formatData(data) + """
                
                KHÔNG gọi tool nào. Chỉ hiển thị tóm tắt và hỏi xác nhận.""";
    }

    static String campaignExecutePrompt(Map<String, Object> data) {
        return """
                Người dùng đã xác nhận tạo chiến dịch. Hãy thực hiện:
                
                1. Gọi tool `generateCampaignId` để tạo mã chiến dịch
                2. Gọi tool `createCampaign` với thông tin sau:
                
                """ + formatData(data) + """
                
                Sau khi tạo xong, thông báo kết quả cho người dùng.""";
    }

    // ========== RULE CREATION PROMPTS ==========

    static String ruleBasicInfoPrompt() {
        return """
                Bạn đang giúp người dùng TẠO RULE/THỂ LỆ MỚI cho chiến dịch.
                Hãy hỏi người dùng các thông tin CƠ BẢN sau (bằng tiếng Việt, thân thiện):
                
                1. Tên rule
                2. Thuộc chiến dịch nào? (nếu biết campaign ID thì cung cấp, nếu không biết thì mô tả để tìm)
                3. Loại rule:
                   - AWD: Thưởng điểm
                   - RED: Đổi điểm lấy quà
                   - IRED: Đổi quà đặc biệt
                   - ADJ: Điều chỉnh điểm
                   - CEP: Sự kiện trích xuất bộ đếm
                   - REP: Đổi điểm trích xuất
                   - TEP: Tích lũy theo giao dịch
                   - MAWD: Thưởng Marketing
                4. Mô tả rule (ngắn gọn)
                5. Thời gian hiệu lực: từ ngày → đến ngày
                
                Hỏi TẤT CẢ các thông tin trên trong MỘT lần. Liệt kê rõ ràng từng mục.
                KHÔNG gọi tool nào. Chỉ hỏi thông tin.""";
    }

    static String ruleRewardConfigPrompt(Map<String, Object> data) {
        return """
                Bạn đang giúp người dùng TẠO RULE/THỂ LỆ MỚI.
                Thông tin cơ bản đã có:
                """ + formatData(data) + """
                
                Bây giờ hãy hỏi thêm thông tin CẤU HÌNH THƯỞNG:
                
                1. Pool thưởng (pool ID nếu biết, hoặc để trống)
                2. Công thức thưởng: điểm cố định (fixed) hay theo tỷ lệ giao dịch (rate)?
                3. Giá trị thưởng (ví dụ: 100 điểm, hoặc 2% giá trị giao dịch)
                4. Giới hạn thưởng tối đa (cap) nếu có
                5. Có áp dụng lịch trình chạy (schedule) không?
                
                Hỏi TẤT CẢ các thông tin trên trong MỘT lần.
                KHÔNG gọi tool nào. Chỉ hỏi thông tin.""";
    }

    static String ruleConfirmPrompt(Map<String, Object> data) {
        return """
                Bạn đang giúp người dùng TẠO RULE/THỂ LỆ MỚI.
                
                Người dùng đã cung cấp đủ thông tin. Hãy:
                1. Tóm tắt lại TOÀN BỘ thông tin rule sẽ tạo (dạng danh sách rõ ràng)
                2. Hỏi "Anh/chị xác nhận tạo rule này không?"
                
                Thông tin đã thu thập:
                """ + formatData(data) + """
                
                KHÔNG gọi tool nào. Chỉ hiển thị tóm tắt và hỏi xác nhận.""";
    }

    static String ruleExecutePrompt(Map<String, Object> data) {
        return """
                Người dùng đã xác nhận tạo rule. Hãy thực hiện:
                
                1. Gọi tool `generateRuleId` để tạo mã rule
                2. Gọi tool `createRule` với thông tin sau:
                
                """ + formatData(data) + """
                
                Sau khi tạo xong, thông báo kết quả cho người dùng.""";
    }

    // ========== COMMON PROMPTS ==========

    static String extractDataPrompt(WorkflowState state) {
        String target = (state.getWorkflowType() == Intent.CAMPAIGN_CREATE) ? "chiến dịch" : "rule";
        return """
                Người dùng đang cung cấp thông tin để tạo %s.
                Dựa trên câu trả lời của người dùng, hãy trích xuất thông tin và xác nhận lại.
                Nếu thiếu thông tin quan trọng, hãy hỏi lại phần còn thiếu.
                
                Thông tin đã có trước đó:
                %s
                
                KHÔNG gọi tool nào. Chỉ xác nhận thông tin và hỏi phần còn thiếu (nếu có).
                Nếu đã đủ thông tin cơ bản, hãy nói "Tôi đã ghi nhận đủ thông tin" và hỏi người dùng muốn tiếp tục cấu hình chi tiết hay tạo luôn.
                """.formatted(target, formatData(state.getCollectedData()));
    }

    static String missingInfoPrompt(WorkflowState state) {
        String target = (state.getWorkflowType() == Intent.CAMPAIGN_CREATE) ? "chiến dịch" : "rule";
        return """
                Người dùng đang cung cấp thông tin để tạo %s, nhưng thông tin hiện tại chưa đủ để sang bước tiếp theo.

                Thông tin đã có:
                %s

                Hãy hỏi ngắn gọn các mục còn thiếu. KHÔNG gọi tool nào.
                """.formatted(target, formatData(state.getCollectedData()));
    }

    /**
     * Detect if user's response indicates confirmation.
     */
    static boolean isConfirmation(String userInput) {
        if (userInput == null) return false;
        String lower = userInput.trim().toLowerCase();
        return lower.matches("(?i).*(xác nhận|đồng ý|ok|oke|được|tạo đi|tạo luôn|yes|confirm|đúng rồi|chính xác).*");
    }

    /**
     * Detect if user's response indicates cancellation.
     */
    static boolean isCancellation(String userInput) {
        if (userInput == null) return false;
        String lower = userInput.trim().toLowerCase();
        return lower.matches("(?i)^\\s*(hủy|cancel|thôi|bỏ qua workflow|dừng|stop|không tạo|không tạo nữa|hủy tạo)(\\s|[.!?])*.*");
    }

    /**
     * Detect if user wants to skip optional config and proceed.
     */
    static boolean isSkipToConfirm(String userInput) {
        if (userInput == null) return false;
        String lower = userInput.trim().toLowerCase();
        return lower.matches("(?i).*(tạo luôn|bỏ qua|skip|không cần|đủ rồi|tạo thôi).*");
    }

    private static String formatData(Map<String, Object> data) {
        if (data == null || data.isEmpty()) return "(chưa có)";
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            sb.append("- ").append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
        }
        return sb.toString();
    }
}
