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

import json
import logging

from odoo import api, fields, models
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)


class FusionClientChatSession(models.Model):
    _name = 'fusion.client.chat.session'
    _description = 'Client Intelligence Chat Session'
    _order = 'create_date desc'

    name = fields.Char(string='Session Title', required=True,
                       default=lambda self: f'Chat - {fields.Date.today()}')
    profile_id = fields.Many2one(
        'fusion.client.profile', string='Client Profile',
        ondelete='set null',
        help='If set, chat is scoped to this specific client',
    )
    user_id = fields.Many2one(
        'res.users', string='User', default=lambda self: self.env.user,
        required=True,
    )
    message_ids = fields.One2many(
        'fusion.client.chat.message', 'session_id', string='Messages',
    )
    state = fields.Selection([
        ('active', 'Active'),
        ('archived', 'Archived'),
    ], default='active', string='State')

    # Input field for the form view
    user_input = fields.Text(string='Your Question')

    def action_send_message(self):
        """Process user message and generate AI response."""
        self.ensure_one()
        if not self.user_input or not self.user_input.strip():
            return

        question = self.user_input.strip()

        # Create user message
        self.env['fusion.client.chat.message'].create({
            'session_id': self.id,
            'role': 'user',
            'content': question,
        })

        # Generate AI response
        try:
            response = self._generate_ai_response(question)
        except Exception as e:
            _logger.exception('AI chat error: %s', e)
            response = f'Sorry, I encountered an error processing your question. Error: {str(e)}'

        # Create assistant message
        msg = self.env['fusion.client.chat.message'].create({
            'session_id': self.id,
            'role': 'assistant',
            'content': response,
        })

        # Clear input
        self.user_input = False
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'fusion.client.chat.session',
            'view_mode': 'form',
            'res_id': self.id,
            'target': 'current',
        }

    def _generate_ai_response(self, question):
        """Generate an AI-powered response to the user question.

        Uses OpenAI API to analyze the question, query relevant data,
        and formulate a response.
        """
        ICP = self.env['ir.config_parameter'].sudo()
        api_key = ICP.get_param('fusion_claims.ai_api_key', '')
        if not api_key:
            return self._generate_local_response(question)

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

        # Build context about available data
        context_data = self._build_data_context(question)

        # Build system prompt
        system_prompt = self._build_system_prompt()

        # Build messages
        messages = [{'role': 'system', 'content': system_prompt}]

        # Add conversation history (last 10 messages)
        history = self.message_ids.sorted('create_date')[-10:]
        for msg in history:
            messages.append({'role': msg.role, 'content': msg.content})

        # Add current question with data context
        user_msg = question
        if context_data:
            user_msg += f'\n\n--- Retrieved Data ---\n{context_data}'
        messages.append({'role': 'user', 'content': user_msg})

        # Call OpenAI API
        try:
            import requests
            response = requests.post(
                'https://api.openai.com/v1/chat/completions',
                headers={
                    'Authorization': f'Bearer {api_key}',
                    'Content-Type': 'application/json',
                },
                json={
                    'model': ai_model,
                    'messages': messages,
                    'max_tokens': 2000,
                    'temperature': 0.3,
                },
                timeout=30,
            )
            response.raise_for_status()
            result = response.json()
            return result['choices'][0]['message']['content']
        except ImportError:
            return self._generate_local_response(question)
        except Exception as e:
            _logger.warning('OpenAI API error: %s', e)
            return self._generate_local_response(question)

    def _generate_local_response(self, question):
        """Generate a response without AI, using direct database queries.

        This is the fallback when no API key is configured.
        """
        question_lower = question.lower()
        Profile = self.env['fusion.client.profile']
        SaleOrder = self.env['sale.order']

        # If scoped to a specific profile
        if self.profile_id:
            profile = self.profile_id
            orders = SaleOrder.search([
                ('partner_id', '=', profile.partner_id.id),
                ('x_fc_sale_type', '!=', False),
            ]) if profile.partner_id else SaleOrder

            lines = []
            lines.append(f'**Client: {profile.display_name}**')
            lines.append(f'- Health Card: {profile.health_card_number or "N/A"}')
            lines.append(f'- Date of Birth: {profile.date_of_birth or "N/A"}')
            lines.append(f'- City: {profile.city or "N/A"}')
            lines.append(f'- Medical Condition: {profile.medical_condition or "N/A"}')
            lines.append(f'- Mobility Status: {profile.mobility_status or "N/A"}')
            lines.append(f'- Total Claims: {len(orders)}')
            lines.append(f'- Total ADP Funded: ${profile.total_adp_funded:,.2f}')
            lines.append(f'- Total Client Portion: ${profile.total_client_portion:,.2f}')

            if orders:
                lines.append('\n**Claims History:**')
                for order in orders[:10]:
                    status = dict(order._fields['x_fc_adp_application_status'].selection).get(
                        order.x_fc_adp_application_status, order.x_fc_adp_application_status or 'N/A'
                    )
                    lines.append(
                        f'- {order.name}: {order.x_fc_sale_type or "N/A"} | '
                        f'Status: {status} | '
                        f'ADP: ${order.x_fc_adp_portion_total:,.2f} | '
                        f'Client: ${order.x_fc_client_portion_total:,.2f}'
                    )

            apps = profile.application_data_ids[:5]
            if apps:
                lines.append('\n**Application History:**')
                for app in apps:
                    lines.append(
                        f'- {app.application_date or "No date"}: '
                        f'{app.device_category or "N/A"} | '
                        f'Device: {app.base_device or "N/A"} | '
                        f'Reason: {app.reason_for_application or "N/A"}'
                    )

            return '\n'.join(lines)

        # Global queries
        total_profiles = Profile.search_count([])
        total_orders = SaleOrder.search_count([('x_fc_sale_type', '!=', False)])

        if 'how many' in question_lower or 'count' in question_lower:
            if 'client' in question_lower or 'profile' in question_lower:
                return f'There are currently **{total_profiles}** client profiles in the system.'
            if 'claim' in question_lower or 'order' in question_lower or 'case' in question_lower:
                return f'There are currently **{total_orders}** claims/orders in the system.'

        # Search for specific client
        if 'find' in question_lower or 'search' in question_lower or 'show' in question_lower:
            # Try to extract name from question
            words = question.split()
            profiles = Profile.search([], limit=20)
            for word in words:
                if len(word) > 2 and word[0].isupper():
                    found = Profile.search([
                        '|',
                        ('first_name', 'ilike', word),
                        ('last_name', 'ilike', word),
                    ], limit=5)
                    if found:
                        profiles = found
                        break

            if profiles:
                lines = [f'Found **{len(profiles)}** matching profile(s):']
                for p in profiles[:10]:
                    lines.append(
                        f'- **{p.display_name}** | HC: {p.health_card_number or "N/A"} | '
                        f'City: {p.city or "N/A"} | Claims: {p.claim_count}'
                    )
                return '\n'.join(lines)

        return (
            f'I have access to **{total_profiles}** client profiles and **{total_orders}** claims. '
            f'You can ask me questions like:\n'
            f'- "How many clients are from Brampton?"\n'
            f'- "Find client Raymond Wellesley"\n'
            f'- "Show all clients with CVA diagnosis"\n\n'
            f'For more intelligent responses, configure an OpenAI API key in '
            f'Fusion Claims > Configuration > Settings.'
        )

    def _build_system_prompt(self):
        """Build the system prompt for the AI."""
        profile_context = ''
        if self.profile_id:
            p = self.profile_id
            profile_context = f"""
You are currently looking at a specific client profile:
- Name: {p.display_name}
- Health Card: {p.health_card_number or 'N/A'}
- DOB: {p.date_of_birth or 'N/A'}
- City: {p.city or 'N/A'}
- Medical Condition: {p.medical_condition or 'N/A'}
- Mobility Status: {p.mobility_status or 'N/A'}
- Total Claims: {p.claim_count}
- Total ADP Funded: ${p.total_adp_funded:,.2f}
- Total Client Portion: ${p.total_client_portion:,.2f}
"""

        return f"""You are a helpful AI assistant for Fusion Claims, a healthcare equipment claims management system.
You help users find information about clients, their ADP (Assistive Devices Program) claims, funding history, 
medical conditions, and devices.

Available data includes:
- Client profiles with personal info, health card numbers, addresses, medical conditions
- ADP application data parsed from XML submissions  
- Sale orders with funding type, status, ADP/client portions
- Device information (wheelchairs, walkers, power bases, seating)

Funding types: ADP, ODSP, WSIB, March of Dimes, Muscular Dystrophy, Insurance, Hardship Funding, Rentals, Direct/Private
Client types: REG (75%/25%), ODS, OWP, ACS, LTC, SEN, CCA (100%/0%)
{profile_context}
Answer concisely and include specific data when available. Format monetary values with $ and commas."""

    def _build_data_context(self, question):
        """Query relevant data based on the question to provide context to AI."""
        question_lower = question.lower()
        context_parts = []

        Profile = self.env['fusion.client.profile']
        SaleOrder = self.env['sale.order']

        if self.profile_id:
            # Scoped to specific client - load their data
            p = self.profile_id
            orders = SaleOrder.search([
                ('partner_id', '=', p.partner_id.id),
                ('x_fc_sale_type', '!=', False),
            ], limit=20) if p.partner_id else SaleOrder

            if orders:
                order_data = []
                for o in orders:
                    order_data.append({
                        'name': o.name,
                        'sale_type': o.x_fc_sale_type,
                        'status': o.x_fc_adp_application_status,
                        'adp_total': o.x_fc_adp_portion_total,
                        'client_total': o.x_fc_client_portion_total,
                        'amount_total': o.amount_total,
                        'date': str(o.date_order) if o.date_order else '',
                    })
                context_parts.append(f'Orders: {json.dumps(order_data)}')

            apps = p.application_data_ids[:10]
            if apps:
                app_data = []
                for a in apps:
                    app_data.append({
                        'date': str(a.application_date) if a.application_date else '',
                        'device_category': a.device_category,
                        'base_device': a.base_device or '',
                        'condition': a.medical_condition or '',
                        'reason': a.reason_for_application or '',
                        'authorizer': f'{a.authorizer_first_name} {a.authorizer_last_name}'.strip(),
                    })
                context_parts.append(f'Applications: {json.dumps(app_data)}')
        else:
            # Global query - provide summary stats
            total_profiles = Profile.search_count([])
            total_orders = SaleOrder.search_count([('x_fc_sale_type', '!=', False)])

            # City distribution
            if 'city' in question_lower or 'cities' in question_lower or 'where' in question_lower:
                city_data = SaleOrder.read_group(
                    [('x_fc_sale_type', '!=', False), ('partner_id.city', '!=', False)],
                    ['partner_id'],
                    ['partner_id'],
                    limit=20,
                )
                context_parts.append(f'Total profiles: {total_profiles}, Total orders: {total_orders}')

            context_parts.append(f'Summary: {total_profiles} profiles, {total_orders} orders')

        return '\n'.join(context_parts) if context_parts else ''


class FusionClientChatMessage(models.Model):
    _name = 'fusion.client.chat.message'
    _description = 'Chat Message'
    _order = 'create_date asc'

    session_id = fields.Many2one(
        'fusion.client.chat.session', string='Session',
        required=True, ondelete='cascade',
    )
    role = fields.Selection([
        ('user', 'User'),
        ('assistant', 'Assistant'),
    ], string='Role', required=True)
    content = fields.Text(string='Content', required=True)
    timestamp = fields.Datetime(
        string='Timestamp', default=fields.Datetime.now,
    )
