from wechat_action.sql_tools import save_human_info, delete_wechat_info, save_wechat_info
from wechat_api.get_wechat_info import WechatApi
from wechat_action.create_ad_layout import CreateAd
from wechat_action.create_ad_plan import CreateAdPlan
from wechat_action import sql_tools
from sqlalchemy import Table
from communication_tools import dingtalk
import json
import logging
from datetime import datetime
from wechat_action.login_ad import LogIn

# 定位为:接受请求之后对应的线程处理
layout_create_action = 'create_ad_layout'
ad_plan_create_action = 'create_ad_plan'
refresh_wechat_action = 'refresh_wechat_info'


def carry_plan(user_id, ad_plan_list, log_ad, db, cookie_canuse, task_name):
    # TODO:失败后 ,状态为:创建中  ----进行对应删除

    # 创建中的数据需要进行删除
    sql_session = db.DBSession()

    try:
        action_record_table = Table('action_record', db.metadata,
                                    autoload=True, autoload_with=db.engine)

        # cookies保存
        if not cookie_canuse:
            log_ad.cookies_save(log_ad,sql_session)
        for _ in ad_plan_list:
            service_name = _['service_name']
            wechat_name = _['wechat_name']
            plan_name = _['title']
            try:
                # 1.检查1.落地页是否创建过了
                log_ad.select_ad_master(service_name, wechat_name,sql_session)
                # 现在默认layout_name在30个字符以内
                layout_name = _['idea']['jump_type_page_type']['layout_name']
                if CreateAd.check_sucess_api(layout_name=layout_name, log_ad=log_ad):
                    res = {'sucess': True, 'result_info': '已经创建过对应落地页'}
                    sql_tools.action_record(res, sql_session, layout_create_action, user_id, layout_name,
                                            action_record_table,
                                            service_name, wechat_name, task_name)

                else:
                    # 1.5无则创建落地页
                    try:
                        create_ad_layout = CreateAd(login_ad=log_ad, service_name=service_name, wechat_name=wechat_name)
                        layout_typesetting_dict = sql_tools.get_layout_typesetting(sql_session, user_id,
                                                                                   typesetting_name=layout_name)
                        layout_typesetting_dict = json.loads(layout_typesetting_dict)
                        res = create_ad_layout.create_layout(layout_typesetting_dict,sql_session)
                        sql_tools.action_record(res, sql_session, layout_create_action, user_id, layout_name,
                                                action_record_table,
                                                service_name, wechat_name, task_name)
                    except Exception as e:
                        res = {'sucess': False, 'result_info': str(e)}
                        logging.error('layout 创建失败,{}'.format(str(e)))
                        # 创建落地页,计划都失败
                        sql_tools.action_record(res, sql_session, layout_create_action, user_id, layout_name,
                                                action_record_table,
                                                service_name, wechat_name, task_name)
                        res = {'sucess': False, 'result_info': '落地页创建失败'}
                        sql_tools.action_record(res, sql_session, ad_plan_create_action, user_id, plan_name,
                                                action_record_table,
                                                service_name, wechat_name, task_name)
                        raise
                        continue

                log_ad.refresh_driver()
                # 3.创建计划
                log_ad.select_ad_master(service_name, wechat_name,sql_session)
                # plan_typesetting_dict = sql_tools.get_ad_plan_typesetting(sql_session=sql_session, user_id=user_id,
                #                                                           typesetting_name=plan_name)
                create_ad_plan = CreateAdPlan(login_ad=log_ad, task=_, service_name=service_name,
                                              wechat_name=wechat_name)
                res = create_ad_plan.run(sql_session)
                # 4.更新action_record相关计划信息
                sql_tools.action_record(res, sql_session, ad_plan_create_action, user_id, plan_name,
                                        action_record_table,
                                        service_name, wechat_name, task_name)
                logging.info('创建计划任务结束')
            except Exception as e:
                log_ad.driver.save_screenshot(
                    'user_id:{}_time_{}_plan_name:{}_plan_error.png'.format(user_id, datetime.now().strftime(
                        "%Y-%m-%d, %H:%M:%S"), plan_name))
                logging.error(str(e))
                res = {'sucess': False, 'result_info': str(e)}
                sql_tools.action_record(res, sql_session, ad_plan_create_action, user_id, plan_name,
                                        action_record_table,
                                        service_name, wechat_name, task_name)
                raise
            finally:
                log_ad.refresh_driver()


    except Exception as e:
        sql_tools.update_task_status_error(sql_session=sql_session, user_id=user_id, task_name=task_name)
        dingtalk.send_message('user_id:{} 计划执行出错,进行检查\n{}'.format(user_id, str(e)))
        logging.error(e)
        raise
    finally:
        logging.info('创建计划,任务结束')
        # 每次运行微信相关操作,对微信相关信息进行刷新
        sql_session.commit()
        log_ad.driver.quit()
        check_task_in_hand(user_id, db)


def get_human_info(user_id, log_ad, db, cookie_canuse, task_name):
    # 数据库
    action_record_table = Table('action_record', db.metadata,
                                autoload=True, autoload_with=db.engine)
    human_info_table = Table('human_info', db.metadata,
                             autoload=True, autoload_with=db.engine)
    wechat_info_table = Table('wechat_info', db.metadata,
                              autoload=True, autoload_with=db.engine)
    sql_session = db.DBSession()

    # 行为记录对应参数
    object_name = ''
    service_name = ''
    wechat_name = ''
    try:
        # 1.cookies保存
        if not cookie_canuse:
            log_ad.cookies_save(log_ad,sql_session)

        # 动作存放
        object_name = ''
        action_info = {'user_id': user_id, 'service_name': service_name,
                       'wechat_name': wechat_name,
                       'action_type': refresh_wechat_action, 'object_name': object_name, 'task_name': task_name,
                       'status': 'todo'}
        record_insert = sql_tools.save_action_record(action_record_info=action_info,
                                                     table_action_record=action_record_table)
        sql_session.execute(record_insert)
        sql_session.commit()

        # wechat_info.每次都删除掉前面全部数据,进行更新
        # human_info 进行全局更新
        w_api = WechatApi(log_ad=log_ad)
        res_info = w_api.get_human_info(sql_session)

        if not res_info['sucess']:
            dingtalk.send_message('user_id:{} 获取微信数据为空,进行检查'.format(user_id))

            sql_tools.action_record(res_info, sql_session, refresh_wechat_action, user_id,
                                    object_name, action_record_table,
                                    service_name, wechat_name, task_name)
            return

        # wechat info进行数据更新
        # 1.删除所有数据
        delete_wechat_info(sql_session=sql_session, user_id=user_id)
        # 2.重新添加一遍相关数据
        for _ in res_info['result_list']:
            service_name_wechat = _['service_name']
            wechat_name_wechat = _['wechat_name']
            appid = _['appid']
            wxname = _['wxname']
            wechat_info = {'appid': appid, 'wxname': wxname, 'service_name': service_name_wechat,
                           'wechat_name': wechat_name_wechat,
                           'user_id': user_id}
            wechat_insert = save_wechat_info(wechat_info=wechat_info,
                                             table_wechat=wechat_info_table)

            sql_session.execute(wechat_insert)
            sql_session.commit()
        logging.info('update wechat info')

        # human info 相关数据进行更新
        for _ in res_info['result_list']:
            service_name_human = _['service_name']
            wechat_name_human = _['wechat_name']
            human_info = _['data']['list']

            update_res = human_info_table.update() \
                .where(human_info_table.c.service_name == service_name_human) \
                .where(human_info_table.c.wechat_name == wechat_name_human) \
                .values(human_info=human_info)
            update_res = sql_session.execute(update_res)
            sql_session.commit()
            if update_res.rowcount == 0:
                human_info = {'service_name': service_name_human, 'wechat_name': wechat_name_human,
                              'human_info': human_info}
                human_insert = save_human_info(human_info=human_info,
                                               table_human=human_info_table)

                sql_session.execute(human_insert)
                sql_session.commit()
            logging.info('update human info')

        sql_tools.action_record(res_info, sql_session, refresh_wechat_action,
                                user_id, object_name, action_record_table,
                                service_name, wechat_name, task_name)
        log_ad.refresh_driver()

    except Exception as e:
        res_info = {'sucess': False, 'result_info': str(e)}
        sql_tools.action_record(res_info, sql_session, refresh_wechat_action,
                                user_id, object_name, action_record_table,
                                service_name, wechat_name, task_name)

        log_ad.driver.save_screenshot(
            'user_id:{}_time_{}_wechat_info_error.png'.format(user_id, datetime.now().strftime("%Y-%m-%d, %H:%M:%S")))
        dingtalk.send_message('user_id:{} 获取微信数据出错,进行检查\n{}'.format(user_id, str(e)))
        log_ad.refresh_driver()
        logging.error(e)
        raise
    finally:
        logging.info('刷新用户,任务结束')
        sql_session.commit()
        log_ad.driver.quit()
        check_task_in_hand(user_id=user_id, db=db)


def check_task_in_hand(user_id, db):
    sql_session = db.DBSession()
    lines = sql_tools.get_task_in_hand_limit_one(user_id=user_id, sql_session=sql_session)

    task_name = ''
    ad_plan_list = []
    action_type = ''
    for _ in lines:
        typesetting, wechat_name, service_name, action_type, task_name = _
        ad_plan_list.append(json.loads(typesetting))
    if action_type == refresh_wechat_action:
        # 刷新log_ad,以免log_ad超过生命周期
        log_ad = LogIn(user_id=user_id)
        get_human_info(user_id, log_ad, db, True, task_name)
    if action_type == ad_plan_create_action:
        log_ad = LogIn(user_id=user_id)
        carry_plan(user_id, ad_plan_list, log_ad, db, True, task_name)


if __name__ == "__main__":
    pass