import logging
from datetime import datetime
from datetime import timedelta

from odoo import fields
from odoo.http import request

_logger = logging.getLogger(__name__)


def _get_day_names(self, env=None, request_obj=None):
    """Get translated day names list (0=Monday to 6=Sunday)."""
    req = request_obj or request
    if env is None:
        env = req.env

    context_lang = env.context.get("lang", "NO_LANG")
    _logger.info("📅 _get_day_names called with context lang: %s", context_lang)

    group_order_model = env["group.order"]
    fields_def = group_order_model.fields_get(["pickup_day"])
    selection_options = fields_def.get("pickup_day", {}).get("selection", [])
    day_names = [name for value, name in selection_options]
    _logger.info(
        "📅 Returning day names: %s",
        day_names[:3] if len(day_names) >= 3 else day_names,
    )
    return day_names


def _get_next_date_for_weekday(self, weekday_num, start_date=None):
    if start_date is None:
        start_date = datetime.now().date()
    target_weekday = int(weekday_num)
    current_weekday = start_date.weekday()
    days_ahead = target_weekday - current_weekday
    if days_ahead <= 0:
        days_ahead += 7
    return start_date + timedelta(days=days_ahead)


def _slot_time_label(self, slot):
    try:
        if slot.label:
            return slot.label
        sh = float(slot.start_hour or 0.0)
        eh = float(slot.end_hour or 0.0)
        sh_h = int(sh)
        sh_m = int(round((sh - sh_h) * 60))
        eh_h = int(eh)
        eh_m = int(round((eh - eh_h) * 60))
        return f"{sh_h:02d}:{sh_m:02d}-{eh_h:02d}:{eh_m:02d}"
    except Exception as exc:
        _logger.debug(
            "_slot_time_label: failed for slot %s: %s", getattr(slot, "id", None), exc
        )
        return ""


def _format_datetime_to_str(self, dt_val):
    if not dt_val:
        return ""
    try:
        if isinstance(dt_val, str):
            dt = fields.Datetime.to_datetime(dt_val)
            return dt.strftime("%d/%m/%Y")
        if hasattr(dt_val, "strftime"):
            return dt_val.strftime("%d/%m/%Y")
        return str(dt_val)
    except Exception:
        return str(dt_val)


def _format_slot_pickup_info(self, group_order, slot, request_obj=None):
    pickup_day_name = ""
    pickup_date_str = ""
    pickup_day_index = None
    try:
        pickup_day_index = int(slot.weekday)
    except Exception:
        pickup_day_index = None

    if pickup_day_index is not None:
        try:
            req = request_obj or request
            day_names = _get_day_names(self, env=req.env, request_obj=req)
            pickup_day_name = day_names[pickup_day_index % len(day_names)]
        except Exception:
            pickup_day_name = ""

    time_label = _slot_time_label(self, slot)

    dt_val = getattr(group_order, "next_pickup_datetime", None) or getattr(
        group_order, "pickup_date", None
    )
    pickup_date_str = _format_datetime_to_str(self, dt_val)

    if time_label:
        pickup_day_name = (
            f"{pickup_day_name} {time_label}" if pickup_day_name else time_label
        )

    return pickup_day_name, pickup_date_str, pickup_day_index


def _format_legacy_pickup_info(self, group_order, is_delivery, request_obj=None):
    pickup_day_name = ""
    pickup_date_str = ""
    pickup_day_index = None
    try:
        pickup_day_index = int(group_order.pickup_day)
    except Exception:
        pickup_day_index = None

    if pickup_day_index is not None:
        try:
            req = request_obj or request
            day_names = _get_day_names(self, env=req.env, request_obj=req)
            pickup_day_name = day_names[pickup_day_index % len(day_names)]
        except Exception:
            pickup_day_name = ""

    if group_order.pickup_date:
        if is_delivery:
            if group_order.delivery_date:
                pickup_date_str = group_order.delivery_date.strftime("%d/%m/%Y")
                if pickup_day_index is not None:
                    try:
                        req = request_obj or request
                        day_names = _get_day_names(self, env=req.env, request_obj=req)
                        next_day_index = (pickup_day_index + 1) % 7
                        pickup_day_name = day_names[next_day_index]
                    except Exception:
                        pickup_day_name = ""
            else:
                pickup_date_str = group_order.pickup_date.strftime("%d/%m/%Y")
        else:
            pickup_date_str = group_order.pickup_date.strftime("%d/%m/%Y")

    return pickup_day_name, pickup_date_str, pickup_day_index


def _format_pickup_info(self, group_order, is_delivery, request_obj=None):
    slot = getattr(group_order, "next_pickup_slot_id", False) or False
    if slot:
        return _format_slot_pickup_info(
            self,
            group_order,
            slot,
            request_obj=request_obj,
        )
    return _format_legacy_pickup_info(
        self,
        group_order,
        is_delivery,
        request_obj=request_obj,
    )
