from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import Any
from collections import defaultdict

import lancedb

from .store import append_import_record, append_rules, load_rules, normalize_rule_row


DEFAULT_LEGACY_DB = Path(r"D:\google ads\lancedb")
DEFAULT_LEGACY_TABLE = "fakty"


@dataclass(frozen=True)
class LegacyImportResult:
    db_path: Path
    table_name: str
    imported_count: int
    skipped_existing_count: int
    total_rows: int


def import_legacy_lancedb(
    db_path: Path = DEFAULT_LEGACY_DB,
    table_name: str = DEFAULT_LEGACY_TABLE,
    limit: int | None = None,
) -> LegacyImportResult:
    if not db_path.exists():
        raise FileNotFoundError(f"Nie znaleziono starej bazy LanceDB: {db_path}")

    db = lancedb.connect(str(db_path))
    table_names = list(db.table_names()) if hasattr(db, "table_names") else list(db.list_tables())
    if table_name not in table_names:
        raise ValueError(f"Brak tabeli {table_name} w {db_path}. Dostepne tabele: {', '.join(table_names)}")

    table = db.open_table(table_name)
    df = table.to_pandas()
    if limit is not None:
        df = df.head(max(limit, 0))

    existing_ids = {rule.id for rule in load_rules()}
    rows: list[dict[str, Any]] = []
    skipped = 0
    source_file = str(db_path / f"{table_name}.lance")

    occurrences: dict[str, int] = defaultdict(int)
    for _, record in df.iterrows():
        record_dict = record.to_dict()
        old_id = str(record_dict.get("id") or "").strip()
        occurrences[old_id] += 1
        row = legacy_record_to_rule(record_dict, source_file, occurrences[old_id])
        normalized = normalize_rule_row(row)
        if normalized["id"] in existing_ids:
            skipped += 1
            continue
        existing_ids.add(normalized["id"])
        rows.append(normalized)

    saved = append_rules(rows)
    append_import_record(
        {
            "file": source_file,
            "source": f"legacy_lancedb:{table_name}",
            "model": "none",
            "rules_count": len(saved),
            "skipped_existing_count": skipped,
            "notes": "Import starej tabeli LanceDB bez API i bez przypisywania regul do zadan.",
        }
    )
    return LegacyImportResult(
        db_path=db_path,
        table_name=table_name,
        imported_count=len(saved),
        skipped_existing_count=skipped,
        total_rows=len(df),
    )


def legacy_record_to_rule(record: dict[str, Any], source_file: str, occurrence: int = 1) -> dict[str, Any]:
    old_id = str(record.get("id") or "").strip()
    fact = str(record.get("fakt") or "").strip()
    topic = str(record.get("temat") or "legacy").strip()
    section = str(record.get("sekcja") or "").strip()
    source = str(record.get("zrodlo") or "legacy_lancedb").strip()
    target_id = old_id or fact[:80] or "legacy_rule"
    if occurrence > 1:
        target_id = f"{target_id[:80]}__{occurrence}"
    return {
        "id": target_id,
        "status": "active",
        "topic": topic,
        "task_ids": [],
        "suggested_task_ids": [],
        "rule_type": "implementation_note",
        "condition": section,
        "recommendation": fact,
        "risk": "",
        "source": source,
        "source_file": source_file,
        "confidence": "medium",
        "duplicate_of": "",
        "supersedes": [],
        "text": fact,
    }
