from __future__ import annotations

from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
import re

from shared.assistant_profiles import compose_assistant_prompt, get_assistant_profile

GENERIC_OPERATIONAL_CONTEXTS = {
    "",
    "Inserisci qui procedure interne, policy operative, dati sensibili e contesto aziendale da esporre all'assistente.",
    "Il backend-hub centralizzera' progressivamente dati sensibili, policy operative e contesto aziendale.",
}

DEFAULT_MENU_BASE_PROMPT = get_assistant_profile("menu").base_prompt


@dataclass(frozen=True)
class VenuePromptData:
    venue_name: str
    concept: str
    service_moments: list[str]
    response_style: str
    menu_full_text: str
    wine_list_full_text: str


def _extract_required(pattern: str, source: str, *, flags: int = 0) -> str:
    match = re.search(pattern, source, flags)
    if not match:
        raise ValueError(f"Pattern non trovato: {pattern}")
    return match.group(1).strip()


@lru_cache
def load_menu2_prompt_data(path: str) -> VenuePromptData | None:
    source_path = Path(path)
    if not source_path.exists():
        return None

    source = source_path.read_text(encoding="utf-8")

    try:
        venue_name = _extract_required(r'venueName:\s*"([^"]+)"', source)
        concept = _extract_required(r'concept:\s*"([^"]+)"', source, flags=re.S)
        service_moments_block = _extract_required(r"serviceMoments:\s*\[(.*?)\]\s*,\s*responseStyle:", source, flags=re.S)
        service_moments = re.findall(r'"([^"]+)"', service_moments_block)
        response_style = _extract_required(r'responseStyle:\s*"([^"]+)"', source, flags=re.S)
        menu_full_text = _extract_required(r"export const MENU_FULL_TEXT = `([\s\S]*?)`\.trim\(\);", source, flags=re.S)
        wine_list_full_text = _extract_required(
            r"export const WINE_LIST_FULL_TEXT = `([\s\S]*?)`\.trim\(\);",
            source,
            flags=re.S,
        )
    except ValueError:
        return None

    return VenuePromptData(
        venue_name=venue_name,
        concept=concept,
        service_moments=service_moments,
        response_style=response_style,
        menu_full_text=menu_full_text,
        wine_list_full_text=wine_list_full_text,
    )


def build_menu2_system_prompt(path: str) -> str | None:
    prompt_data = load_menu2_prompt_data(path)
    if prompt_data is None:
        return None

    sections = [
        f"Nome locale: {prompt_data.venue_name}",
        f"Concept: {prompt_data.concept}",
        f"Momenti di servizio: {'; '.join(prompt_data.service_moments)}",
        f"Stile di risposta: {prompt_data.response_style}",
        "REGOLE IMPORTANTI:",
        "- Se il cliente chiede consigli di vino, usa solo etichette realmente presenti nella carta.",
        "- Se il cliente chiede un abbinamento, proponi solo piatti e vini presenti nei dati ufficiali.",
        "- Se un vino o un piatto sembra molto raro, costoso o di disponibilita' incerta, puoi segnalarlo.",
        "- Tieni presente che la carta vini e' aggiornata mensilmente e alcune selezioni potrebbero non essere disponibili.",
        "- Per allergie o intolleranze rimanda sempre al personale di sala e non dare rassicurazioni mediche.",
        "TRASCRIZIONE MENU UFFICIALE:",
        prompt_data.menu_full_text,
        "TRASCRIZIONE CARTA VINI UFFICIALE:",
        prompt_data.wine_list_full_text,
    ]

    return (
        f"Sei l'assistente digitale Menu 2.0 per {prompt_data.venue_name}. "
        "Devi conoscere perfettamente le proposte del locale e guidare il cliente verso la scelta migliore "
        f"basandoti esclusivamente sui dati seguenti.\n{'\n'.join(sections)}"
    )


def build_menu_assistant_description(venue_name: str) -> str:
    return (
        f"Chiedi un consiglio su piatti, cocktail o abbinamenti di {venue_name}. "
        "L'assistente usa solo i contenuti configurati dal locale."
    )


def build_menu_prompt_preview(
    *,
    venue_name: str,
    sales_focus: str = "",
    menu_text: str = "",
    cocktail_list_text: str = "",
    uploaded_assets_context: str = "",
) -> str:
    cleaned_sales_focus = sales_focus.strip()
    cleaned_uploaded_assets_context = uploaded_assets_context.strip()
    extra_sections: list[tuple[str, str]] = []
    if cleaned_sales_focus:
        extra_sections.append(("Obiettivo vendita prioritario", cleaned_sales_focus))
    if cleaned_uploaded_assets_context:
        extra_sections.append(("Materiale del locale elaborato dai file caricati", cleaned_uploaded_assets_context))
    else:
        extra_sections.append(("Dati non ancora configurati", "Il menu del locale non e ancora stato caricato tramite file. Non inventare contenuti."))

    return compose_assistant_prompt(
        "menu",
        venue_name=venue_name,
        extra_sections=tuple(extra_sections),
    )
