#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据库模块（稳定 API 门面）- SQLite

P2 / O-07：拆分 `database.py` 为稳定门面 + `db/` 分域实现。

约束：
- 外部仍通过 `import database` 调用（函数名/参数/返回结构保持不变）
- schema/migration 入口统一，避免 scattered ALTER TABLE
"""

from __future__ import annotations

import os
import threading
import time
from typing import Optional

import db_pool
from app_config import get_config

from db.schema import ensure_schema
from db.migrations import migrate_database as _migrate_database
from db.admin import (
    admin_reset_user_password,
    clean_old_operation_logs,
    ensure_default_admin,
    get_hourly_registration_count,
    get_system_config_raw as _get_system_config_raw,
    get_system_stats,
    update_admin_password,
    update_admin_username,
    update_system_config as _update_system_config,
    verify_admin,
)
from db.accounts import (
    create_account,
    delete_account,
    delete_user_accounts,
    get_account,
    get_account_status,
    get_account_status_batch,
    get_user_accounts,
    increment_account_login_fail,
    reset_account_login_status,
    update_account_remark,
)
from db.announcements import (
    create_announcement,
    delete_announcement,
    dismiss_announcement_for_user,
    get_active_announcement_for_user,
    get_announcement_by_id,
    get_announcements,
    set_announcement_active,
)
from db.email import (
    get_user_by_email,
    get_user_email_notify,
    update_user_email,
    update_user_email_notify,
)
from db.feedbacks import (
    close_feedback,
    create_bug_feedback,
    delete_feedback,
    get_bug_feedbacks,
    get_feedback_by_id,
    get_feedback_stats,
    get_user_feedbacks,
    reply_feedback,
)
from db.schedules import (
    clean_old_schedule_logs,
    create_schedule_execution_log,
    create_user_schedule,
    delete_schedule_logs,
    delete_user_schedule,
    get_due_user_schedules,
    get_enabled_user_schedules,
    get_schedule_by_id,
    get_schedule_execution_logs,
    get_user_all_schedule_logs,
    get_user_schedules,
    recompute_schedule_next_run,
    toggle_user_schedule,
    update_schedule_next_run,
    update_schedule_execution_log,
    update_schedule_last_run,
    update_user_schedule,
)
from db.tasks import create_task_log, delete_old_task_logs, get_task_logs, get_task_stats, get_user_run_stats
from db.users import (
    approve_user,
    create_user,
    delete_user,
    extend_user_vip,
    get_all_users,
    get_pending_users,
    get_user_by_id,
    get_user_by_username,
    get_user_kdocs_settings,
    get_user_stats,
    get_user_vip_info,
    get_vip_config,
    is_user_vip,
    reject_user,
    remove_user_vip,
    set_default_vip_days,
    set_user_vip,
    update_user_kdocs_settings,
    verify_user,
)
from db.security import record_login_context

config = get_config()

# 数据库文件路径
DB_FILE = config.DB_FILE

# 数据库版本 (用于迁移管理)
DB_VERSION = 17


# ==================== 系统配置缓存（P1 / O-03） ====================

_system_config_cache_lock = threading.Lock()
_system_config_cache_value: Optional[dict] = None
_system_config_cache_loaded_at = 0.0
try:
    _SYSTEM_CONFIG_CACHE_TTL_SECONDS = float(os.environ.get("SYSTEM_CONFIG_CACHE_TTL_SECONDS", "3"))
except Exception:
    _SYSTEM_CONFIG_CACHE_TTL_SECONDS = 3.0
_SYSTEM_CONFIG_CACHE_TTL_SECONDS = max(0.0, _SYSTEM_CONFIG_CACHE_TTL_SECONDS)


def invalidate_system_config_cache() -> None:
    global _system_config_cache_value, _system_config_cache_loaded_at
    with _system_config_cache_lock:
        _system_config_cache_value = None
        _system_config_cache_loaded_at = 0.0


def init_database():
    """初始化数据库表结构 + 迁移（入口统一）。"""
    db_pool.init_pool(DB_FILE, pool_size=config.DB_POOL_SIZE)

    with db_pool.get_db() as conn:
        ensure_schema(conn)
        _migrate_database(conn, DB_VERSION)

    ensure_default_admin()


def migrate_database():
    """数据库迁移（对外保留接口）。"""
    with db_pool.get_db() as conn:
        ensure_schema(conn)
        _migrate_database(conn, DB_VERSION)


# ==================== 系统配置管理（缓存门面） ====================


def get_system_config():
    """获取系统配置（带进程内缓存）。"""
    global _system_config_cache_value, _system_config_cache_loaded_at

    now_ts = time.time()
    with _system_config_cache_lock:
        if _system_config_cache_value is not None:
            if _SYSTEM_CONFIG_CACHE_TTL_SECONDS <= 0 or (now_ts - _system_config_cache_loaded_at) < _SYSTEM_CONFIG_CACHE_TTL_SECONDS:
                return dict(_system_config_cache_value)

    value = _get_system_config_raw()

    with _system_config_cache_lock:
        _system_config_cache_value = dict(value)
        _system_config_cache_loaded_at = now_ts
    return dict(value)


def update_system_config(
    max_concurrent=None,
    schedule_enabled=None,
    schedule_time=None,
    schedule_browse_type=None,
    schedule_weekdays=None,
    max_concurrent_per_account=None,
    max_screenshot_concurrent=None,
    enable_screenshot=None,
    proxy_enabled=None,
    proxy_api_url=None,
    proxy_expire_minutes=None,
    auto_approve_enabled=None,
    auto_approve_hourly_limit=None,
    auto_approve_vip_days=None,
    kdocs_enabled=None,
    kdocs_doc_url=None,
    kdocs_default_unit=None,
    kdocs_sheet_name=None,
    kdocs_sheet_index=None,
    kdocs_unit_column=None,
    kdocs_image_column=None,
    kdocs_admin_notify_enabled=None,
    kdocs_admin_notify_email=None,
):
    """更新系统配置（写入后立即失效缓存）。"""
    ok = _update_system_config(
        max_concurrent=max_concurrent,
        schedule_enabled=schedule_enabled,
        schedule_time=schedule_time,
        schedule_browse_type=schedule_browse_type,
        schedule_weekdays=schedule_weekdays,
        max_concurrent_per_account=max_concurrent_per_account,
        max_screenshot_concurrent=max_screenshot_concurrent,
        enable_screenshot=enable_screenshot,
        proxy_enabled=proxy_enabled,
        proxy_api_url=proxy_api_url,
        proxy_expire_minutes=proxy_expire_minutes,
        auto_approve_enabled=auto_approve_enabled,
        auto_approve_hourly_limit=auto_approve_hourly_limit,
        auto_approve_vip_days=auto_approve_vip_days,
        kdocs_enabled=kdocs_enabled,
        kdocs_doc_url=kdocs_doc_url,
        kdocs_default_unit=kdocs_default_unit,
        kdocs_sheet_name=kdocs_sheet_name,
        kdocs_sheet_index=kdocs_sheet_index,
        kdocs_unit_column=kdocs_unit_column,
        kdocs_image_column=kdocs_image_column,
        kdocs_admin_notify_enabled=kdocs_admin_notify_enabled,
        kdocs_admin_notify_email=kdocs_admin_notify_email,
    )
    if ok:
        invalidate_system_config_cache()
    return ok
