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

from odoo import api, fields, models


class FusionClientProfile(models.Model):
    _name = 'fusion.client.profile'
    _description = 'Client Profile'
    _order = 'last_name, first_name'
    _rec_name = 'display_name'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    # ------------------------------------------------------------------
    # PERSONAL INFORMATION (from ADP XML Section 1)
    # ------------------------------------------------------------------
    partner_id = fields.Many2one(
        'res.partner', string='Odoo Contact',
        help='Linked contact record in Odoo',
    )
    first_name = fields.Char(string='First Name', tracking=True)
    last_name = fields.Char(string='Last Name', tracking=True)
    middle_initial = fields.Char(string='Middle Initial')
    display_name = fields.Char(
        string='Name', compute='_compute_display_name', store=True,
    )
    health_card_number = fields.Char(
        string='Health Card Number', index=True, tracking=True,
        help='Ontario Health Card Number (10 digits)',
    )
    health_card_version = fields.Char(string='Health Card Version')
    date_of_birth = fields.Date(string='Date of Birth', tracking=True)
    ltch_name = fields.Char(
        string='Long-Term Care Home',
        help='Name of LTCH if applicable',
    )

    # ------------------------------------------------------------------
    # ADDRESS
    # ------------------------------------------------------------------
    unit_number = fields.Char(string='Unit Number')
    street_number = fields.Char(string='Street Number')
    street_name = fields.Char(string='Street Name')
    rural_route = fields.Char(string='Lot/Concession/Rural Route')
    city = fields.Char(string='City', index=True, tracking=True)
    province = fields.Char(string='Province', default='ON')
    postal_code = fields.Char(string='Postal Code')

    # ------------------------------------------------------------------
    # CONTACT
    # ------------------------------------------------------------------
    home_phone = fields.Char(string='Home Phone')
    business_phone = fields.Char(string='Business Phone')
    phone_extension = fields.Char(string='Phone Extension')

    # ------------------------------------------------------------------
    # BENEFITS ELIGIBILITY (from XML confirmationOfBenefit)
    # ------------------------------------------------------------------
    receives_social_assistance = fields.Boolean(
        string='Receives Social Assistance', tracking=True,
    )
    benefit_type = fields.Selection([
        ('owp', 'Ontario Works Program (OWP)'),
        ('odsp', 'Ontario Disability Support Program (ODSP)'),
        ('acsd', 'Assistance to Children with Severe Disabilities (ACSD)'),
    ], string='Benefit Type', tracking=True)
    wsib_eligible = fields.Boolean(string='WSIB Eligible', tracking=True)
    vac_eligible = fields.Boolean(
        string='Veterans Affairs Canada Eligible', tracking=True,
    )

    # ------------------------------------------------------------------
    # CURRENT MEDICAL STATUS (updated from latest XML)
    # ------------------------------------------------------------------
    medical_condition = fields.Text(
        string='Medical Condition/Diagnosis', tracking=True,
        help='Current presenting medical condition from latest ADP application',
    )
    mobility_status = fields.Text(
        string='Functional Mobility Status', tracking=True,
        help='Current functional mobility status from latest ADP application',
    )
    last_assessment_date = fields.Date(
        string='Last Assessment Date', tracking=True,
    )

    # ------------------------------------------------------------------
    # RELATIONSHIPS
    # ------------------------------------------------------------------
    application_data_ids = fields.One2many(
        'fusion.adp.application.data', 'profile_id',
        string='ADP Applications',
    )
    # Chat is handled via Odoo's native AI agent (discuss.channel with ai_chat type)

    # ------------------------------------------------------------------
    # COMPUTED FIELDS
    # ------------------------------------------------------------------
    claim_count = fields.Integer(
        string='Claims', compute='_compute_claim_stats', store=True,
    )
    total_adp_funded = fields.Monetary(
        string='Total ADP Funded', compute='_compute_claim_stats', store=True,
        currency_field='currency_id',
    )
    total_client_portion = fields.Monetary(
        string='Total Client Portion', compute='_compute_claim_stats', store=True,
        currency_field='currency_id',
    )
    total_amount = fields.Monetary(
        string='Total Amount', compute='_compute_claim_stats', store=True,
        currency_field='currency_id',
    )
    currency_id = fields.Many2one(
        'res.currency', string='Currency',
        default=lambda self: self.env.company.currency_id,
    )
    application_count = fields.Integer(
        string='Applications', compute='_compute_application_count',
    )

    # ------------------------------------------------------------------
    # AI ANALYSIS (auto-computed from application data)
    # ------------------------------------------------------------------
    ai_summary = fields.Text(
        string='Summary',
        compute='_compute_ai_analysis',
    )
    ai_risk_flags = fields.Text(
        string='Risk Flags',
        compute='_compute_ai_analysis',
    )
    ai_last_analyzed = fields.Datetime(string='Last AI Analysis')

    # ------------------------------------------------------------------
    # COMPUTED METHODS
    # ------------------------------------------------------------------
    @api.depends('first_name', 'last_name')
    def _compute_display_name(self):
        for profile in self:
            parts = [profile.last_name or '', profile.first_name or '']
            profile.display_name = ', '.join(p for p in parts if p) or 'New Profile'

    @api.depends('partner_id', 'partner_id.sale_order_ids',
                 'partner_id.sale_order_ids.x_fc_adp_portion_total',
                 'partner_id.sale_order_ids.x_fc_client_portion_total',
                 'partner_id.sale_order_ids.amount_total')
    def _compute_claim_stats(self):
        for profile in self:
            if profile.partner_id:
                orders = self.env['sale.order'].search([
                    ('partner_id', '=', profile.partner_id.id),
                    ('x_fc_sale_type', '!=', False),
                ])
                profile.claim_count = len(orders)
                profile.total_adp_funded = sum(orders.mapped('x_fc_adp_portion_total'))
                profile.total_client_portion = sum(orders.mapped('x_fc_client_portion_total'))
                profile.total_amount = sum(orders.mapped('amount_total'))
            else:
                profile.claim_count = 0
                profile.total_adp_funded = 0
                profile.total_client_portion = 0
                profile.total_amount = 0

    def _compute_application_count(self):
        for profile in self:
            profile.application_count = len(profile.application_data_ids)

    @api.depends('application_data_ids', 'application_data_ids.application_date',
                 'application_data_ids.base_device', 'application_data_ids.reason_for_application')
    def _compute_ai_analysis(self):
        for profile in self:
            apps = profile.application_data_ids.sorted('application_date', reverse=True)

            # --- SUMMARY ---
            summary_lines = []

            # Number of applications
            app_count = len(apps)
            summary_lines.append(f"Total Applications: {app_count}")

            # Last funding history
            if apps:
                latest = apps[0]
                date_str = latest.application_date.strftime('%B %d, %Y') if latest.application_date else 'Unknown date'
                device = latest.base_device or 'Not specified'
                category = dict(latest._fields['device_category'].selection).get(
                    latest.device_category, latest.device_category or 'N/A'
                ) if latest.device_category else 'N/A'
                summary_lines.append(f"Last Application: {date_str}")
                summary_lines.append(f"Last Device: {device} ({category})")

                # Reason for last application
                reason = latest.reason_for_application or 'Not specified'
                summary_lines.append(f"Reason: {reason}")

                # Authorizer
                auth_name = f"{latest.authorizer_first_name or ''} {latest.authorizer_last_name or ''}".strip()
                if auth_name:
                    summary_lines.append(f"Authorizer: {auth_name}")

                # All devices received (unique)
                devices = set()
                for a in apps:
                    if a.base_device:
                        devices.add(a.base_device)
                if len(devices) > 1:
                    summary_lines.append(f"All Devices: {', '.join(sorted(devices))}")
            else:
                summary_lines.append("No applications on file.")

            profile.ai_summary = '\n'.join(summary_lines)

            # --- RISK FLAGS ---
            risk_lines = []

            if app_count >= 2:
                # Calculate frequency
                dated_apps = [a for a in apps if a.application_date]
                if len(dated_apps) >= 2:
                    dates = sorted([a.application_date for a in dated_apps])
                    total_span = (dates[-1] - dates[0]).days
                    if total_span > 0:
                        avg_days = total_span / (len(dates) - 1)
                        if avg_days < 365:
                            risk_lines.append(
                                f"High Frequency: {app_count} applications over "
                                f"{total_span} days (avg {avg_days:.0f} days apart)"
                            )
                        elif avg_days < 730:
                            risk_lines.append(
                                f"Moderate Frequency: {app_count} applications over "
                                f"{total_span // 365} year(s) (avg {avg_days:.0f} days apart)"
                            )
                        else:
                            risk_lines.append(
                                f"Normal Frequency: {app_count} applications over "
                                f"{total_span // 365} year(s) (avg {avg_days:.0f} days apart)"
                            )

                    # Check for multiple replacements
                    replacements = [a for a in apps if a.reason_for_application and 'replacement' in a.reason_for_application.lower()]
                    if len(replacements) >= 2:
                        risk_lines.append(f"Multiple Replacements: {len(replacements)} replacement applications")

            if not risk_lines:
                risk_lines.append("No flags identified.")

            profile.ai_risk_flags = '\n'.join(risk_lines)

    # ------------------------------------------------------------------
    # ACTIONS
    # ------------------------------------------------------------------
    def action_view_claims(self):
        """Open sale orders for this client."""
        self.ensure_one()
        return {
            'type': 'ir.actions.act_window',
            'name': f'Claims - {self.display_name}',
            'res_model': 'sale.order',
            'view_mode': 'list,form',
            'domain': [('partner_id', '=', self.partner_id.id), ('x_fc_sale_type', '!=', False)],
        }

    def action_view_applications(self):
        """Open parsed ADP application data for this client."""
        self.ensure_one()
        return {
            'type': 'ir.actions.act_window',
            'name': f'Applications - {self.display_name}',
            'res_model': 'fusion.adp.application.data',
            'view_mode': 'list,form',
            'domain': [('profile_id', '=', self.id)],
        }

    def action_open_ai_chat(self):
        """Open AI chat about this client using Odoo's native AI agent."""
        self.ensure_one()
        agent = self.env.ref('fusion_claims.ai_agent_fusion_claims', raise_if_not_found=False)
        if agent:
            # Create channel with client context so the AI knows which client
            channel = agent._create_ai_chat_channel()
            # Post an initial context message about this client
            initial_prompt = (
                f"I want to ask about client {self.display_name} "
                f"(Profile ID: {self.id}, Health Card: {self.health_card_number or 'N/A'}). "
                f"Please look up their details."
            )
            return {
                'type': 'ir.actions.client',
                'tag': 'agent_chat_action',
                'params': {
                    'channelId': channel.id,
                    'user_prompt': initial_prompt,
                },
            }
        return {'type': 'ir.actions.act_window_close'}
