from __future__ import annotations

import logging
from html import escape

from aiogram import Bot
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup

from app.constants import STATUS_LINES, Status
from app.models import Booking, Order, User
from app.utils import format_money, format_visit_date

logger = logging.getLogger(__name__)


def order_keyboard(order_id: int) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="✅ Прийнято", callback_data=f"staff:order:{Status.ACCEPTED}:{order_id}"),
                InlineKeyboardButton(text="❌ Відхилено", callback_data=f"staff:order:{Status.REJECTED}:{order_id}"),
            ]
        ]
    )


def booking_keyboard(booking_id: int) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="✅ Прийнято", callback_data=f"staff:booking:{Status.ACCEPTED}:{booking_id}"),
                InlineKeyboardButton(text="❌ Відхилено", callback_data=f"staff:booking:{Status.REJECTED}:{booking_id}"),
            ]
        ]
    )


def _contact_line(user: User) -> str:
    if user.username:
        return f"💬 @{escape(user.username)}"
    return f'💬 <a href="tg://user?id={user.telegram_id}">написати клієнту</a>'


def order_group_body(order: Order, user: User, items_text: str) -> str:
    lines = [
        f"🍔 <b>Нове замовлення на доставку #{order.id}</b>",
        "",
        f"👤 {escape(order.name)}",
        f"📞 {escape(order.phone)}",
        f"📍 {escape(order.address)}",
        _contact_line(user),
    ]
    lines.extend(["", "<b>Замовлення:</b>", items_text or "—"])
    if order.subtotal:
        lines.append(f"Сума: {format_money(order.subtotal)}")
    else:
        lines.append("Сума: уточніть у клієнта")
    if order.comment:
        lines.extend(["", f"💬 {escape(order.comment)}"])
    lines.extend(["", "Оплата при отриманні."])
    return "\n".join(lines)


def booking_group_text(booking: Booking, user: User) -> str:
    lines = [
        f"📅 <b>Нове бронювання столика #{booking.id}</b>",
        "",
        f"👤 {escape(booking.name)}",
        f"📞 {escape(booking.phone)}",
        f"🗓 {escape(format_visit_date(booking.visit_date))} о {escape(booking.visit_time)}",
        f"👥 Гостей: {booking.guests}",
        _contact_line(user),
    ]
    if booking.comment:
        lines.extend(["", f"💬 {escape(booking.comment)}"])
    return "\n".join(lines)


def order_status_text(order: Order, status: str, settings: dict[str, str]) -> str:
    phone = (settings.get("phone") or "").strip()
    tail = f"\nТелефон закладу: {escape(phone)}" if phone else ""
    if status == Status.ACCEPTED:
        return f"✅ Замовлення <b>#{order.id}</b> прийнято. Очікуйте на дзвінок.{tail}"
    if status == Status.REJECTED:
        return f"❌ Замовлення <b>#{order.id}</b> відхилено. Можете оформити його ще раз або зателефонувати.{tail}"
    if status == Status.CANCELLED:
        return f"❌ Замовлення <b>#{order.id}</b> скасовано.{tail}"
    return f"Статус замовлення #{order.id} оновлено.{tail}"


def booking_status_text(booking: Booking, status: str, settings: dict[str, str], lang: str = "uk") -> str:
    from app.i18n import t

    phone = (settings.get("phone") or "").strip()
    tail = ("\n" + t(lang, "place_phone", phone=escape(phone))) if phone else ""
    when = f"{format_visit_date(booking.visit_date)} {t(lang, 'at')} {escape(booking.visit_time)}"
    if status == Status.ACCEPTED:
        return t(lang, "booking_accepted", id=booking.id, when=when, guests=booking.guests, tail=tail)
    if status == Status.REJECTED:
        return t(lang, "booking_rejected", id=booking.id, tail=tail)
    if status == Status.CANCELLED:
        return t(lang, "booking_cancelled_note", id=booking.id, tail=tail)
    return t(lang, "booking_updated", id=booking.id, tail=tail)


async def send_to_group(bot: Bot | None, settings: dict[str, str], text: str, markup) -> int | None:
    if bot is None:
        return None
    raw = (settings.get("group_chat_id") or "").strip()
    if not raw:
        logger.warning("Група персоналу не підключена")
        return None
    try:
        chat_id = int(raw)
    except ValueError:
        logger.error("group_chat_id не є числом")
        return None
    try:
        message = await bot.send_message(chat_id, text, reply_markup=markup)
        return message.message_id
    except Exception:
        logger.exception("Не вдалося надіслати заявку в групу %s", chat_id)
        return None


async def safe_send(bot: Bot, telegram_id: int, text: str) -> None:
    try:
        await bot.send_message(telegram_id, text)
    except Exception:
        logger.exception("Не вдалося написати клієнту %s", telegram_id)


async def edit_group_status(
    bot: Bot | None,
    settings: dict[str, str],
    message_id: int | None,
    original: str,
    status: str,
    fallback: str,
) -> None:
    if bot is None:
        return
    raw = (settings.get("group_chat_id") or "").strip()
    if not raw:
        return
    try:
        chat_id = int(raw)
    except ValueError:
        return
    line = STATUS_LINES.get(status, escape(status))
    text = f"{original}\n\n{line}" if original else fallback
    if message_id:
        try:
            await bot.edit_message_text(text, chat_id=chat_id, message_id=message_id, reply_markup=None)
            return
        except Exception:
            logger.exception("Не вдалося оновити повідомлення в групі")
    try:
        await bot.send_message(chat_id, fallback)
    except Exception:
        logger.exception("Не вдалося надіслати статус у групу")
