"""Learning and feedback system for B2B detection."""

from __future__ import annotations

import os
from contextlib import contextmanager
from pathlib import Path
from typing import Dict, List

import duckdb


class B2BLearningSystem:
    """Track and learn from user corrections."""

    def __init__(self, db_path: str | os.PathLike[str] | None = None):
        self.db_path = Path(
            db_path or os.getenv("FM_LEARNING_DB", "learning.duckdb")
        ).resolve()
        self._init_tables()

    @contextmanager
    def _connect(self):
        conn = duckdb.connect(str(self.db_path))
        try:
            yield conn
        finally:
            try:
                conn.close()
            except Exception:
                pass

    def _init_tables(self):
        """Create learning tables if not exist."""
        with self._connect() as conn:
            conn.execute(
                """
                CREATE TABLE IF NOT EXISTS mapping_feedback (
                    account_id TEXT,
                    header TEXT,
                    mapped_field TEXT,
                    confidence DOUBLE,
                    accepted BOOLEAN,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
                """
            )

            conn.execute(
                """
                CREATE TABLE IF NOT EXISTS detection_performance (
                    account_id TEXT,
                    field_type TEXT,
                    detected_column TEXT,
                    actual_column TEXT,
                    confidence DOUBLE,
                    was_correct BOOLEAN,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
                """
            )

    def record_feedback(self, account_id: str, feedback: Dict):
        """Record user feedback on mapping."""
        payload = (
            account_id,
            feedback.get("header"),
            feedback.get("mapped_field"),
            feedback.get("confidence"),
            feedback.get("accepted"),
        )
        with self._connect() as conn:
            conn.execute(
                """
                INSERT INTO mapping_feedback
                (account_id, header, mapped_field, confidence, accepted)
                VALUES (?, ?, ?, ?, ?)
                """,
                payload,
            )

    def get_tenant_aliases(self, account_id: str) -> Dict[str, List[str]]:
        """Get custom aliases learned from tenant."""
        with self._connect() as conn:
            result = conn.execute(
                """
                SELECT mapped_field, header, COUNT(*) as uses
                FROM mapping_feedback
                WHERE account_id = ?
                    AND accepted = true
                    AND timestamp > CURRENT_TIMESTAMP - INTERVAL '90 days'
                GROUP BY mapped_field, header
                HAVING COUNT(*) >= 3
                """,
                (account_id,),
            ).fetchall()

        aliases: Dict[str, List[str]] = {}
        for field, header, _ in result:
            aliases.setdefault(field, []).append(header.lower())

        return aliases

    def get_global_aliases(self) -> Dict[str, List[str]]:
        """Get aliases learned across all tenants."""
        with self._connect() as conn:
            result = conn.execute(
                """
                SELECT mapped_field, header, COUNT(DISTINCT account_id) as tenants
                FROM mapping_feedback
                WHERE accepted = true
                    AND timestamp > CURRENT_TIMESTAMP - INTERVAL '30 days'
                GROUP BY mapped_field, header
                HAVING COUNT(DISTINCT account_id) >= 5
                """
            ).fetchall()

        aliases: Dict[str, List[str]] = {}
        for field, header, _ in result:
            aliases.setdefault(field, []).append(header.lower())

        return aliases
