import json
import logging

try:
    from odoo.addons.encoach_ai.services.openai_service import OpenAIService
except ImportError:
    OpenAIService = None

try:
    from odoo.addons.encoach_quality_gate.services.content_gate import ContentSourceGate
except ImportError:
    ContentSourceGate = None

_logger = logging.getLogger(__name__)

SKILL_PROMPTS = {
    'listening': (
        'Generate an IELTS Listening section. Return JSON with keys: '
        '"script", "speakers", "duration_estimate", "questions".'
    ),
    'reading': (
        'Generate an IELTS Reading passage with questions. Return JSON with keys: '
        '"passage", "word_count", "questions", "question_types".'
    ),
    'writing': (
        'Generate an IELTS Writing task. Return JSON with keys: '
        '"task_type", "prompt", "requirements", "sample_band_descriptors".'
    ),
    'speaking': (
        'Generate an IELTS Speaking part. Return JSON with keys: '
        '"part", "questions", "cue_card" (if part 2), "follow_up_questions".'
    ),
}

IELTS_FORMAT_RULES = {
    'listening': {'required_keys': ['script', 'questions'], 'min_questions': 10},
    'reading': {'required_keys': ['passage', 'questions'], 'min_word_count': 500},
    'writing': {'required_keys': ['prompt', 'requirements']},
    'speaking': {'required_keys': ['questions']},
}


class IeltsPipeline:
    """AI content generation pipeline for IELTS skill-specific content."""

    def __init__(self, env):
        self.env = env
        self.ai = OpenAIService(env)

    def generate_content(self, env, skill, brief):
        """Generate IELTS skill-specific content.

        Args:
            env: Odoo environment.
            skill: one of 'listening', 'reading', 'writing', 'speaking'.
            brief: dict with generation parameters.

        Returns:
            dict with generated content.
        """
        system_prompt = SKILL_PROMPTS.get(skill, SKILL_PROMPTS['reading'])
        brief_text = json.dumps(brief) if isinstance(brief, dict) else str(brief)

        messages = [
            {'role': 'system', 'content': (
                f'You are an expert IELTS content creator. {system_prompt}'
            )},
            {'role': 'user', 'content': (
                f'Generate IELTS {skill} content based on this brief: {brief_text}'
            )},
        ]

        try:
            content = self.ai.chat_json(messages, temperature=0.8)
        except Exception as e:
            _logger.error("IELTS %s content generation failed: %s", skill, e)
            return {'error': str(e)}

        resource = env['encoach.ai.ielts.generation.log'].create({
            'skill': skill,
            'brief': brief_text,
            'status': 'format_check',
            'attempts': 1,
        })

        # Apply content source gate logic
        if ContentSourceGate is not None:
            try:
                ContentSourceGate.apply_gate(resource)
            except Exception as e:
                _logger.warning("ContentSourceGate.apply_gate failed: %s", e)

        return content

    def format_check(self, env, content, skill):
        """Validate IELTS format compliance for a given skill.

        Args:
            env: Odoo environment.
            content: dict of generated content.
            skill: IELTS skill type.

        Returns:
            dict with 'passed' bool and 'errors' list.
        """
        errors = []
        rules = IELTS_FORMAT_RULES.get(skill, {})

        for key in rules.get('required_keys', []):
            if key not in content or not content[key]:
                errors.append(f'Missing required key: {key}')

        if skill == 'listening':
            questions = content.get('questions', [])
            min_q = rules.get('min_questions', 10)
            if len(questions) < min_q:
                errors.append(
                    f'Listening requires at least {min_q} questions, '
                    f'got {len(questions)}'
                )

        if skill == 'reading':
            passage = content.get('passage', '')
            min_wc = rules.get('min_word_count', 500)
            word_count = len(passage.split()) if passage else 0
            if word_count < min_wc:
                errors.append(
                    f'Reading passage must be at least {min_wc} words, '
                    f'got {word_count}'
                )

        if skill == 'speaking' and not content.get('questions'):
            errors.append('Speaking section requires at least one question')

        return {'passed': len(errors) == 0, 'errors': errors}

    def band_calibration(self, env, content, target_band):
        """Check content aligns with target IELTS band level.

        Args:
            env: Odoo environment.
            content: dict of generated content.
            target_band: float target band score (e.g. 6.5).

        Returns:
            dict with 'passed' bool and 'issues' list.
        """
        messages = [
            {'role': 'system', 'content': (
                'You are an IELTS band calibration expert. Evaluate whether '
                'the provided content matches the target band level. '
                'Return JSON with keys: "calibrated" (bool), "estimated_band" (float), '
                '"issues" (list of strings).'
            )},
            {'role': 'user', 'content': (
                f'Target band: {target_band}. '
                f'Content: {json.dumps(content)}'
            )},
        ]

        try:
            result = self.ai.chat_json(messages, temperature=0.3)
        except Exception as e:
            _logger.error("Band calibration failed: %s", e)
            return {'passed': False, 'issues': [f'Band calibration error: {e}']}

        return {
            'passed': result.get('calibrated', False),
            'issues': result.get('issues', []),
        }
