from __future__ import annotations

from typing import Optional

from analogai.foundation.modules.fact.basefact import BaseFact


def format_fact_summary(fact: BaseFact) -> str:
    text = str(getattr(fact, "text", "") or "").strip()
    source = _format_source_id(fact.source_id)
    if text and source:
        return f"source={source}: {text}"
    if text:
        return f"source={fact.user_id}: {text}"
    return f"source={source or fact.user_id}"


def format_fact_with_source(fact: BaseFact) -> str:
    text = get_fact_text(fact).strip()
    if not text:
        return ""
    source = _format_source_id(fact.source_id)
    if not source:
        return text
    return f"{text} (source: {source})"


def get_belief_id(belief) -> Optional[str]:
    if belief is None:
        return None
    value = belief.id
    return str(value) if value else None


def get_statement_id(belief) -> Optional[str]:
    if belief is None:
        return None
    if hasattr(belief, "statement_id"):
        value = belief.statement_id
        return str(value) if value else None
    if hasattr(belief, "statements"):
        statements = belief.statements
        if statements:
            first = statements[0]
            value = getattr(first, "id", None)
            return str(value) if value else None
    return None


def get_fact_text(fact) -> str:
    if fact is None:
        return ""
    return str(getattr(fact, "text", "") or "")


def _format_source_id(source_id: str | None) -> str:
    if not source_id:
        return ""
    value = str(source_id).strip()
    if not value:
        return ""
    return value


def collect_fact_window(
    fact,
    window: int,
    time_window_seconds: int | None = None,
) -> list:
    if fact is None:
        return []
    prevs: list = []
    current = fact
    for _ in range(max(0, int(window))):
        prev_chunk = current.prev()
        if prev_chunk is None:
            break
        prevs.append(prev_chunk)
        current = prev_chunk
    nexts: list = []
    current = fact
    for _ in range(max(0, int(window))):
        next_chunk = current.next()
        if next_chunk is None:
            break
        nexts.append(next_chunk)
        current = next_chunk
    prevs.reverse()
    combined = prevs + [fact] + nexts
    if time_window_seconds is None:
        return combined
    if time_window_seconds <= 0:
        return [fact]
    anchor_time = getattr(fact, "created_at", None)
    if anchor_time is None:
        return combined
    filtered = []
    for item in combined:
        item_time = getattr(item, "created_at", None)
        if item_time is None:
            continue
        delta = abs((item_time - anchor_time).total_seconds())
        if delta <= float(time_window_seconds):
            filtered.append(item)
    return filtered
