import sqlite3
import os
import shutil

# 数据库放到 Windows 常见的 APPDATA 目录（避免写在项目目录）
APP_NAME = "CleanDesktopOrganizer"

_PROJECT_DB_PATH = os.path.join(
    os.path.dirname(os.path.dirname(__file__)), "data.db"
)

_BASE_DIR = os.environ.get("APPDATA") or os.environ.get("LOCALAPPDATA") or ""
DB_DIR = os.path.join(_BASE_DIR, APP_NAME) if _BASE_DIR else None
DB_PATH = os.path.join(DB_DIR, "data.db") if DB_DIR else _PROJECT_DB_PATH


def _ensure_db_dir():
    if DB_DIR:
        os.makedirs(DB_DIR, exist_ok=True)


def _migrate_old_db_if_needed():
    """
    首次升级：把旧版项目目录下的 data.db 自动拷贝到 APPDATA，
    避免你之前分组/设置丢失。
    """
    try:
        if os.path.isfile(_PROJECT_DB_PATH) and not os.path.isfile(DB_PATH):
            _ensure_db_dir()
            shutil.copy2(_PROJECT_DB_PATH, DB_PATH)
    except Exception:
        # 迁移失败不影响程序运行（会在新目录重新创建库）
        pass


def get_conn():
    _ensure_db_dir()
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def init_db():
    _migrate_old_db_if_needed()
    conn = get_conn()
    c = conn.cursor()
    c.execute("""
        CREATE TABLE IF NOT EXISTS groups (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            position INTEGER DEFAULT 0,
            folder_path TEXT DEFAULT ''
        )
    """)
    c.execute("""
        CREATE TABLE IF NOT EXISTS items (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            group_id INTEGER NOT NULL,
            name TEXT NOT NULL,
            path TEXT NOT NULL,
            icon_path TEXT,
            position INTEGER DEFAULT 0,
            FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE
        )
    """)
    c.execute("""
        CREATE TABLE IF NOT EXISTS settings (
            key TEXT PRIMARY KEY,
            value TEXT NOT NULL
        )
    """)
    # 迁移：旧库没有 folder_path 字段时自动添加
    try:
        c.execute("ALTER TABLE groups ADD COLUMN folder_path TEXT DEFAULT ''")
        conn.commit()
    except Exception:
        pass  # 字段已存在则忽略

    # 默认分组
    c.execute("SELECT COUNT(*) FROM groups")
    if c.fetchone()[0] == 0:
        c.execute("INSERT INTO groups (name, position) VALUES ('常用程序', 0)")
    conn.commit()
    conn.close()

    _migrate_item_shortcut_paths_to_targets()


def _migrate_item_shortcut_paths_to_targets():
    """将旧数据中仍保存为 .lnk 的路径改存为快捷方式目标（若可解析）。仅执行一次。"""
    conn = get_conn()
    row = conn.execute(
        "SELECT value FROM settings WHERE key='items_lnk_targets_migrated'"
    ).fetchone()
    conn.close()
    if row and row["value"] == "1":
        return

    from shortcut_target import path_for_storage

    conn = get_conn()
    rows = conn.execute("SELECT id, path FROM items").fetchall()
    for r in rows:
        iid, p = r["id"], (r["path"] or "")
        pl = p.lower()
        if not pl.endswith(".lnk"):
            continue
        try:
            if not os.path.isfile(p):
                continue
        except OSError:
            continue
        new_p = path_for_storage(p)
        if new_p != p:
            conn.execute("UPDATE items SET path=? WHERE id=?", (new_p, iid))
    conn.execute(
        "INSERT INTO settings (key, value) VALUES (?,?) "
        "ON CONFLICT(key) DO UPDATE SET value=excluded.value",
        ("items_lnk_targets_migrated", "1"),
    )
    conn.commit()
    conn.close()


# ── Settings ─────────────────────────────────────────────
def get_setting(key: str, default: str = "") -> str:
    conn = get_conn()
    row = conn.execute("SELECT value FROM settings WHERE key=?", (key,)).fetchone()
    conn.close()
    return row["value"] if row else default


def set_setting(key: str, value: str):
    conn = get_conn()
    conn.execute(
        "INSERT INTO settings (key, value) VALUES (?,?) "
        "ON CONFLICT(key) DO UPDATE SET value=excluded.value",
        (key, value)
    )
    conn.commit()
    conn.close()


# ── Groups ──────────────────────────────────────────────
def get_groups():
    conn = get_conn()
    rows = conn.execute("SELECT * FROM groups ORDER BY position").fetchall()
    conn.close()
    return [dict(r) for r in rows]


def add_group(name, folder_path=""):
    conn = get_conn()
    conn.execute("INSERT INTO groups (name, folder_path) VALUES (?,?)", (name, folder_path))
    conn.commit()
    gid = conn.execute("SELECT last_insert_rowid()").fetchone()[0]
    conn.close()
    return gid


def rename_group(gid, name):
    conn = get_conn()
    conn.execute("UPDATE groups SET name=? WHERE id=?", (name, gid))
    conn.commit()
    conn.close()


def delete_group(gid):
    conn = get_conn()
    conn.execute("DELETE FROM groups WHERE id=?", (gid,))
    conn.commit()
    conn.close()


def reorder_groups(id_list):
    conn = get_conn()
    for pos, gid in enumerate(id_list):
        conn.execute("UPDATE groups SET position=? WHERE id=?", (pos, gid))
    conn.commit()
    conn.close()


# ── Items ────────────────────────────────────────────────
def get_items(group_id):
    conn = get_conn()
    rows = conn.execute(
        "SELECT * FROM items WHERE group_id=? ORDER BY position", (group_id,)
    ).fetchall()
    conn.close()
    return [dict(r) for r in rows]


def add_item(group_id, name, path, icon_path=None):
    from shortcut_target import path_for_storage

    path = path_for_storage(path)
    conn = get_conn()
    conn.execute(
        "INSERT INTO items (group_id, name, path, icon_path) VALUES (?,?,?,?)",
        (group_id, name, path, icon_path),
    )
    conn.commit()
    iid = conn.execute("SELECT last_insert_rowid()").fetchone()[0]
    conn.close()
    return iid


def delete_item(item_id):
    conn = get_conn()
    conn.execute("DELETE FROM items WHERE id=?", (item_id,))
    conn.commit()
    conn.close()


def move_item(item_id, new_group_id, new_position):
    conn = get_conn()
    conn.execute(
        "UPDATE items SET group_id=?, position=? WHERE id=?",
        (new_group_id, new_position, item_id),
    )
    conn.commit()
    conn.close()


def reorder_items(group_id, id_list):
    conn = get_conn()
    for pos, iid in enumerate(id_list):
        conn.execute("UPDATE items SET position=? WHERE id=?", (pos, iid))
    conn.commit()
    conn.close()


def reset_groups_and_items(recreate_default_group: bool = True):
    """
    清空所有分组与程序（items）。
    - 为避免外键级联受 SQLite 外键开关影响，这里显式先删 items 再删 groups。
    - 可选地重新创建默认分组「常用程序」，保证界面至少有一个组可操作。
    """
    conn = get_conn()
    conn.execute("DELETE FROM items")
    conn.execute("DELETE FROM groups")
    if recreate_default_group:
        conn.execute("INSERT INTO groups (name, position) VALUES ('常用程序', 0)")
    conn.commit()
    conn.close()
