package com.emonster.taroaichat.service.llm.gemini.tools;

import com.google.genai.types.Schema;
import com.google.genai.types.Type;
import org.springframework.stereotype.Component;

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

/**
 * Gemini-native tool for revealing and interpreting individual tarot cards during a reading.
 * Follows official Gemini SDK patterns.
 */
@Component
public class GeminiRevealCardTool extends GeminiAITool {

    @Override
    public String getName() {
        return "reveal_card";
    }

    @Override
    public String getDescription() {
        return "CRITICAL RULE: This tool is MANDATORY for revealing the next card and providing its interpretation. " +
               "STATE: Use in AWAITING_SITUATION, AWAITING_OBSTACLE, or AWAITING_ADVICE states. " +
               "TRIGGER: Call this tool IMMEDIATELY WHEN user expresses readiness to see the next card. " +
               "--- PARAMETER LOGIC ---" +
               "- cardPosition: Use 'situation' for first card (AWAITING_SITUATION), 'obstacle' for second (AWAITING_OBSTACLE), 'advice' for third (AWAITING_ADVICE) " +
               "- interpretation: The FULL interpretation including Jungian psychology and astrological layers based on user's context " +
               "IMPORTANT: Be flexible with trigger phrases - if user shows ANY readiness to proceed, call this tool. " +
               "NEVER mention this tool call in your response - the card reveal happens through the UI.";
    }

    @Override
    public Schema getParameterSchema() {
        return Schema.builder()
            .type(Type.Known.OBJECT)
            .properties(Map.of(
                "cardPosition", Schema.builder()
                    .type(Type.Known.STRING)
                    .description("The position of the card to reveal. Must be exactly 'situation', 'obstacle', or 'advice'. This is the ONLY required parameter.")
                    .enum_(List.of("situation", "obstacle", "advice"))
                    .build(),
                "interpretation", Schema.builder()
                    .type(Type.Known.STRING)
                    .description("The full interpretation of this card including Jungian and astrological layers, with user chatting context. This should be the complete interpretation you would speak to the user.")
                    .build(),
                "cardInterpretationNote", Schema.builder()
                    .type(Type.Known.STRING)
                    .description("Brief note about what aspect of this specific card to emphasize (optional)")
                    .build()
            ))
            .required(List.of("cardPosition", "interpretation"))
            .build();
    }

    @Override
    public GeminiToolResult execute(Map<String, Object> parameters) {
        // Validate parameters
        if (!validateParameters(parameters)) {
            return GeminiToolResult.failure("Invalid parameters provided");
        }

        // Try multiple parameter name variations that Gemini might use
        String cardPosition = (String) parameters.getOrDefault("cardPosition",
            parameters.getOrDefault("card_position",
                parameters.getOrDefault("position",  // Gemini also uses this
                    parameters.get("card_name")))); // Gemini sometimes uses this
        String interpretation = (String) parameters.getOrDefault("interpretation",
            parameters.get("interpretation"));
        String cardInterpretationNote = (String) parameters.getOrDefault("cardInterpretationNote",
            parameters.get("card_interpretation_note"));

        LOG.info("Gemini reveal_card tool called: cardPosition='{}', interpretation length={}",
                cardPosition, interpretation != null ? interpretation.length() : 0);

        // Return success with the card revelation data including interpretation
        Map<String, Object> resultData = Map.of(
            "action", "revealCard",
            "cardPosition", cardPosition,
            "interpretation", interpretation != null ? interpretation : "",
            "cardInterpretationNote", cardInterpretationNote != null ? cardInterpretationNote : ""
        );

        return GeminiToolResult.success(
            "reveal_card executed successfully",
            resultData
        );
    }

    @Override
    public boolean validateParameters(Map<String, Object> parameters) {
        if (!super.validateParameters(parameters)) {
            return false;
        }

        // Check required fields - accept multiple variations
        if (!parameters.containsKey("cardPosition") &&
            !parameters.containsKey("card_position") &&
            !parameters.containsKey("position") &&
            !parameters.containsKey("card_name")) {
            LOG.warn("Missing required parameter: cardPosition, card_position, position, or card_name. Received parameters: {}", parameters.keySet());
            return false;
        }

        // Validate cardPosition - try multiple naming conventions
        String cardPosition = (String) parameters.getOrDefault("cardPosition",
            parameters.getOrDefault("card_position",
                parameters.getOrDefault("position",
                    parameters.get("card_name"))));
        if (cardPosition == null || !isValidCardPosition(cardPosition)) {
            LOG.warn("Invalid cardPosition: {}", cardPosition);
            return false;
        }

        // Check for interpretation parameter
        if (!parameters.containsKey("interpretation")) {
            LOG.warn("Missing required parameter: interpretation. Received parameters: {}", parameters.keySet());
            return false;
        }

        // Validate interpretation is not empty
        String interpretation = (String) parameters.get("interpretation");
        if (interpretation == null || interpretation.trim().isEmpty()) {
            LOG.warn("Interpretation parameter is empty");
            return false;
        }

        return true;
    }

    private boolean isValidCardPosition(String position) {
        return position.equals("situation") ||
               position.equals("obstacle") ||
               position.equals("advice");
    }
}
