"""
存储路径配置 API

允许用户配置文书生成、电子取证、系统备份的保存路径。
路径存储在 runtime.db 的 system_configs 表中。
"""
import os
import logging
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from typing import Optional

from ...core.database import get_db, get_runtime_db, _has_split_databases
from ...core.permission import require_login
from ...core import paths

logger = logging.getLogger(__name__)
router = APIRouter()

# 默认路径（相对于数据目录）
DEFAULT_DOCUMENT_PATH = "uploads"
DEFAULT_EXPORT_PATH = "exports"
DEFAULT_BACKUP_PATH = "data/backups"

# 配置键名
KEY_DOCUMENT_PATH = "document_save_path"
KEY_EXPORT_PATH = "export_save_path"
KEY_BACKUP_PATH = "backup_save_path"


async def _get_config_value(key: str, default: str) -> str:
    """从 runtime.db 读取配置值"""
    try:
        if _has_split_databases():
            async for conn, cur in get_runtime_db():
                await cur.execute(
                    "SELECT config_value FROM system_configs WHERE config_key = ?", (key,)
                )
                row = await cur.fetchone()
                if row:
                    val = row["config_value"] if isinstance(row, dict) else row[0]
                    if val and val.strip():
                        return val.strip()
                break
        else:
            async for conn, cur in get_db():
                await cur.execute(
                    "SELECT config_value FROM system_configs WHERE config_key = ?", (key,)
                )
                row = await cur.fetchone()
                if row:
                    val = row["config_value"] if isinstance(row, dict) else row[0]
                    if val and val.strip():
                        return val.strip()
                break
    except Exception as e:
        logger.warning(f"读取配置 {key} 失败: {e}")
    return default


async def _set_config_value(key: str, value: str):
    """写入配置到 runtime.db"""
    try:
        if _has_split_databases():
            async for conn, cur in get_runtime_db():
                await cur.execute(
                    "INSERT OR REPLACE INTO system_configs (config_key, config_value) VALUES (?, ?)",
                    (key, value),
                )
                await conn.commit()
                break
        else:
            async for conn, cur in get_db():
                await cur.execute(
                    "INSERT OR REPLACE INTO system_configs (config_key, config_value) VALUES (?, ?)",
                    (key, value),
                )
                await conn.commit()
                break
    except Exception as e:
        logger.error(f"写入配置 {key} 失败: {e}")
        raise HTTPException(status_code=500, detail=f"保存配置失败: {e}")


def _resolve_absolute(rel_path: str) -> str:
    """将相对路径解析为绝对路径（相对于数据目录）"""
    if os.path.isabs(rel_path):
        return rel_path
    return os.path.normpath(os.path.join(paths.get_data_dir(), rel_path))


class PathConfigResponse(BaseModel):
    document_path: str
    document_path_abs: str
    export_path: str
    export_path_abs: str
    backup_path: str
    backup_path_abs: str
    data_dir: str


class PathUpdateRequest(BaseModel):
    document_path: Optional[str] = None
    export_path: Optional[str] = None
    backup_path: Optional[str] = None


@router.get("/config/paths")
async def get_paths(user: dict = Depends(require_login)):
    """获取当前存储路径配置"""
    doc_path = await _get_config_value(KEY_DOCUMENT_PATH, DEFAULT_DOCUMENT_PATH)
    exp_path = await _get_config_value(KEY_EXPORT_PATH, DEFAULT_EXPORT_PATH)
    bak_path = await _get_config_value(KEY_BACKUP_PATH, DEFAULT_BACKUP_PATH)

    data = {
        "document_path": doc_path,
        "document_path_abs": _resolve_absolute(doc_path),
        "export_path": exp_path,
        "export_path_abs": _resolve_absolute(exp_path),
        "backup_path": bak_path,
        "backup_path_abs": _resolve_absolute(bak_path),
        "data_dir": paths.get_data_dir(),
    }
    return {"success": True, "data": data}


@router.put("/config/paths")
async def update_paths(
    body: PathUpdateRequest,
    user: dict = Depends(require_login),
):
    """更新存储路径配置"""
    results = {}

    if body.document_path is not None:
        path = body.document_path.strip()
        if path:
            abs_path = _resolve_absolute(path)
            # 验证路径可写性
            try:
                os.makedirs(abs_path, exist_ok=True)
                test_file = os.path.join(abs_path, ".write_test")
                with open(test_file, "w") as f:
                    f.write("test")
                os.remove(test_file)
            except Exception as e:
                raise HTTPException(
                    status_code=400,
                    detail=f"文书保存路径不可写: {abs_path} ({e})"
                )
            await _set_config_value(KEY_DOCUMENT_PATH, path)
            results["document_path"] = path

    if body.export_path is not None:
        path = body.export_path.strip()
        if path:
            abs_path = _resolve_absolute(path)
            try:
                os.makedirs(abs_path, exist_ok=True)
                test_file = os.path.join(abs_path, ".write_test")
                with open(test_file, "w") as f:
                    f.write("test")
                os.remove(test_file)
            except Exception as e:
                raise HTTPException(
                    status_code=400,
                    detail=f"取证导出路径不可写: {abs_path} ({e})"
                )
            await _set_config_value(KEY_EXPORT_PATH, path)
            results["export_path"] = path

    if body.backup_path is not None:
        path = body.backup_path.strip()
        if path:
            abs_path = _resolve_absolute(path)
            try:
                os.makedirs(abs_path, exist_ok=True)
                test_file = os.path.join(abs_path, ".write_test")
                with open(test_file, "w") as f:
                    f.write("test")
                os.remove(test_file)
            except Exception as e:
                raise HTTPException(
                    status_code=400,
                    detail=f"备份保存路径不可写: {abs_path} ({e})"
                )
            await _set_config_value(KEY_BACKUP_PATH, path)
            results["backup_path"] = path

    return {"success": True, "data": results}


# ===== 工具函数：供其他模块调用 =====

async def get_document_save_path() -> str:
    """获取文书保存绝对路径"""
    rel = await _get_config_value(KEY_DOCUMENT_PATH, DEFAULT_DOCUMENT_PATH)
    abs_path = _resolve_absolute(rel)
    os.makedirs(abs_path, exist_ok=True)
    return abs_path


async def get_export_save_path() -> str:
    """获取取证导出绝对路径"""
    rel = await _get_config_value(KEY_EXPORT_PATH, DEFAULT_EXPORT_PATH)
    abs_path = _resolve_absolute(rel)
    os.makedirs(abs_path, exist_ok=True)
    return abs_path


async def get_backup_save_path() -> str:
    """获取备份保存绝对路径"""
    rel = await _get_config_value(KEY_BACKUP_PATH, DEFAULT_BACKUP_PATH)
    abs_path = _resolve_absolute(rel)
    os.makedirs(abs_path, exist_ok=True)
    return abs_path
