import json
import logging
from database import get_db

logger = logging.getLogger("builder.database")


async def insert_built_melody(melody_id: str, name: str, pid: str, steps: str, is_builtin: bool = False) -> None:
    db = await get_db()
    await db.execute(
        """INSERT INTO built_melodies (id, name, pid, steps, assigned_melody_ids, is_builtin)
           VALUES (?, ?, ?, ?, ?, ?)""",
        (melody_id, name, pid, steps, json.dumps([]), 1 if is_builtin else 0),
    )
    await db.commit()


async def update_built_melody(melody_id: str, name: str, pid: str, steps: str, is_builtin: bool = False) -> None:
    db = await get_db()
    await db.execute(
        """UPDATE built_melodies
           SET name = ?, pid = ?, steps = ?, is_builtin = ?, updated_at = datetime('now')
           WHERE id = ?""",
        (name, pid, steps, 1 if is_builtin else 0, melody_id),
    )
    await db.commit()


async def update_builtin_flag(melody_id: str, is_builtin: bool) -> None:
    db = await get_db()
    await db.execute(
        """UPDATE built_melodies
           SET is_builtin = ?, updated_at = datetime('now')
           WHERE id = ?""",
        (1 if is_builtin else 0, melody_id),
    )
    await db.commit()


async def update_binary_path(melody_id: str, binary_path: str) -> None:
    db = await get_db()
    await db.execute(
        """UPDATE built_melodies
           SET binary_path = ?, updated_at = datetime('now')
           WHERE id = ?""",
        (binary_path, melody_id),
    )
    await db.commit()


async def update_progmem_code(melody_id: str, progmem_code: str) -> None:
    db = await get_db()
    await db.execute(
        """UPDATE built_melodies
           SET progmem_code = ?, updated_at = datetime('now')
           WHERE id = ?""",
        (progmem_code, melody_id),
    )
    await db.commit()


async def update_assigned_melody_ids(melody_id: str, assigned_ids: list) -> None:
    db = await get_db()
    await db.execute(
        """UPDATE built_melodies
           SET assigned_melody_ids = ?, updated_at = datetime('now')
           WHERE id = ?""",
        (json.dumps(assigned_ids), melody_id),
    )
    await db.commit()


async def get_built_melody(melody_id: str) -> dict | None:
    db = await get_db()
    rows = await db.execute_fetchall(
        "SELECT * FROM built_melodies WHERE id = ?", (melody_id,)
    )
    if not rows:
        return None
    row = dict(rows[0])
    row["assigned_melody_ids"] = json.loads(row["assigned_melody_ids"] or "[]")
    row["is_builtin"] = bool(row.get("is_builtin", 0))
    return row


async def list_built_melodies() -> list[dict]:
    db = await get_db()
    rows = await db.execute_fetchall(
        "SELECT * FROM built_melodies ORDER BY updated_at DESC"
    )
    results = []
    for row in rows:
        r = dict(row)
        r["assigned_melody_ids"] = json.loads(r["assigned_melody_ids"] or "[]")
        r["is_builtin"] = bool(r.get("is_builtin", 0))
        results.append(r)
    return results


async def delete_built_melody(melody_id: str) -> None:
    db = await get_db()
    await db.execute("DELETE FROM built_melodies WHERE id = ?", (melody_id,))
    await db.commit()
