# -*- coding: utf-8 -*-
import babel.dates
import pytz
import logging
import odoo
from odoo import models, api
from odoo.osv import expression
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from odoo.tools.misc import posix_to_ldml, file_open
from odoo import http
from odoo.http import request
import werkzeug
from datetime import datetime

_logger = logging.getLogger(__name__)


def format_date(env, value, lang_code=False, date_format=False):
    if not value:
        return ''
    if isinstance(value, str):
        try:
            # Convert string to datetime object for Odoo 18
            if len(value) > 10:  # datetime
                value = datetime.fromisoformat(value.replace('Z', '+00:00'))
                value = odoo.fields.Datetime.context_timestamp(env['res.lang'], value)
            else:  # date
                value = datetime.fromisoformat(value)
        except ValueError:
            return ''

    lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
    locale = babel.Locale.parse(lang.code)
    locale = str(locale)
    if locale.lower().startswith('ar'):
        locale = "ar"
    if not date_format:
        date_format = posix_to_ldml(lang.date_format, locale=locale)

    return babel.dates.format_date(value, format=date_format, locale=locale)


# Only override if not already overridden
if not hasattr(odoo.tools.misc, '_original_format_date'):
    odoo.tools.misc._original_format_date = odoo.tools.misc.format_date
    odoo.tools.misc.format_date = format_date


class WebClientInherit(http.Controller):
    @http.route('/web/webclient/locale/<string:lang>', type='http', auth="none")
    def load_locale(self, lang):
        magic_file_finding = [lang.replace("_", '-').lower(), lang.split('_')[0]]
        for code in magic_file_finding:
            if code.lower().startswith('ar'):
                code = 'ar-sa'
            try:
                # Updated for Odoo 18 file structure
                file_path = f'web/static/lib/moment/locale/{code}.js'
                file_content = file_open(file_path, 'rb').read()

                return request.make_response(
                    file_content,
                    headers=[
                        ('Content-Type', 'application/javascript; charset=utf-8'),
                        ('Cache-Control', 'max-age=36000'),
                    ]
                )
            except (IOError, FileNotFoundError):
                _logger.debug("No moment locale for code %s", code)

        return request.make_response("", headers=[
            ('Content-Type', 'application/javascript'),
            ('Cache-Control', 'max-age=36000'),
        ])


class BaseModelExtend(models.BaseModel):
    _name = 'basemodel.extend_custom_months'
    _description = 'Base Model Extension for Custom Months'

    def _register_hook(self):
        # Store original method
        original_method = models.BaseModel._read_group_format_result

        @api.model
        def _read_group_format_result_custom(self, rows_dict, lazy_groupby):
            """
            Enhanced version of _read_group_format_result with Arabic locale support.
            Overrides Odoo 18's method to use 'ar' locale instead of 'ar_SY' for Arabic.
            """
            from odoo.models import READ_GROUP_TIME_GRANULARITY, READ_GROUP_DISPLAY_FORMAT
            from odoo.tools.misc import get_lang
            import datetime

            for group in lazy_groupby:
                field_name = group.split(':')[0].split('.')[0]
                field = self._fields.get(field_name)
                if not field:
                    continue

                if field.type in ('date', 'datetime'):
                    granularity = group.split(':')[1] if ':' in group else 'month'
                    if granularity in READ_GROUP_TIME_GRANULARITY:
                        # Get locale and modify for Arabic
                        lang = get_lang(self.env)
                        locale = lang.code
                        if locale.lower().startswith('ar'):
                            locale = "ar"

                        fmt = DEFAULT_SERVER_DATETIME_FORMAT if field.type == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
                        interval = READ_GROUP_TIME_GRANULARITY[granularity]
                elif field.type == "properties":
                    self._read_group_format_result_properties(rows_dict, group)
                    continue

                for row in rows_dict:
                    value = row.get(group)

                    if isinstance(value, models.BaseModel):
                        row[group] = (value.id, value.sudo().display_name) if value else False
                        value = value.id

                    if not value and field.type == 'many2many':
                        additional_domain = [(field_name, 'not any', [])]
                    else:
                        additional_domain = [(field_name, '=', value)]

                    if field.type in ('date', 'datetime'):
                        if value and isinstance(value, (datetime.date, datetime.datetime)):
                            range_start = value
                            range_end = value + interval
                            if field.type == 'datetime':
                                tzinfo = None
                                if self._context.get('tz') in pytz.all_timezones_set:
                                    tzinfo = pytz.timezone(self._context['tz'])
                                    range_start = tzinfo.localize(range_start).astimezone(pytz.utc)
                                    range_end = tzinfo.localize(range_end).astimezone(pytz.utc)

                                label = babel.dates.format_datetime(
                                    range_start, format=READ_GROUP_DISPLAY_FORMAT[granularity],
                                    tzinfo=tzinfo, locale=locale
                                )
                            else:
                                label = babel.dates.format_date(
                                    value, format=READ_GROUP_DISPLAY_FORMAT[granularity],
                                    locale=locale
                                )
                            # Special case for weeks
                            if granularity == 'week':
                                from odoo.tools import date_utils
                                year, week = date_utils.weeknumber(
                                    babel.Locale.parse(locale),
                                    value,
                                )
                                label = f"W{week} {year:04}"

                            range_start = range_start.strftime(fmt)
                            range_end = range_end.strftime(fmt)
                            row[group] = label
                            row.setdefault('__range', {})[group] = {'from': range_start, 'to': range_end}
                            additional_domain = [
                                '&',
                                    (field_name, '>=', range_start),
                                    (field_name, '<', range_end),
                            ]
                        elif not value:
                            row.setdefault('__range', {})[group] = False

                    row['__domain'] = expression.AND([row.get('__domain', []), additional_domain])

        # Only override if not already overridden
        if not hasattr(models.BaseModel, '_months_custom_override'):
            models.BaseModel._months_custom_override = True
            models.BaseModel._read_group_format_result = _read_group_format_result_custom

        return super(BaseModelExtend, self)._register_hook()