# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)

import base64
import logging
import os
import tempfile

from odoo import http
from odoo.http import request

_logger = logging.getLogger(__name__)


class FusionNotesController(http.Controller):

    # ------------------------------------------------------------------
    # Settings endpoint (for frontend to fetch user preferences)
    # ------------------------------------------------------------------

    @http.route('/fusion_notes/get_settings', type='jsonrpc', auth='user')
    def get_settings(self, **kwargs):
        """Return Fusion Notes settings for the frontend."""
        ICP = request.env['ir.config_parameter'].sudo()
        return {
            'review_mode': ICP.get_param(
                'fusion_notes.default_review_mode', 'True') == 'True',
            'ai_format': ICP.get_param(
                'fusion_notes.default_ai_format', 'False') == 'True',
            'max_seconds': int(
                ICP.get_param('fusion_notes.max_recording_seconds', '300')),
            'has_api_key': bool(
                ICP.get_param('fusion_notes.openai_api_key', '')),
        }

    # ------------------------------------------------------------------
    # Whisper transcription
    # ------------------------------------------------------------------

    @http.route('/fusion_notes/transcribe', type='jsonrpc', auth='user')
    def transcribe(self, audio_base64, mime_type='audio/webm', **kwargs):
        """Transcribe audio using OpenAI Whisper API.

        Args:
            audio_base64: Base64-encoded audio data.
            mime_type: MIME type of the audio (default audio/webm).

        Returns:
            dict with 'text' on success or 'error' on failure.
        """
        ICP = request.env['ir.config_parameter'].sudo()
        api_key = ICP.get_param('fusion_notes.openai_api_key', '')

        if not api_key:
            return {
                'error': 'OpenAI API key not configured. '
                         'Go to Settings > Fusion Notes.',
            }

        try:
            import requests as req
        except ImportError:
            return {'error': 'Python requests library not available.'}

        # Decode audio from base64
        try:
            audio_data = base64.b64decode(audio_base64)
        except Exception as e:
            _logger.error('Failed to decode audio: %s', e)
            return {'error': 'Invalid audio data.'}

        if len(audio_data) < 1000:
            return {'error': 'Audio too short. Please record a longer message.'}

        # Determine file extension from MIME type
        ext_map = {
            'audio/webm': '.webm',
            'audio/ogg': '.ogg',
            'audio/wav': '.wav',
            'audio/mp4': '.m4a',
            'audio/mpeg': '.mp3',
        }
        suffix = ext_map.get(mime_type, '.webm')

        # Write to temp file and send to Whisper
        tmp_path = None
        try:
            with tempfile.NamedTemporaryFile(
                suffix=suffix, delete=False
            ) as tmp:
                tmp.write(audio_data)
                tmp_path = tmp.name

            with open(tmp_path, 'rb') as audio_file:
                # Use translations endpoint to always output English
                # (auto-translates any spoken language to English)
                response = req.post(
                    'https://api.openai.com/v1/audio/translations',
                    headers={'Authorization': f'Bearer {api_key}'},
                    files={
                        'file': (
                            f'recording{suffix}', audio_file, mime_type,
                        ),
                    },
                    data={'model': 'whisper-1'},
                    timeout=60,
                )
                response.raise_for_status()
                result = response.json()
                text = result.get('text', '').strip()

                if not text:
                    return {'error': 'No speech detected in the recording.'}

                return {'text': text}

        except req.exceptions.Timeout:
            return {
                'error': 'Transcription timed out. '
                         'Please try a shorter recording.',
            }
        except req.exceptions.HTTPError as e:
            body = e.response.text if e.response else ''
            _logger.error('Whisper API error: %s - %s', e, body)
            return {'error': f'Transcription failed: {e}'}
        except Exception as e:
            _logger.error('Transcription error: %s', e)
            return {'error': f'Transcription failed: {e}'}
        finally:
            if tmp_path and os.path.exists(tmp_path):
                try:
                    os.unlink(tmp_path)
                except OSError:
                    pass

    # ------------------------------------------------------------------
    # GPT formatting
    # ------------------------------------------------------------------

    @http.route('/fusion_notes/format', type='jsonrpc', auth='user')
    def format_note(self, text, **kwargs):
        """Format transcribed text into a professional note using GPT.

        Args:
            text: Raw transcription text.

        Returns:
            dict with 'text' on success or 'error' on failure.
        """
        ICP = request.env['ir.config_parameter'].sudo()
        api_key = ICP.get_param('fusion_notes.openai_api_key', '')

        if not api_key:
            return {'error': 'OpenAI API key not configured.'}

        model = ICP.get_param('fusion_notes.ai_model', 'gpt-4o-mini')

        try:
            import requests as req
        except ImportError:
            return {'error': 'Python requests library not available.'}

        system_prompt = (
            "You are a professional note formatter. Rewrite the following "
            "voice transcription as a clean, professional log entry.\n"
            "Rules:\n"
            "- ALWAYS output in English regardless of input language\n"
            "- If the input is in another language, translate it to English\n"
            "- Fix grammar and punctuation\n"
            "- Remove filler words (um, uh, like, you know, so, basically)\n"
            "- Keep ALL facts, names, dates, and details exactly as stated\n"
            "- Organize into clear, concise sentences\n"
            "- Use professional tone appropriate for clinical/business notes\n"
            "- Do NOT add information that was not in the original\n"
            "- Do NOT add headers, bullet points, or extra formatting "
            "unless the content clearly warrants it\n"
            "- Return ONLY the formatted text, no explanations or preamble"
        )

        try:
            response = req.post(
                'https://api.openai.com/v1/chat/completions',
                headers={
                    'Authorization': f'Bearer {api_key}',
                    'Content-Type': 'application/json',
                },
                json={
                    'model': model,
                    'messages': [
                        {'role': 'system', 'content': system_prompt},
                        {'role': 'user', 'content': text},
                    ],
                    'max_tokens': 1000,
                    'temperature': 0.3,
                },
                timeout=30,
            )
            response.raise_for_status()
            result = response.json()
            formatted = result['choices'][0]['message']['content'].strip()
            return {'text': formatted}

        except Exception as e:
            _logger.error('GPT formatting error: %s', e)
            return {'error': f'Formatting failed: {e}'}

    # ------------------------------------------------------------------
    # Post note to chatter
    # ------------------------------------------------------------------

    @http.route('/fusion_notes/post_note', type='jsonrpc', auth='user')
    def post_note(self, thread_model, thread_id, body, **kwargs):
        """Post a voice note to the specified record's chatter.

        Args:
            thread_model: The Odoo model name (e.g. 'sale.order').
            thread_id: The record ID.
            body: The note text to post.

        Returns:
            dict with 'success' or 'error'.
        """
        try:
            record = request.env[thread_model].browse(int(thread_id))
            if not record.exists():
                return {'error': 'Record not found.'}

            record.message_post(
                body=body,
                message_type='comment',
                subtype_xmlid='mail.mt_note',
            )
            return {'success': True}
        except Exception as e:
            _logger.error('Failed to post voice note: %s', e)
            return {'error': f'Failed to post note: {e}'}
