import re

from odoo import api, fields, models


class TierMailbox(models.Model):
    _name = 'tier.mailbox'
    _description = 'Tier Mailbox'
    _rec_name = 'name'

    name = fields.Char(string='Name', required=True)
    code = fields.Char(string='Code', required=True)
    description = fields.Text(string='Description')
    user_ids = fields.Many2many(
        'res.users',
        string='Allowed Users',
        help='Users who have access to this mailbox. If empty, all users can access it.',
    )
    is_lead_inbox = fields.Boolean(string='Lead Inbox', default=False)
    is_ticket_inbox = fields.Boolean(string='Ticket Inbox', default=False)

    _sql_constraints = [
        ('code_unique', 'UNIQUE(code)', 'The mailbox code must be unique.'),
    ]

    @api.model
    def get_accessible_mailboxes(self):
        """Return mailboxes accessible to the current user.

        A mailbox is accessible if the current user is in user_ids,
        or if user_ids is empty (open to all).
        """
        uid = self.env.uid
        domain = [
            '|',
            ('user_ids', '=', False),
            ('user_ids', 'in', [uid]),
        ]
        mailboxes = self.search(domain)
        return mailboxes.read(['id', 'name', 'code', 'is_lead_inbox', 'is_ticket_inbox'])

    @api.model
    def get_mailbox_conversations(self, mailbox_id, limit=50):
        """Return messages in a mailbox grouped by author (partner).

        Returns a list of conversations:
        [{
            'partner_id': int,
            'partner_name': str,
            'partner_avatar_url': str,
            'last_message_preview': str,  # first 80 chars of body text
            'last_message_date': str,
            'channel_code': str|None,  # email, matrix, or None
            'message_count': int,
        }]
        """
        mailbox_tags = self.env['tier.mailbox.tag'].search([
            ('mailbox_id', '=', mailbox_id),
        ], order='message_id desc', limit=500)

        if not mailbox_tags:
            return []

        message_ids = mailbox_tags.mapped('message_id')

        # Group by author — show last message in conversation (ours or theirs)
        conversations_by_partner = {}
        for message in message_ids.sorted(key=lambda m: m.id, reverse=True):
            author = message.author_id
            partner_id = author.id if author else 0

            if partner_id not in conversations_by_partner:
                # Strip HTML for preview
                body_text = re.sub(r'<[^>]+>', '', message.body or '')
                preview = body_text[:80].strip() if body_text else (message.subject or '')

                # If preview is still empty, use subject
                if not preview and message.subject:
                    preview = message.subject[:80]

                # Get channel code
                channel_code = None
                if message.channel_tag_ids:
                    channel_code = message.channel_tag_ids[0].code

                conversations_by_partner[partner_id] = {
                    'partner_id': partner_id,
                    'partner_name': author.name if author else (message.email_from or 'Неизвестный'),
                    'last_message_preview': preview or 'Нет текста',
                    'last_message_date': str(message.date or message.create_date or ''),
                    'channel_code': channel_code,
                    'message_count': 0,
                }

            conversations_by_partner[partner_id]['message_count'] += 1

        result = list(conversations_by_partner.values())[:limit]
        return result
