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

from dateutil.relativedelta import relativedelta

from odoo import models, fields, api, _


class FusionLTCFacility(models.Model):
    _name = 'fusion.ltc.facility'
    _description = 'LTC Facility'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _order = 'name'

    name = fields.Char(
        string='Facility Name',
        required=True,
        tracking=True,
    )
    code = fields.Char(
        string='Code',
        copy=False,
        readonly=True,
        default=lambda self: _('New'),
    )
    active = fields.Boolean(default=True)
    image_1920 = fields.Image(string='Image', max_width=1920, max_height=1920)

    partner_id = fields.Many2one(
        'res.partner',
        string='Contact Record',
        help='The facility as a contact in the system',
        tracking=True,
    )

    # Address
    street = fields.Char(string='Street')
    street2 = fields.Char(string='Street2')
    city = fields.Char(string='City')
    state_id = fields.Many2one(
        'res.country.state',
        string='Province',
        domain="[('country_id', '=', country_id)]",
    )
    zip = fields.Char(string='Postal Code')
    country_id = fields.Many2one('res.country', string='Country')
    phone = fields.Char(string='Phone')
    email = fields.Char(string='Email')
    website = fields.Char(string='Website')

    # Key contacts
    director_of_care_id = fields.Many2one(
        'res.partner',
        string='Director of Care',
        tracking=True,
    )
    service_supervisor_id = fields.Many2one(
        'res.partner',
        string='Service Supervisor',
        tracking=True,
    )
    physiotherapist_ids = fields.Many2many(
        'res.partner',
        'ltc_facility_physiotherapist_rel',
        'facility_id',
        'partner_id',
        string='Physiotherapists',
        help='Primary contacts for equipment recommendations and communication',
    )

    # Structure
    number_of_floors = fields.Integer(string='Number of Floors')
    floor_ids = fields.One2many(
        'fusion.ltc.floor',
        'facility_id',
        string='Floors',
    )

    # Contract
    contract_start_date = fields.Date(string='Contract Start Date', tracking=True)
    contract_end_date = fields.Date(string='Contract End Date', tracking=True)
    contract_file = fields.Binary(
        string='Contract Document',
        attachment=True,
    )
    contract_file_filename = fields.Char(string='Contract Filename')
    contract_notes = fields.Text(string='Contract Notes')

    # Cleanup scheduling
    cleanup_frequency = fields.Selection([
        ('quarterly', 'Quarterly (Every 3 Months)'),
        ('semi_annual', 'Semi-Annual (Every 6 Months)'),
        ('annual', 'Annual (Yearly)'),
        ('custom', 'Custom Interval'),
    ], string='Cleanup Frequency', default='quarterly')
    cleanup_interval_days = fields.Integer(
        string='Custom Interval (Days)',
        help='Number of days between cleanups when using custom interval',
    )
    next_cleanup_date = fields.Date(
        string='Next Cleanup Date',
        compute='_compute_next_cleanup_date',
        store=True,
        readonly=False,
        tracking=True,
    )

    # Related records
    repair_ids = fields.One2many('fusion.ltc.repair', 'facility_id', string='Repairs')
    cleanup_ids = fields.One2many('fusion.ltc.cleanup', 'facility_id', string='Cleanups')

    # Computed counts
    repair_count = fields.Integer(compute='_compute_repair_count', string='Total Repairs')
    active_repair_count = fields.Integer(compute='_compute_repair_count', string='Active Repairs')
    cleanup_count = fields.Integer(compute='_compute_cleanup_count', string='Cleanups')

    notes = fields.Html(string='Notes')

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if vals.get('code', _('New')) == _('New'):
                vals['code'] = self.env['ir.sequence'].next_by_code('fusion.ltc.facility') or _('New')
        return super().create(vals_list)

    @api.depends('contract_start_date', 'cleanup_frequency', 'cleanup_interval_days')
    def _compute_next_cleanup_date(self):
        today = fields.Date.context_today(self)
        for facility in self:
            start = facility.contract_start_date
            freq = facility.cleanup_frequency
            if not start or not freq:
                if not facility.next_cleanup_date:
                    facility.next_cleanup_date = False
                continue

            interval = facility._get_cleanup_interval_days()
            delta = relativedelta(days=interval)

            candidate = start + delta
            while candidate < today:
                candidate += delta

            facility.next_cleanup_date = candidate

    def action_preview_contract(self):
        self.ensure_one()
        if not self.contract_file:
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('No Document'),
                    'message': _('No contract document has been uploaded yet.'),
                    'type': 'warning',
                    'sticky': False,
                },
            }

        attachment = self.env['ir.attachment'].search([
            ('res_model', '=', self._name),
            ('res_id', '=', self.id),
            ('res_field', '=', 'contract_file'),
        ], limit=1)

        if not attachment:
            attachment = self.env['ir.attachment'].search([
                ('res_model', '=', self._name),
                ('res_id', '=', self.id),
                ('name', '=', self.contract_file_filename or 'contract_file'),
            ], limit=1, order='id desc')

        if attachment:
            return {
                'type': 'ir.actions.client',
                'tag': 'fusion_claims.preview_document',
                'params': {
                    'attachment_id': attachment.id,
                    'title': _('Contract - %s', self.name),
                },
            }

        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': _('Error'),
                'message': _('Could not load contract document.'),
                'type': 'danger',
                'sticky': False,
            },
        }

    def _compute_repair_count(self):
        for facility in self:
            repairs = facility.repair_ids
            facility.repair_count = len(repairs)
            facility.active_repair_count = len(repairs.filtered(
                lambda r: r.stage_id and not r.stage_id.fold
            ))

    def _compute_cleanup_count(self):
        for facility in self:
            facility.cleanup_count = len(facility.cleanup_ids)

    def action_view_repairs(self):
        self.ensure_one()
        return {
            'name': _('Repairs - %s', self.name),
            'type': 'ir.actions.act_window',
            'res_model': 'fusion.ltc.repair',
            'view_mode': 'kanban,list,form',
            'domain': [('facility_id', '=', self.id)],
            'context': {'default_facility_id': self.id},
        }

    def action_view_cleanups(self):
        self.ensure_one()
        return {
            'name': _('Cleanups - %s', self.name),
            'type': 'ir.actions.act_window',
            'res_model': 'fusion.ltc.cleanup',
            'view_mode': 'list,kanban,form',
            'domain': [('facility_id', '=', self.id)],
            'context': {'default_facility_id': self.id},
        }

    def _get_cleanup_interval_days(self):
        mapping = {
            'quarterly': 90,
            'semi_annual': 180,
            'annual': 365,
        }
        if self.cleanup_frequency == 'custom':
            return self.cleanup_interval_days or 90
        return mapping.get(self.cleanup_frequency, 90)


class FusionLTCFloor(models.Model):
    _name = 'fusion.ltc.floor'
    _description = 'LTC Facility Floor'
    _order = 'sequence, name'

    facility_id = fields.Many2one(
        'fusion.ltc.facility',
        string='Facility',
        required=True,
        ondelete='cascade',
    )
    name = fields.Char(string='Floor Name', required=True)
    sequence = fields.Integer(string='Sequence', default=10)
    station_ids = fields.One2many(
        'fusion.ltc.station',
        'floor_id',
        string='Nursing Stations',
    )
    head_nurse_id = fields.Many2one(
        'res.partner',
        string='Head Nurse',
    )
    physiotherapist_id = fields.Many2one(
        'res.partner',
        string='Physiotherapist',
        help='Floor-level physiotherapist if different from facility level',
    )


class FusionLTCStation(models.Model):
    _name = 'fusion.ltc.station'
    _description = 'LTC Nursing Station'
    _order = 'sequence, name'

    floor_id = fields.Many2one(
        'fusion.ltc.floor',
        string='Floor',
        required=True,
        ondelete='cascade',
    )
    name = fields.Char(string='Station Name', required=True)
    sequence = fields.Integer(string='Sequence', default=10)
    head_nurse_id = fields.Many2one(
        'res.partner',
        string='Head Nurse',
    )
    phone = fields.Char(string='Phone')


class FusionLTCFamilyContact(models.Model):
    _name = 'fusion.ltc.family.contact'
    _description = 'LTC Resident Family Contact'
    _order = 'is_poa desc, name'

    partner_id = fields.Many2one(
        'res.partner',
        string='Resident',
        required=True,
        ondelete='cascade',
    )
    name = fields.Char(string='Contact Name', required=True)
    relationship = fields.Selection([
        ('spouse', 'Spouse'),
        ('child', 'Child'),
        ('sibling', 'Sibling'),
        ('parent', 'Parent'),
        ('guardian', 'Guardian'),
        ('poa', 'Power of Attorney'),
        ('other', 'Other'),
    ], string='Relationship')
    phone = fields.Char(string='Phone')
    phone2 = fields.Char(string='Phone 2')
    email = fields.Char(string='Email')
    is_poa = fields.Boolean(string='Is POA', help='Is this person the Power of Attorney?')
    notes = fields.Char(string='Notes')
