import sys
import os

sys.path.append(os.path.dirname(sys.path[0]))  # 上级目录
import pandas as pd
from amazon_params.db_connect import BaseUtils
from amazon_params.params import DB_REQUESTS_ASIN_PARAMS
from amazon_params.requests_param import Requests_param_val
import traceback

print('存储  测试关键词的asin ')


class Save_asin_detail(BaseUtils):
    def __init__(self, site_name=None, proxy_name=None):
        super().__init__()
        self.site_name = site_name  # 站点
        self.asin_detail_list = []
        self.stop_item_queue = True
        self.cols = ['asin', 'sku', 'adv_num']
        self.init_db_names()
        self.read_size = 100
        print("存储 调用 配置 proxy_name：", proxy_name)
        self.reuests_para_val = Requests_param_val(site_name=self.site_name, proxy_name=proxy_name)

    def init_db_names(self):
        """
                1. 初始化数据库连接
                2. 初始化数据库表名
        """
        self.engine = self.mysql_connect()
        self.db_syn = DB_REQUESTS_ASIN_PARAMS['db_potential_product_asin_syn'][3:]
        self.potential_product_asin = DB_REQUESTS_ASIN_PARAMS['db_potential_product_asin'][3:]

    def process_item(self, item_queue, requests_error_asin_list, asin_list_update, asin_not_found_list,
                     asin_not_sure_list, asin_not_foot_list, asin_not_foot2_list, asin_not_buyBox_list,
                     asin_not_response_list, asin_not_redirect_list, asin_not_div_id_dp_list,
                     asin_variation_list, star_list, add_cart_asin_list, bs_category_asin_list):
        print("=================开始存储数据======================")
        while True:
            if item_queue.empty() == False:
                item = item_queue.get()
                item_list = []
                # 需要存到数据库的字段
                item_list.append(item['asin'])
                item_list.append(item['sku'])
                item_list.append(item['sp_num'])
                self.asin_detail_list.append(item_list)
            else:
                if item_queue.empty():
                    self.save_data(requests_error_asin_list, asin_list_update, asin_not_found_list, asin_not_sure_list,
                                   asin_not_foot_list, asin_not_foot2_list, asin_not_buyBox_list,
                                   asin_not_response_list, asin_not_redirect_list, asin_not_div_id_dp_list,
                                   asin_variation_list, star_list, add_cart_asin_list, bs_category_asin_list)
                    self.asin_detail_list = []
                    print("结束--跳出--存储")
                    break

    def read_db_data(self):
        while True:
            try:
                with self.engine.begin() as conn:
                    sql_read = f'SELECT id,asin,sku FROM {self.db_syn} WHERE asin_state=1 LIMIT {self.read_size} for update;'
                    print(sql_read)
                    a = conn.execute(sql_read)
                    self.df_read = pd.DataFrame(a, columns=['id', 'asin', 'sku'])
                    self.df_read.drop_duplicates(['asin'], inplace=True)
                    if self.df_read.shape[0] == 0:
                        print('*********** asin 数据抓取 完毕 *****************')
                        self.stop_item_queue = False
                        return []
                    self.index_tuple = tuple(self.df_read['id'])
                    if len(self.index_tuple) == 1:
                        sql_update = f"""UPDATE {self.db_syn} a set asin_state=2 where a.id in ({self.index_tuple[0]})"""
                    else:
                        sql_update = f"""UPDATE {self.db_syn} a set asin_state=2 where a.id in {self.index_tuple}"""
                    conn.execute(sql_update)
                asin_list = list(self.df_read.asin + '|' + self.df_read.sku)
                return asin_list
            except Exception as e:
                print("读取数据出bug并等待5s继续", e, f"\n{traceback.format_exc()}")
                self.mysql_reconnect(table_name=self.db_syn, e=e)
                continue

    def save_data(self, requests_error_asin_list, asin_list_update, asin_not_found_list, asin_not_sure_list,
                  asin_not_foot_list, asin_not_foot2_list, asin_not_buyBox_list, asin_not_response_list,
                  asin_not_redirect_list, asin_not_div_id_dp_list, asin_variation_list, star_list,
                  add_cart_asin_list, bs_category_asin_list):
        while True:
            try:
                df_asin_detail = pd.DataFrame(data=self.asin_detail_list, columns=self.cols)
                self.asin_list_update = list(df_asin_detail.asin)
                df_asin_detail.drop_duplicates(['asin', 'sku'], inplace=True)  # 去重
                # if df_asin_star.shape[0] > 0:
                #     with self.engine.begin() as conn:
                #         if len(set(df_asin_star.asin)) == 1:
                #             sql_delete_star = f"delete from {self.db_asin_star} where week={week_} and asin in ('{tuple(df_asin_star.asin)[0]}');"
                #         else:
                #             sql_delete_star = f"delete from {self.db_asin_star} where week={week_} and asin in {tuple(set(df_asin_star.asin))};"
                #         conn.execute(sql_delete_star)
                df_asin_detail.to_sql(self.potential_product_asin, con=self.engine, if_exists='append', index=False)
                break
            except Exception as e:
                print(f"存储'{self.db_asin_star}'失败，等待5s继续", e, f"\n{traceback.format_exc()}")
                self.mysql_reconnect(table_name=self.db_asin_star, e=e)
                continue

        if requests_error_asin_list:
            self.db_change_state(state=1, asin_list=requests_error_asin_list)
        if self.asin_list_update:
            self.db_change_state(state=3, asin_list=self.asin_list_update)
        if asin_not_found_list:
            self.db_change_state(state=4, asin_list=asin_not_found_list)
        if asin_not_sure_list:
            self.db_change_state(state=6, asin_list=asin_not_sure_list)
        if asin_not_foot_list:
            self.db_change_state(state=7, asin_list=asin_not_foot_list)  # 没有脚
        if asin_not_foot2_list:
            self.db_change_state(state=8, asin_list=asin_not_foot2_list)
        if asin_not_buyBox_list:
            self.db_change_state(state=9,
                                 asin_list=asin_not_buyBox_list)  # 只有图片和标题，其他数据没有 https://www.amazon.com/dp/B016IBFUWC/qid=1637397113
        if asin_not_response_list:
            self.db_change_state(state=10,
                                 asin_list=asin_not_response_list)  # https://www.amazon.com/dp/B08G3HL4PR 返回空白 html
        if asin_not_redirect_list:
            self.db_change_state(state=12, asin_list=asin_not_redirect_list)
        if asin_not_div_id_dp_list:
            self.db_change_state(state=13, asin_list=asin_not_div_id_dp_list)

    def db_change_state(self, state=2, asin_list=None):
        self.db_change_state_common(state=state, asin_list=asin_list)

    def db_change_state_common(self, state, asin_list):
        print(f"==================== 存储状态 {state} 数据 ========== {len(asin_list)} ========")
        df = self.df_read.loc[self.df_read.asin.isin(asin_list)]
        if state == 3:
            # 剔除状态 7，9 的id
            df = self.df_read.loc[self.df_read.asin.isin(asin_list)]
        id_tuple = tuple(df.id)
        while True:
            try:
                with self.engine.begin() as conn:
                    # 1,3：1--回滚；3--成功
                    if id_tuple:
                        if len(id_tuple) == 1:
                            sql_update = f"update {self.db_syn} set asin_state={state} where id in ({id_tuple[0]}) and asin_state=2;"
                        else:
                            sql_update = f"update {self.db_syn} set asin_state={state} where id in {id_tuple} and asin_state=2;"
                        conn.execute(sql_update)
                break
            except Exception as e:
                print(f"更改{self.db_syn}表的state={state}出错", e, f"\n{traceback.format_exc()}")
                self.mysql_reconnect(table_name=self.db_syn, e=e)
                continue
