import time

import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
from sqlalchemy import text
from sqlalchemy.orm import sessionmaker
import platform
import traceback
import json
import uuid
from sqlalchemy.exc import SQLAlchemyError


class ConnectSpider:
    def __init__(self):
        self.pg_port = 54328
        self.pg_db = "selection"
        self.pg_user = "postgres"
        self.pg_pwd = "F9kL2sXe81rZq"
        self.pg_host = "61.145.136.61"
        self.db_engine = create_engine(f"postgresql://{self.pg_user}:{self.pg_pwd}@{self.pg_host}:{self.pg_port}/{self.pg_db}")

        pg_host = "192.168.10.223"
        self.db_engine192 = create_engine(
            f"postgresql://{self.pg_user}:{self.pg_pwd}@{self.pg_host}:{self.pg_port}/{self.pg_db}")

        # mysql
        self.sql_port = 3306
        self.sql_db = "selection"
        self.sql_user = "adv_yswg"
        self.sql_pwd = "Gd1pGJog1ysLMLBdML8w81"
        self.sql_host = "rm-wz9yg9bsb2zf01ea4yo.mysql.rds.aliyuncs.com"
        self.charset = 'utf8mb4'

        # 创建数据库连接字符串
        connection_string_mysql = f"mysql+pymysql://{self.sql_user}:{self.sql_pwd}@{self.sql_host}:{self.sql_port}/{self.sql_db}?charset={self.charset}"
        self.mysql_engine = create_engine(connection_string_mysql)

        # mysql
        sql_port = 19030
        sql_db = "test"
        sql_user = "fangxingjun"
        sql_pwd = "fangxingjun12345"
        sql_host = "192.168.10.151"
        wai_host = "113.100.143.162"

        # 创建数据库连接字符串
        connection_string_mysql = f"mysql+pymysql://{sql_user}:{sql_pwd}@{wai_host}:{sql_port}/{sql_db}"
        self.mysql_test = create_engine(connection_string_mysql)

        # mysql
        sql_port = 19030
        sql_db = "selection"
        sql_user = "fangxingjun"
        sql_pwd = "fangxingjun12345"
        sql_host = "192.168.10.151"
        wai_host = "113.100.143.162"

        # 创建数据库连接字符串
        connection_string_mysql = f"mysql+pymysql://{sql_user}:{sql_pwd}@{sql_host}:{sql_port}/{sql_db}"
        self.mysql_selection = create_engine(connection_string_mysql)

    def con (self):
        # pg_port = 5433
        # pg_db = "selection"
        # pg_user = "postgres"
        # pg_pwd = "fazAqRRVV9vDmwDNRNb593ht5TxYVrfTyHJSJ3BS"
        # pg_host = "61.145.136.61"
        # db_engine = create_engine(f"postgresql://{pg_user}:{pg_pwd}@{pg_host}:{pg_port}/{pg_db}")
        # return db_engine
        if platform.system().lower() == 'windows':
            PG_CONN_DICT = {
                "pg_port": 5433,
                "pg_db": "selection",
                "pg_user": "postgres",
                "pg_pwd": "fazAqRRVV9vDmwDNRNb593ht5TxYVrfTyHJSJ3BS",
                "pg_host": "192.168.10.223",
            }
        else:
            PG_CONN_DICT = {
                "pg_port": 5433,
                "pg_db": "selection",
                "pg_user": "postgres",
                "pg_pwd": "fazAqRRVV9vDmwDNRNb593ht5TxYVrfTyHJSJ3BS",
                "pg_host": "61.145.136.61",
            }
        nums = 0
        while True:
            try:
                db = 'selection'
                engine_pg = create_engine(
                    f"postgresql+psycopg2://{PG_CONN_DICT['pg_user']}:{PG_CONN_DICT['pg_pwd']}@{PG_CONN_DICT['pg_host']}:{PG_CONN_DICT['pg_port']}/{db}",
                    encoding='utf-8', connect_args={"connect_timeout": 10}, poolclass=NullPool)
                return engine_pg
            except Exception as e:
                print("pg_connect 14 t11111111111111111111111:", e, f"\n{traceback.format_exc()}")
                continue

    def mysql(self):
        sql_port = 3306
        sql_db = "us_spider"
        sql_user = "adv_yswg"
        sql_pwd = "Gd1pGJog1ysLMLBdML8w81"
        sql_host = "rm-wz9yg9bsb2zf01ea4yo.mysql.rds.aliyuncs.com"
        charset = 'utf8mb4'

        # 创建数据库连接字符串
        connection_string_mysql = f"mysql+pymysql://{sql_user}:{sql_pwd}@{sql_host}:{sql_port}/{sql_db}?charset={charset}"
        mysql_engine = create_engine(connection_string_mysql)
        return mysql_engine

    def mysql_us_spider(self):
        sql_port = 19030
        # sql_db = "us_spider"
        sql_db = "test"
        sql_user = "fangxingjun"
        sql_pwd = "fangxingjun12345"
        sql_host = "192.168.10.151"

        # 创建数据库连接字符串
        connection_string_mysql = f"mysql+pymysql://{sql_user}:{sql_pwd}@{sql_host}:{sql_port}/{sql_db}"
        mysql_us_spider_engine = create_engine(connection_string_mysql)
        return mysql_us_spider_engine


    def save_stock_img_id(self, items):
        """批量保存数据到数据库。"""
        table_name = "stock_image_id_wj"

        # 定义DataFrame的列
        columns = ['account_id', 'image_id', 'state', 'created_at']
        df = pd.DataFrame(items, columns=columns)

        # 使用with语句管理数据库连接
        with self.db_engine192.connect() as connection:
            df.to_sql(
                name=table_name,
                con=connection,
                if_exists='append',
                index=False
            )
        # print("保存成功！")

    # def get_account_id(self,item_id):
    #     with self.db_engine192.connect() as connection:
    #         table_name = "stock_image_summary_wj"
    #         # 修改查询语句以匹配你的数据表名称和列名称
    #         # query = f"""-- SELECT account_id,id FROM {table_name} where id = 27 ;"""
    #         query = text(f"SELECT account_id,id FROM {table_name} where id = :item_id")
    #         result = connection.execute(query, {"item_id": item_id})
    #         print(query)
    #         # 执行查询并将结果读取到 DataFrame 中
    #         df_status = pd.read_sql(query, con=connection)
    #         accounts = df_status.account_id.iloc[0]
    #         print(f'账号:{accounts}')
    #         # success_id = tuple(df_status.id)
    #         # sql_update = text(f"UPDATE {table_name} SET state = 2 WHERE id IN :success_id")
    #         # result = connection.execute(sql_update, {"success_id": success_id})
    #         # print('成功更新为2')
    #         connection.close()
    #         return accounts

    def get_account_id(self, item_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_summary_wj"
            query = text(f"SELECT account_id, id FROM {table_name} WHERE id = :item_id")
            result = connection.execute(query, {"item_id": item_id})
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()
            try:
                accounts = df_status.account_id.iloc[0]
            except IndexError:
                accounts = None  # 或者处理不存在的情况
            return accounts

    def update_id_to_3(self,account_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_summary_wj"
            success_id = tuple(account_id)
            sql_update = text(f"UPDATE {table_name} SET state = 3 WHERE account_id IN :success_id")
            result = connection.execute(sql_update, {"success_id": success_id})
            print('成功更新为3')
            connection.close()

    def save_account(self,items):
        """批量保存数据到数据库。"""
        table_name = "stock_image_summary_wj"

        # 定义DataFrame的列
        columns = ['account_id', 'account_secret', 'year_month', 'spider_date','state','created_time']
        df = pd.DataFrame(items, columns=columns)

        # 使用with语句管理数据库连接
        with self.db_engine192.connect() as connection:
            df.to_sql(
                name=table_name,
                con=connection,
                if_exists='append',
                index=False
            )
        print("保存成功！")


    def delet_datails(self, image_id_list):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"

            # 使用 SQLAlchemy 的 text 函数来创建 SQL 语句
            query = text(f"SELECT image_id FROM {table_name} WHERE account_id = 'zhouweiqing@yswg.com.cn';")

            # 使用 connection.execute() 来执行查询
            result = connection.execute(query).fetchall()

            # 获取表中的 image_id 列表
            db_image_ids = [row[0] for row in result]

            # 找出不在 image_id_list 中的 image_id
            non_existent_image_ids = set(db_image_ids) - set(image_id_list)

            # 删除不在 image_id_list 中的记录
            for image_id in non_existent_image_ids:
                delete_query = text(
                    f"DELETE FROM {table_name} WHERE account_id = 'zhouweiqing@yswg.com.cn' AND image_id = '{image_id}';")
                connection.execute(delete_query)

            # 提交更改
            connection.commit()


    def get_datails_image_id(self, account_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"
            sql_query = text(f"SELECT image_id FROM {table_name} WHERE account_id = :account_id and created_time  < '2024-09-02 00:00:00'")
            result = connection.execute(sql_query, {"account_id": account_id})
            image_id_list = [int(row[0]) for row in result.fetchall()]
            # 提交更改
            # connection.commit()
            return image_id_list



    # 1111111111111
    def save_stock_detail(self, item):
        """批量保存数据到数据库。"""
        table_name = "stock_image_detail_wj"

        # 将item包装成列表
        items_list = [item]

        # 定义DataFrame的列
        columns = ['account_id', 'image_id', 'image_size_info', 'image_title', 'image_type', 'image_url', 'created_time']
        df = pd.DataFrame(items_list, columns=columns)

        with self.db_engine192.connect() as connection:
            df.to_sql(
                name=table_name,
                con=connection,
                if_exists='append',
                index=False
            )
        # print("保存成功！")

    def get_stock_image_id(self):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_id_wj"
            # 修改查询语句以匹配你的数据表名称和列名称
            query = f"""SELECT image_id,id FROM {table_name} where account_id = 'daiting@yswg.com.cn' and state = 1;"""
            print(query)
            # 执行查询并将结果读取到 DataFrame 中
            df_status = pd.read_sql(query, con=connection)
            df_status['id'] = df_status['id'].astype(str)

            # 现在你可以安全地连接两列了
            image_id_id_pairs = list(df_status['image_id'] + '||-||' + df_status['id'])
            success_id = tuple(df_status.id)
            connection.close()
            return image_id_id_pairs


    #111111111111111111111
    def get_stock_images_id(self,account_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_id_wj"
            # 修改查询语句以匹配你的数据表名称和列名称
            query = text(f"""SELECT image_id,id FROM {table_name} where account_id = :account_id and state = 1""")
            print(query)
            result = connection.execute(query, {'account_id': account_id})
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()

            df_status['id'] = df_status['id'].astype(str)
            image_id_id_pairs = list(df_status['image_id'] + '||-||' + df_status['id'])
            print(f'账号：{account_id}需爬取{len(image_id_id_pairs)}张')
            connection.close()
            return image_id_id_pairs

    def get_kong_images_id(self, account_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"
            # 使用子查询来过滤掉已经有 image_size_info 的 image_id
            query = text(
                f"""SELECT image_id, image_type, image_url 
                    FROM {table_name} 
                    WHERE account_id = :account_id 
                    AND image_id NOT IN (
                        SELECT image_id 
                        FROM {table_name} 
                        WHERE account_id = :account_id 
                        AND image_size_info != '{{}}'
                    )
                    AND image_size_info = '{{}}'"""
            )
            print(query)
            result = connection.execute(query, {'account_id': account_id})
            df_status = pd.DataFrame(result.fetchall(), columns=result.keys())
            if df_status.empty:
                return []
            data_list = list(df_status['image_id'] + '||' + df_status['image_type'] + '||' + df_status['image_url'])
            connection.close()
            return data_list

    def get_stock_image_detail(self, account_id):
        with self.mysql_selection.connect() as connection:
            table_name = "stock_image_detail"
            query = text(
                f"""SELECT account_id, image_id, image_size_info, image_title, image_type, image_url, created_time FROM {table_name} WHERE account_id = :account_id""")
            print(query)
            result = connection.execute(query, {'account_id': account_id})
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()

            # 将 Timestamp 转换为字符串格式
            df_status['created_time'] = df_status['created_time'].dt.strftime('%Y-%m-%d %H:%M:%S')

            # 拼接字符串
            detail_datas = list(
                df_status['account_id'] + '||-||' +
                df_status['image_id'] + '||-||' +
                df_status['image_size_info'] + '||-||' +
                df_status['image_title'] + '||-||' +
                df_status['image_type'] + '||-||' +
                df_status['image_url'] + '||-||' +
                df_status['created_time']
            )
            print(f'账号：{account_id} 一共 {len(detail_datas)} 条数据')
            return detail_datas

    def save_stock_detail_move(self, data_list):
        table_name = "stock_image_detail_wj"

        # 定义DataFrame的列
        columns = ['account_id', 'image_id', 'image_size_info', 'image_title', 'image_type', 'image_url',
                   'created_time']
        df = pd.DataFrame(data_list, columns=columns)

        with self.db_engine192.connect() as connection:
            df.to_sql(
                name=table_name,
                con=connection,
                if_exists='append',
                index=False
            )
        print("保存成功！")

    # 11111111111
    def update_image_id_to_3(self, item_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_id_wj"
            sql_update = text(f"UPDATE {table_name} SET state = 3 WHERE id = :item_id")
            result = connection.execute(sql_update, {"item_id": item_id})
            connection.close()

    # 11111111111
    def update_image_id_to_4(self, item_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_id_wj"
            sql_update = text(f"UPDATE {table_name} SET state = 4 WHERE id = :item_id")
            result = connection.execute(sql_update, {"item_id": item_id})
            connection.close()

    def save_stock_cookie(self,item):
        table_name = "stock_cookie_wj"
        # 将item包装成列表
        items_list = [item]
        # 定义DataFrame的列
        columns = ['account_id', 'cookie', 'state', 'created_at']
        df = pd.DataFrame(items_list, columns=columns)

        with self.db_engine192.connect() as connection:
            df.to_sql(
                name=table_name,
                con=connection,
                if_exists='append',
                index=False
            )
        print("保存成功！")


    # def get_stock_cookie(self, account):
    #     with self.db_engine192.connect() as connection:
    #         table_name = "stock_cookie_wj"
    #         # 使用参数化查询
    #         query = text(f"""SELECT cookie FROM {table_name} WHERE account_id = :account_id AND state = :state;""")
    #         result = connection.execute(query, {'account_id': account, 'state': 1})
    #         df_status = pd.DataFrame(result.fetchall())
    #         df_status.columns = result.keys()
    #         cookie_list = df_status['cookie'].tolist() if 'cookie' in df_status.columns else []
    #         return cookie_list

    def get_stock_cookie(self, account):
        with self.db_engine192.connect() as connection:
            table_name = "stock_cookie_wj"
            # 使用参数化查询
            query = text(f"""SELECT cookie FROM {table_name} WHERE account_id = :account_id AND state = :state ; """)
            result = connection.execute(query, {'account_id': account, 'state': 1})
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()
            cookie_list = df_status['cookie'].tolist() if 'cookie' in df_status.columns else []
            return cookie_list

    def get_cookie_account(self,item_id):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_summary_wj"
            # 修改查询语句以匹配你的数据表名称和列名称
            query = text(f"""SELECT account_id,account_secret FROM {table_name} where id = :item_id ;""")
            result = connection.execute(query, {'item_id': item_id})
            # print(query)
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()
            account_id = df_status.account_id.iloc[0]
            account_secret = df_status.account_secret.iloc[0]
            account_list = [account_id, account_secret]
            # print(account_list)
            # print(111111111111)
            connection.close()
            return account_list

    def get_stock_test_id(self,username):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_id_wj"
            # 修改查询语句以匹配你的数据表名称和列名称
            query = text(f"""SELECT image_id FROM {table_name} WHERE account_id = :username LIMIT 1;""")
            result = connection.execute(query, {'username': username})
            df_status = pd.DataFrame(result.fetchall())
            df_status.columns = result.keys()
            image_id = df_status.image_id.iloc[0]
            connection.close()
            return image_id

    def upload_data(self, account_id, image_id, upload_time, err_msg):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"
            # 强制将 image_id 转换为字符串类型
            image_id = str(image_id)
            err_msg_json = json.dumps(err_msg)
            sql_update = text(
                f"UPDATE {table_name} SET upload_time = :upload_time, err_msg = :err_msg WHERE account_id = :account_id AND image_id = :image_id AND created_time  < '2024-09-02 00:00:00'")
            result = connection.execute(sql_update, {
                "upload_time": upload_time,
                "err_msg": err_msg_json,
                "account_id": account_id,
                "image_id": image_id
            })

    def upload_success_data(self, account_id, image_id, upload_time):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"
            # 强制将 image_id 转换为字符串类型
            image_id = str(image_id)
            sql_update = text(
                f"UPDATE {table_name} SET upload_time = :upload_time WHERE account_id = :account_id AND image_id = :image_id AND created_time  < '2024-09-02 00:00:00'")
            result = connection.execute(sql_update, {
                "upload_time": upload_time,
                "account_id": account_id,
                "image_id": image_id
            })



    def get_all_image_id(self):
        with self.db_engine192.connect() as connection:
            table_name = "stock_image_detail_wj"
            sql_query = f"SELECT image_id FROM {table_name} "
            df_status = pd.read_sql(sql_query, con=connection)
            image_id = list(df_status['image_id'].astype(str))

            connection.close()
            return image_id




