"""Database migration from v0.2 to v0.3."""

from __future__ import annotations

import hashlib
import logging
import sqlite3

logger = logging.getLogger(__name__)

V03_MIGRATIONS = [
    """
    CREATE TABLE IF NOT EXISTS users (
        username     TEXT PRIMARY KEY,
        role         TEXT NOT NULL DEFAULT 'reader',
        token_hash   TEXT UNIQUE NOT NULL,
        created_by   TEXT DEFAULT 'system',
        created_at   INTEGER NOT NULL,
        active       INTEGER DEFAULT 1
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS device_tokens (
        id           INTEGER PRIMARY KEY AUTOINCREMENT,
        device_name  TEXT NOT NULL,
        token_hash   TEXT UNIQUE NOT NULL,
        permissions  TEXT DEFAULT '[\"read\"]',
        created_at   INTEGER NOT NULL,
        active       INTEGER DEFAULT 1
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS sync_state (
        peer_id         TEXT PRIMARY KEY,
        last_sync_seq   INTEGER DEFAULT 0,
        last_sync_at    INTEGER DEFAULT 0,
        peer_public_key TEXT
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS sync_conflicts (
        id            INTEGER PRIMARY KEY AUTOINCREMENT,
        local_data    TEXT NOT NULL,
        remote_data   TEXT NOT NULL,
        conflict_type TEXT NOT NULL,
        created_at    INTEGER NOT NULL,
        resolved      INTEGER DEFAULT 0,
        resolution    TEXT DEFAULT ''
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS shared_spaces (
        id           BLOB PRIMARY KEY,
        name         TEXT UNIQUE NOT NULL,
        description  TEXT DEFAULT '',
        owner        TEXT NOT NULL,
        created_at   INTEGER NOT NULL
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS space_members (
        space_id     BLOB NOT NULL REFERENCES shared_spaces(id),
        username     TEXT NOT NULL REFERENCES users(username),
        role         TEXT NOT NULL DEFAULT 'reader',
        joined_at    INTEGER NOT NULL,
        PRIMARY KEY (space_id, username)
    )
    """,
    """
    CREATE TABLE IF NOT EXISTS audit_log (
        id           INTEGER PRIMARY KEY AUTOINCREMENT,
        timestamp    INTEGER NOT NULL,
        username     TEXT NOT NULL,
        action       TEXT NOT NULL,
        resource     TEXT NOT NULL,
        success      INTEGER DEFAULT 1,
        details      TEXT DEFAULT '{}'
    )
    """,
    "ALTER TABLE memories ADD COLUMN content_hash TEXT DEFAULT ''",
    "ALTER TABLE memories ADD COLUMN device_origin TEXT DEFAULT 'local'",
    "CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash)",
    "CREATE TABLE IF NOT EXISTS schema_info (key TEXT PRIMARY KEY, value TEXT)",
    "INSERT OR REPLACE INTO schema_info (key, value) VALUES ('version', '0.3.0')",
]


def _parse_version_tuple(raw: str) -> tuple[int, int, int]:
    parts = [p for p in str(raw).split(".") if p != ""]
    values: list[int] = []
    for part in parts[:3]:
        try:
            values.append(int(part))
        except ValueError:
            values.append(0)
    while len(values) < 3:
        values.append(0)
    return values[0], values[1], values[2]


def migrate_v02_to_v03(db_path: str) -> bool:
    """Run v0.2 to v0.3 migration and hash backfill."""
    conn = sqlite3.connect(db_path)

    try:
        try:
            row = conn.execute("SELECT value FROM schema_info WHERE key = 'version'").fetchone()
            current_version = row[0] if row else "0.2.0"
        except Exception:
            current_version = "0.2.0"
            conn.execute("CREATE TABLE IF NOT EXISTS schema_info (key TEXT PRIMARY KEY, value TEXT)")

        if _parse_version_tuple(current_version) >= _parse_version_tuple("0.3.0"):
            logger.info("Database already at v0.3.0+, skipping migration")
            return True

        logger.info("Migrating database from %s to 0.3.0...", current_version)
        for sql in V03_MIGRATIONS:
            try:
                conn.execute(sql.strip())
            except sqlite3.OperationalError as exc:
                if "duplicate column name" in str(exc) or "already exists" in str(exc):
                    continue
                logger.warning("Migration SQL warning: %s", exc)

        try:
            rows = conn.execute("SELECT id, content FROM memories WHERE content_hash = '' OR content_hash IS NULL").fetchall()
            for row in rows:
                content = str(row[1] or "")
                content_hash = hashlib.sha256(content.encode("utf-8")).hexdigest()[:16] if content else ""
                conn.execute("UPDATE memories SET content_hash = ? WHERE id = ?", (content_hash, row[0]))
        except Exception as exc:
            logger.warning("Content hash backfill warning: %s", exc)

        conn.commit()
        logger.info("Migration to v0.3.0 complete")
        return True

    except Exception as exc:
        logger.error("Migration failed: %s", exc)
        conn.rollback()
        return False
    finally:
        conn.close()
