import json
from datetime import datetime, timedelta
from queue import Queue
from threading import Event
from typing import TYPE_CHECKING, Optional

import yaml
from yamlcore import CoreDumper, CoreLoader

from mower.utils.config.conf import Conf
from mower.utils.config.plan import PlanModel
from mower.utils.config.work import SSSModel, WorkModel
from mower.utils.network import get_new_port
from mower.utils.path import get_path
from mower.utils.translate import pretranslate_sss, pretranslate_work

if TYPE_CHECKING:
    from mower.solvers.base_schedule import BaseSchedulerSolver
    from mower.utils.device.device import Device
    from mower.utils.recognize import Recognizer

# conf_path = get_path("@app/conf.json")
conf_path = get_path("@app/conf.yml")
plan_path = get_path("@app/plan.json")
sss_path = get_path("@app/sss.json")


timestamp: int = round(datetime.now().timestamp() * 1000)
"设置最后更改的时间戳"
ws_queue = Queue()


def save_conf(update_timestamp: bool = True):
    if update_timestamp:
        global timestamp
        timestamp = round(datetime.now().timestamp() * 1000)
    ws_queue.put({"type": "conf", "time": timestamp, "data": conf.model_dump()})
    with conf_path.open("w", encoding="utf8") as f:
        # json.dump(conf.model_dump(), f, ensure_ascii=False, indent=4)  # Use json.dump
        yaml.dump(
            conf.model_dump(),
            f,
            Dumper=CoreDumper,
            encoding="utf-8",
            default_flow_style=False,
            allow_unicode=True,
        )


def load_conf():
    global conf
    if not conf_path.is_file():
        conf_path.parent.mkdir(exist_ok=True)
        conf = Conf()
        save_conf()
        return
    with conf_path.open("r", encoding="utf-8") as f:
        # conf = Conf(**json.load(f))
        conf = Conf(**yaml.load(f, Loader=CoreLoader))


conf: Conf
load_conf()


def save_plan():
    with plan_path.open("w", encoding="utf-8") as f:
        json.dump(plan.model_dump(exclude_none=True), f, ensure_ascii=False, indent=2)


def load_plan():
    global plan
    if not plan_path.is_file():
        plan_path.parent.mkdir(exist_ok=True)
        plan = PlanModel()
        save_plan()
        return
    with plan_path.open("r", encoding="utf-8") as f:
        plan = PlanModel(**json.load(f))


plan: PlanModel
load_plan()


def load_works():
    global works
    for work in conf.work.works:
        works_path = get_path(f"@app/works/{work.stage}.json")
        if not works_path.is_file():
            raise FileNotFoundError(f"Work {work.stage} not found")
        with works_path.open("r", encoding="utf-8") as f:
            works[work.stage] = WorkModel(**pretranslate_work(json.load(f)))

    if not sss_path.is_file():
        return
    with sss_path.open("r", encoding="utf-8") as f:
        works["sss"] = SSSModel(**pretranslate_sss(json.load(f)))


works: dict[str, WorkModel | SSSModel] = {}


stop_mower = Event()
stop_maa = Event()

idle: bool = True

screenshot_time: datetime = datetime.now() - timedelta(
    milliseconds=conf.screenshot_interval
)
screenshot_avg: Optional[int] = None
screenshot_count: int = 0

adb_server_port: int = get_new_port()

device: Optional["Device"] = None
recog: Optional["Recognizer"] = None


def mount_device():
    from mower.utils.device.device import Device
    from mower.utils.recognize import Recognizer

    global device
    global recog
    device = device or Device()
    recog = recog or Recognizer()


check_screen = False
"分辨率和DPI是否正确"

tap_info = None, None

# 常量
APP_ACTIVITY_NAME = "com.u8.sdk.U8UnityContext"
MAX_RETRYTIME = 5
MNT_COMPATIBILITY_MODE = False
MNT_PORT = 20937

tasks = []
"基建任务"
task_count = 0
"第几次任务结束"
global_plan = {}
party_time: Optional[datetime] = None
"线索交流结束时间"
base_scheduler: Optional["BaseSchedulerSolver"] = None

ws_connections = []
log_lines: list[str] = []
