#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Create Time    : 2025/04/03 10:30
# @File           : crud.py
# @IDE            : PyCharm
# @desc           : 数据访问层

from utils import status
from core.crud import DalBase
from . import schemas, models
from utils import os_utils as os
from utils.huawei_obs import MyObs
from utils.random_utils import random_str
from core.exception import CustomException
from application.settings import detect_url
from sqlalchemy.ext.asyncio import AsyncSession

from fastapi import UploadFile


class ProjectDetectDal(DalBase):

    def __init__(self, db: AsyncSession):
        super(ProjectDetectDal, self).__init__()
        self.db = db
        self.model = models.ProjectDetect
        self.schema = schemas.ProjectDetectOut

    async def check_name(self, name: str, project_id: int) -> bool:
        """
        校验推理集合名称
        """
        count = await self.get_count(
            v_where=[models.ProjectDetect.project_id == project_id, models.ProjectDetect.detect_name == name])
        return count > 0

    async def add_detect(self, data: schemas.ProjectDetectIn, user_id: int):
        """
        新增集合
        """
        detect = self.model(**data.model_dump())
        detect.detect_no = random_str(6)
        detect.detect_version = 0
        detect.detect_status = '0'
        detect.user_id = user_id
        if detect.file_type != 'rtsp':
            url = os.create_folder(detect_url, detect.detect_no, 'images')
            detect.folder_url = url
        await self.create_model(detect)
        return detect

    async def delete_detects(self, ids: list[int]):
        """
        删除集合数据+文件夹的文件夹+每次推理日志的文件
        """
        for id_ in ids:
            detect_info = await self.get_data(data_id=id_)
            if detect_info.file_type != 'rtsp':
                os.delete_paths([detect_info.folder_url])
                logs = await ProjectDetectLogDal(self.db).get_datas(v_where=[models.ProjectDetectLog.detect_id == id_])
                log_ids = []
                log_urls = []
                for log in logs:
                    log_urls.append(log.folder_url)
                    log_ids.append(log.id)
                if log_ids:
                    await ProjectDetectLogDal(self.db).delete_datas(ids=log_ids, v_soft=False)
                if log_urls:
                    os.delete_paths(log_urls)
        await self.delete_datas(ids=ids, v_soft=False)


class ProjectDetectFileDal(DalBase):

    def __init__(self, db: AsyncSession):
        super(ProjectDetectFileDal, self).__init__()
        self.db = db
        self.model = models.ProjectDetectFile
        self.schema = schemas.ProjectDetectFileOut

    async def file_count(self, detect_id: int) -> int:
        count = await self.get_count(v_where=[models.ProjectDetectFile.detect_id == detect_id])
        return count

    async def add_files(self, detect: models.ProjectDetect, files: list[UploadFile], user_id: int):
        images = []
        obs = MyObs()
        for file in files:
            image = models.ProjectDetectFile()
            image.detect_id = detect.id
            image.file_name = file.filename
            # 保存原图
            path = os.save_images(detect.folder_url, file=file)
            image.file_url = path
            image.user_id = user_id
            # 上传到obs
            object_key = detect.detect_no + '/' + file.filename
            success, key, url = obs.put_file(object_key=object_key, file_path=path)
            if success:
                image.object_key = object_key
                image.thumb_file_url = url
            else:
                raise CustomException("obs上传失败", code=status.HTTP_ERROR)
            images.append(image)
        await self.create_models(images)

    async def delete_files(self, ids: list[int]):
        file_urls = []
        object_keys = []
        for id_ in ids:
            file = await self.get_data(data_id=id_)
            if file:
                file_urls.append(file.file_url)
                object_keys.append(file.object_key)
        os.delete_paths(file_urls)
        MyObs().del_objects(object_keys)
        await self.delete_datas(ids, v_soft=False)


class ProjectDetectLogDal(DalBase):

    def __init__(self, db: AsyncSession):
        super(ProjectDetectLogDal, self).__init__()
        self.db = db
        self.model = models.ProjectDetectLog
        self.schema = schemas.ProjectDetectLogOut


class ProjectDetectLogFileDal(DalBase):

    def __init__(self, db: AsyncSession):
        super(ProjectDetectLogFileDal, self).__init__()
        self.db = db
        self.model = models.ProjectDetectLogFile
        self.schema = schemas.ProjectDetectLogFileOut
