"""
Style Adapter для Степана.

adapt_response_style(response, user_profile) → str

Не змінює зміст відповіді, лише форму:
  concise    → скорочує, прибирає пояснення
  checklist  → переформатовує у маркери
  analytical → додає блок "Причина / Наслідок"
  detailed   → дозволяє довшу форму (без змін)
  conversational → за замовчуванням, без змін

Стиль визначається:
  1. Явні слова користувача ("коротко", "списком", ...)
  2. Поле user_profile["style"]

Fail-safe: будь-який виняток → повертає оригінальну відповідь.
"""

from __future__ import annotations

import logging
import re

logger = logging.getLogger(__name__)


# ─── Sentence splitter ───────────────────────────────────────────────────────

_SENT_SPLIT_RE = re.compile(r'(?<=[.!?])\s+')


def _split_sentences(text: str) -> list[str]:
    return [s.strip() for s in _SENT_SPLIT_RE.split(text.strip()) if s.strip()]


# ─── Style transformers ──────────────────────────────────────────────────────

def _to_concise(text: str) -> str:
    """Скоротити до 2–3 речень, прибрати надлишкові вступні фрази."""
    # Remove common filler openings
    filler_re = re.compile(
        r'^(звісно[,!]?\s*|звичайно[,!]?\s*|добре[,!]?\s*|зрозуміло[,!]?\s*'
        r'|окей[,!]?\s*|ок[,!]?\s*|чудово[,!]?\s*|ось[,!]?\s*|так[,!]?\s*)',
        re.IGNORECASE | re.UNICODE,
    )
    text = filler_re.sub('', text).strip()

    sentences = _split_sentences(text)
    if len(sentences) <= 3:
        return text
    # Keep first 3 meaningful sentences
    short = ' '.join(sentences[:3])
    if len(sentences) > 3:
        short += ' …'
    return short


def _to_checklist(text: str) -> str:
    """
    Переформатовує відповідь у маркований список.
    Якщо вже є маркери — повертає без змін.
    """
    if re.search(r'^\s*[-•*]\s', text, re.MULTILINE):
        return text  # already formatted

    sentences = _split_sentences(text)
    if len(sentences) < 2:
        return text  # too short to convert

    items = '\n'.join(f'• {s}' for s in sentences)
    return items


def _to_analytical(text: str) -> str:
    """
    Додає короткий блок «Чому це важливо:» якщо відповідь досить довга.
    Не дублює зміст — тільки додає структуру.
    """
    sentences = _split_sentences(text)
    if len(sentences) < 3:
        return text

    # First 2 sentences — основа; решта — обґрунтування
    main = ' '.join(sentences[:2])
    reason = ' '.join(sentences[2:4])
    result = main
    if reason:
        result += f'\n\n*Чому це важливо:* {reason}'
    return result


# ─── Style detection from text ───────────────────────────────────────────────

_STYLE_SIGNAL: dict[str, list[str]] = {
    "concise":    ["коротко", "без деталей", "стисло", "коротку відповідь", "кратко"],
    "checklist":  ["списком", "маркерами", "у списку", "по пунктах", "пунктами"],
    "analytical": ["аналіз", "причини", "наслідки", "детальний аналіз", "розбери"],
    "detailed":   ["детально", "докладно", "розгорнуто", "повністю", "докладну"],
}


def detect_style_from_text(text: str) -> str | None:
    """Визначити бажаний стиль з тексту повідомлення."""
    tl = text.lower()
    for style, signals in _STYLE_SIGNAL.items():
        if any(s in tl for s in signals):
            return style
    return None


# ─── Main adapter ────────────────────────────────────────────────────────────

def adapt_response_style(response: str, user_profile: dict | None) -> str:
    """
    Адаптувати відповідь під стиль користувача.

    Якщо user_profile відсутній або style не визначено — повертає оригінал.
    Fail-safe: будь-який виняток → повертає оригінал.
    """
    try:
        if not response or not user_profile:
            return response

        style = user_profile.get("style") or "conversational"

        if style == "concise":
            adapted = _to_concise(response)
        elif style == "checklist":
            adapted = _to_checklist(response)
        elif style == "analytical":
            adapted = _to_analytical(response)
        else:
            # "detailed" and "conversational" — no transformation
            adapted = response

        if adapted != response:
            logger.debug("style_adapter: style=%s original_len=%d adapted_len=%d", style, len(response), len(adapted))

        return adapted

    except Exception as exc:
        logger.warning("style_adapter: failed (returning original): %s", exc)
        return response


def build_style_prefix(user_profile: dict | None) -> str:
    """
    Сформувати prefix для system prompt Степана з урахуванням профілю.
    Використовується у _stepan_light_response і фінальній задачі Deep mode.
    """
    if not user_profile:
        return ""

    parts: list[str] = []

    name = user_profile.get("name")
    if name:
        parts.append(f"Користувача звати {name}.")

    role = user_profile.get("role", "unknown")
    role_labels = {
        "owner":      "власник/керівник господарства",
        "agronomist": "агроном",
        "operator":   "оператор",
        "mechanic":   "механік",
    }
    if role in role_labels:
        parts.append(f"Його роль: {role_labels[role]}.")

    style = user_profile.get("style", "conversational")
    style_instructions = {
        "concise":       "Відповідай стисло, 1–2 речення, без зайвих вступів.",
        "checklist":     "Якщо доречно — структуруй відповідь у маркований список.",
        "analytical":    "Якщо доречно — виділи причину і наслідок.",
        "detailed":      "Можеш відповідати розгорнуто.",
        "conversational": "Говори природно, живою мовою.",
    }
    if style in style_instructions:
        parts.append(style_instructions[style])

    summary = user_profile.get("interaction_summary")
    if summary:
        parts.append(f"Контекст про користувача: {summary}")

    return " ".join(parts)
