from logger import logger
from databases import DeviceConfig, PhotoRecord, SqlQuery
from sqlalchemy.orm import sessionmaker, scoped_session
import settings
from .online_request.module_online_data import OnlineDataRequest, GetOnlineDataHLM

import time
from datetime import datetime, timedelta
from sqlalchemy.sql import func
from sqlalchemy.orm import aliased
import copy
import threading


class DataBaseModel():
    # 基础数据基类
    # signal_data = Signal(dict)
    # add_data_to_online_sign = Signal(dict)

    def __init__(self, token):
        # super().__init__(parent=None)
        self.logger = logger
        self.token = token
        # 创建一个实例化的会话对象 session;该会话会自己处理上下文，线程结束时会自动关闭会话；适合多线程处理
        self.session = SqlQuery()

        if settings.PROJECT == "红蜻蜓":
            self.get_online_data = OnlineDataRequest(self.token)
        elif settings.PROJECT == "惠利玛":
            self.get_online_data = GetOnlineDataHLM(self.token)

        # self.add_data_to_online_sign.connect(self.send_record_to_online)

    # 新增数据的记录发送到云端
    def send_record_to_online(self, data):
        # _data = {"goods_art_no":goods_art_no,
        #          "image_index": image_index,
        #          "photo_create_time": photo_create_time,
        #          "image_deal_mode": image_deal_mode,
        #          "take_photo_created_at": date_time.strftime('%Y-%m-%d %H:%M:%S'),
        #          }
        data["photo_create_time"] = "{}".format(data["photo_create_time"])
        data["take_photo_created_at"] = "{}".format(data["take_photo_created_at"])
        self.get_online_data.add_auto_photo_logs(data)
        pass

    def send_info(self, _type="", mode="", data=None):
        self.signal_data.emit({"_type": _type, "plugins_mode": mode, "data": data})

    def send_log(self, text, is_debug=False):
        if is_debug:
            self.logger.debug(text)
        else:
            self.logger.info(text)

    def insert_data_to_phone_record(self, data: dict):
        # 异步提交数据到后台
        photo_create_time = data["photo_create_time"]
        try:
            photo_create_time = time.strptime(photo_create_time, "%Y-%m-%d %H:%M:%S")
        except:
            photo_create_time = time.strptime(photo_create_time, "%Y:%m:%d %H:%M:%S")

        photo_create_time = time.mktime(photo_create_time)
        photo_create_time = datetime.fromtimestamp(photo_create_time)

        image_deal_mode = data["image_deal_mode"] if "image_deal_mode" in data else 0
        image_index = data["image_index"] if "image_index" in data else 0
        goods_art_no = data["goods_art_no"]
        d_1 = PhotoRecord(
            goods_art_no=goods_art_no,
            image_index=image_index,
            photo_create_time=photo_create_time,
            image_deal_mode=image_deal_mode,
        )

        self.session.add(d_1)
        self.session.commit()
        date_time = datetime.fromtimestamp(time.time())
        _data = {"goods_art_no": goods_art_no,
                 "image_index": image_index,
                 "photo_create_time": photo_create_time,
                 "image_deal_mode": image_deal_mode,
                 "take_photo_created_at": date_time.strftime('%Y-%m-%d %H:%M:%S'),
                 }
        # self.add_data_to_online_sign.emit(_data)

    def get_goods_art_no(self, date_time_original):
        time_array = time.strptime(date_time_original, "%Y:%m:%d %H:%M:%S")
        time_array = time.mktime(time_array)
        datetime_obj = datetime.fromtimestamp(time_array)
        result = (
            self.session.query(PhotoRecord)
            .filter(PhotoRecord.photo_create_time == datetime_obj)
            .order_by(PhotoRecord.id.desc())
            .scalar()
        )
        if result:
            return result.goods_art_no, result.image_index, result.image_deal_mode
        else:
            return None

    def get_data_from_hqt_with_goods_art_no(self, goods_art_no_list):
        _goods_art_no_list = copy.deepcopy(goods_art_no_list)
        _list = []
        # 单次请求数少于20个
        goods_art_no_dict = {}

        while _goods_art_no_list:
            goods_art_no = _goods_art_no_list.pop()

            _list.append(goods_art_no)
            if len(_list) == 20 or len(_goods_art_no_list) == 0:
                online_goods_art_data = self.get_online_data.get_goods_art_no_info(
                    goods_art_list=_list
                )
                if online_goods_art_data:
                    for _goods_art_no in online_goods_art_data:
                        goods_art_no_dict[_goods_art_no] = online_goods_art_data[
                            _goods_art_no
                        ]
                _list = []
        return goods_art_no_dict

    def get_data_from_hqt(self, goods_number_list):
        _goods_number_list = copy.deepcopy(goods_number_list)
        _list = []
        # 单次请求数少于20个
        goods_number_dict = {}

        while _goods_number_list:
            goods_art_no = _goods_number_list.pop()
            if "NUM" in goods_art_no:
                goods_art_no = goods_art_no.replace("NUM", "")

            _list.append(goods_art_no)
            if len(_list) == 20 or len(_goods_number_list) == 0:
                online_goods_art_data = self.get_online_data.get_goods_art_no_info(
                    numbers_list=_list
                )
                if online_goods_art_data:
                    for number in online_goods_art_data:
                        goods_number_dict["NUM" + number] = online_goods_art_data[
                            number
                        ]
                _list = []
        return goods_number_dict

    ##=====设备配置处理=======
    def device_config_delete(self, config_id):
        d_c_1 = self.session.query(DeviceConfig).get(config_id)
        self.session.delete(d_c_1)
        self.session.commit()

    def device_config_delete_by_mode_type(self, mode_type: str):
        all_data = (
            self.session.query(DeviceConfig)
            .filter(DeviceConfig.mode_type == mode_type)
            .all()
        )
        [self.session.delete(u) for u in all_data]
        self.session.commit()

    def device_config_copy_by_id(self, config_id):
        d_c_1 = self.session.query(DeviceConfig).get(config_id)

        d_c_2 = DeviceConfig(
            mode_type=d_c_1.mode_type,
            execution_type=d_c_1.execution_type,
            action_name=d_c_1.action_name + "_复制",
            action_index=d_c_1.action_index + 1,
            picture_index=d_c_1.picture_index,
            camera_height=d_c_1.camera_height,
            camera_angle=d_c_1.camera_angle,
            number_focus=d_c_1.number_focus,
            take_picture=d_c_1.take_picture,
            turntable_position=d_c_1.turntable_position,
            turntable_angle=d_c_1.turntable_angle,
            shoe_upturn=d_c_1.shoe_upturn,
            pre_delay=d_c_1.pre_delay,
            after_delay=d_c_1.after_delay,
            led_switch=d_c_1.led_switch,
            is_wait=d_c_1.is_wait,
        )
        # 复制一个后，其他的数据的排序进行后移
        other_d_c = self.session.query(DeviceConfig).filter(
            DeviceConfig.mode_type == d_c_1.mode_type,
            DeviceConfig.action_index >= d_c_1.action_index + 1,
            DeviceConfig.delete_time.is_(None),
        )
        other_d_c.update(
            {
                DeviceConfig.action_index: DeviceConfig.action_index + 1,
            }
        )
        self.session.add(d_c_2)

        self.session.commit()

    def device_config_add(self, data: dict):
        f_data = (
            self.session.query(
                func.max(DeviceConfig.action_index).label("max_action_index")
            )
            .filter(
                DeviceConfig.mode_type == data["mode_type"],
                DeviceConfig.delete_time.is_(None),
            )
            .scalar()
        )

        if not f_data:
            data["action_index"] = 10
        else:
            data["action_index"] = f_data + 10

        d_c_1 = DeviceConfig(**data)
        self.session.add(d_c_1)
        self.session.commit()

    def device_config_change_action_index(self, up_config_id_1, down_config_id_2):
        d_c_1 = (
            self.session.query(DeviceConfig.action_index)
            .filter(DeviceConfig.id == up_config_id_1)
            .scalar()
        )
        d_c_2 = (
            self.session.query(DeviceConfig.action_index)
            .filter(DeviceConfig.id == down_config_id_2)
            .scalar()
        )

        if d_c_1 == d_c_2:
            d_c = self.session.query(DeviceConfig).get(up_config_id_1)
            d_c.update(
                {
                    DeviceConfig.action_index: DeviceConfig.action_index - 1,
                }
            )
        else:
            d_c_update_1 = self.session.query(DeviceConfig).filter(
                DeviceConfig.id == up_config_id_1
            )
            d_c_update_2 = self.session.query(DeviceConfig).filter(
                DeviceConfig.id == down_config_id_2
            )
            d_c_update_1.update(
                {
                    DeviceConfig.action_index: d_c_2,
                }
            )
            d_c_update_2.update(
                {
                    DeviceConfig.action_index: d_c_1,
                }
            )
        self.session.commit()
        pass

    def device_config_update(self, data: dict):
        d_c = self.session.query(DeviceConfig).filter(DeviceConfig.id == data["id"])
        data.pop("id")
        d_c.update(data)
        self.session.commit()

    def device_config_config_list(self, mode_type, action_name=None):
        _q = self.session.query(DeviceConfig).filter(
            DeviceConfig.mode_type == mode_type, DeviceConfig.delete_time.is_(None)
        )
        if action_name:
            _q = _q.filter(DeviceConfig.action_name == action_name)
        results = _q.order_by(DeviceConfig.action_index.asc()).all()
        return [self.to_dict(row) for row in results]

    def to_dict(self, row):
        return {c.name: getattr(row, c.name, None) for c in row.__table__.columns}

    def device_config_detail(self, config_id):
        results = (
            self.session.query(DeviceConfig)
            .filter(DeviceConfig.id == config_id, DeviceConfig.delete_time.is_(None))
            .one()
        )
        return self.to_dict(results)

    def delete3MonthAgoRecord(self):
        """删除3个月以前得数据"""
        print("d_c_1")
        # 计算3个月前的日期
        three_months_ago = datetime.now() - timedelta(days=90)
        d_c_1 = (
            self.session.query(PhotoRecord)
            .filter(PhotoRecord.create_time < three_months_ago)
            .delete()
        )
        self.session.commit()
