import sys
import os

sys.path.append(os.path.dirname(sys.path[0]))  # 上级目录
from curl_cffi import requests
from sqlalchemy import create_engine
import pandas as pd
from queue import Queue
import threading
import time
import subprocess
import os
from amazon_params.params import DB_CONN_DICT, PG_CONN_DICT
import urllib3
from threading import Lock

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from utils.requests_param import Requests_param_val
import traceback
from datetime import datetime, timedelta
from amazon_spider.VPS_IP import is_internet_available
from func_timeout import func_set_timeout
from func_timeout.exceptions import FunctionTimedOut
import paramiko


class Amazon_Img():
    def __init__(self, site_name):
        self.site_name = site_name
        self.asin_img_queue = Queue()
        self.asin_state_list = []
        self.asin_not_find = []
        self.asin_imgurl_null = []
        self.reuests_para_val = Requests_param_val(site_name=self.site_name)
        self.mysql_reconnect()
        # SFTP服务器的连接信息
        self.host = "61.145.136.61"
        self.port = 218
        self.username = "vps_ftp"
        self.password = "ysws123!@#"

    def mysql_reconnect(self):
        nums = 0
        while True:
            nums += 1
            try:
                if self.site_name == 'us':
                    db = 'selection'
                else:
                    db = f'selection_{self.site_name}'
                self.engine = create_engine(
                    f'mysql+pymysql://{DB_CONN_DICT["mysql_user"]}:' + f'{DB_CONN_DICT["mysql_pwd"]}@{DB_CONN_DICT["mysql_host"]}:{DB_CONN_DICT["mysql_port"]}/{db}?charset=utf8mb4',
                    connect_args={"connect_timeout": 30})  # , pool_recycle=3600
                break
            except Exception as e:
                print("error_mysql_connect:", e, f"\n{traceback.format_exc()}")
                time.sleep(nums * 20)
                continue

    def ssh_connect(self):
        while True:
            try:
                # 创建SSH客户端
                self.ssh = paramiko.SSHClient()
                self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                # 连接到SFTP服务器
                self.ssh.connect(self.host, self.port, self.username, self.password, timeout=15)
                # 创建SFTP客户端
                self.sftp = self.ssh.open_sftp()
                break
            except:
                print('重新连接')
                time.sleep(5)

    def delete_img_path(self, path):
        try:
            command = f"rm {path}"
            # 使用subprocess运行命令
            subprocess.run(command, shell=True)
        except Exception as e:
            print(f"Error deleting file: {e}")

    def downlad_img(self):
        while True:
            if self.asin_img_queue.empty() == False:
                querys = self.asin_img_queue.get()
                query = querys.split('|-|')
                print('请求：：：', query)
                asin = query[0]
                asin_img_path = 'temu'
                img_url = query[1]
                # https://img.kwcdn.com/product/Fancyalgo/VirtualModelMatting/0f47aafebeb2331e32d20eb5973a3b62.jpg
                headers = {
                    'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
                    'accept-language': 'zh-CN,zh;q=0.9',
                    'Host': 'img.kwcdn.com',
                    'cache-control': 'no-cache',
                    'Connection': 'keep-alive',
                    'pragma': 'no-cache',
                    'sec-fetch-dest': 'image',
                    'sec-fetch-mode': 'no-cors',
                    'sec-fetch-site': 'cross-site',
                    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
                }
                if img_url == 'null' or img_url == 'None' or img_url == '':
                    self.asin_imgurl_null.append(asin)
                    continue
                try:
                    r = requests.get(img_url, headers=headers, timeout=60, verify=False,
                                     impersonate="chrome110")  # 获取网页
                except Exception as e:
                    print('========================请求报错：', e)
                    self.asin_not_find.append(asin)
                    continue

                # 获取当前时间
                current_time = datetime.now()
                # 格式化时间为 'YYYYMMDDHH' 格式
                formatted_time = current_time.strftime('%Y%m%d%H')
                asin_upper = asin.upper()
                path_1 = fr"/run/{formatted_time}/mnt/data/img_data/{asin_img_path}"
                print(asin, "存储路径", rf"{path_1}/{asin_upper}.jpg")
                if os.path.exists(path_1) == False:  # 判断路径是否存在
                    os.makedirs(path_1)
                with open(rf"/run/{formatted_time}/mnt/data/img_data/{asin_img_path}/{asin_upper}.jpg",
                          'wb') as f:  # 打开写入到path路径里-二进制文件，返回的句柄名为f
                    f.write(r.content)  # 往f里写入r对象的二进制文件
                self.asin_state_list.append(asin)
                while True:
                    try:
                        # /run/2023112009/mnt/data/img_data/temu/601099515670861.jpg
                        self.to_server_img(rf"/run/{formatted_time}/mnt/data/img_data/{asin_img_path}/{asin_upper}.jpg",
                                           f"{asin_upper}.jpg")
                        break
                    except FunctionTimedOut as e:
                        print('断网', e)
                        time.sleep(10)
                        # 重新连接并重试上传
                        self.ssh_connect()

            else:
                break

    @func_set_timeout(15)
    def update_asin_state(self, state=2, asin_list=None):
        if len(asin_list) > 1:
            print("asin_list::", asin_list)
            df = self.df_read.loc[(self.df_read.asin_compet.isin(asin_list))]
            asin_tuple = tuple(df.asin_compet)
            print(state, '修改状态::', len(asin_tuple))
            while True:
                try:
                    print('修改状态')
                    with self.engine.begin() as conn:
                        # 1,3：1--回滚；3--成功
                        if asin_list:
                            if len(asin_tuple) == 1:
                                sql_update = f"update us_self_asin_compet_temu_copy1 set state={state} where asin_compet in ('{asin_tuple[0]}') and state=2;"
                            else:
                                sql_update = f"update us_self_asin_compet_temu_copy1 set state={state} where asin_compet in {asin_tuple} and state=2;"
                            print(sql_update)
                            conn.execute(sql_update)
                    break
                except Exception as e:
                    print(e, '444444444444')
                    self.mysql_reconnect()
                    time.sleep(5)
                    continue

    def read_img_url(self):
        while True:
            try:
                with self.engine.begin() as conn:
                    sql_read = f"SELECT asin_compet,img_url,id  FROM us_self_asin_compet_temu_copy1 where state=1 LIMIT 100 FOR UPDATE"
                    print(sql_read)
                    a = conn.execute(sql_read)
                    self.df_read = pd.DataFrame(a, columns=['asin_compet', 'img_url', 'id'])
                    self.df_read.drop_duplicates(['asin_compet'], inplace=True)
                    if self.df_read.shape[0] == 0:
                        return []
                    index_tuple = tuple(self.df_read['asin_compet'])
                    print('更改状态 2 ', len(index_tuple))
                    if len(index_tuple) == 1:
                        sql_update = f"""UPDATE us_self_asin_compet_temu_copy1 a set state=2 where a.asin_compet in ('{index_tuple[0]}')"""
                    else:
                        sql_update = f"""UPDATE us_self_asin_compet_temu_copy1 a set state=2 where a.asin_compet in {index_tuple}"""
                    conn.execute(sql_update)
                    asin_img_list = list(
                        self.df_read.asin_compet + '|-|' + self.df_read.img_url)
                    # print(asin_img_list)
                    return asin_img_list
            except Exception as e:
                print("读取数据出bug并等待5s继续", e)
                self.mysql_reconnect()
                time.sleep(3)
                continue
    # 函数执行时间
    @func_set_timeout(15)
    def to_server_img(self, local_file_path, file_name):
        print('上传图片')
        current_time = datetime.now()
        # 格式化时间为 'YYYYMMDDHH' 格式
        formatted_time = current_time.strftime('%Y%m%d%H')
        # 目标位置
        remote_file_path = f"/vps_ftp/temu/{formatted_time}/"
        try:
            # 自动创建目标目录和其上级目录
            try:
                self.sftp.chdir(remote_file_path)  # 尝试切换到目标目录，如果目录不存在，会引发异常
            except IOError:
                self.sftp.mkdir(remote_file_path)  # 创建目标目录
                self.sftp.chdir(remote_file_path)  # 切换到目标目录
            # 上传本地文件到远程服务器
            remote_file_path = f"/vps_ftp/temu/{formatted_time}/{file_name}"
            print('服务器目录：', remote_file_path)
            print('本地目录：', local_file_path)
            # 上传本地文件到远程服务器
            self.sftp.put(local_file_path, remote_file_path)
            self.delete_img_path(local_file_path)
        except (paramiko.SSHException, OSError) as e:
            print(f"Error uploading file: {e}")

    def run(self):
        while True:
            self.ssh_connect()
            asin_img_list = self.read_img_url()
            if asin_img_list:
                for asin_img in asin_img_list:
                    self.asin_img_queue.put(asin_img)
                html_thread = []
                for i in range(1):
                    thread2 = threading.Thread(target=self.downlad_img)
                    html_thread.append(thread2)
                for ti in html_thread:
                    ti.start()
                for t2 in html_thread:
                    t2.join()
                self.mysql_reconnect()
                if self.asin_state_list:
                    while True:
                        try:
                            self.update_asin_state(state=3, asin_list=self.asin_state_list)
                            break
                        except FunctionTimedOut as e:
                            self.mysql_reconnect()
                            print('断网', e)
                    self.asin_state_list = []
                if self.asin_not_find:
                    while True:
                        try:
                            self.update_asin_state(state=1, asin_list=self.asin_not_find)
                            break
                        except FunctionTimedOut as e:
                            self.mysql_reconnect()
                            print('断网', e)
                    self.asin_not_find = []
                if self.asin_imgurl_null:
                    while True:
                        try:
                            self.update_asin_state(state=5, asin_list=self.asin_imgurl_null)
                            break
                        except FunctionTimedOut as e:
                            self.mysql_reconnect()
                            print('断网', e)
                    self.asin_imgurl_null = []
            else:
                break


if __name__ == '__main__':
    Amazon_Img('us').run()
