import json
import random
import time
import traceback
from json import JSONDecodeError
from urllib.parse import urlencode

import requests
from django.db.models import Avg, F
from django.utils import timezone

from accounts.models import FifaAccount
from sbc.models import SBCWorker
from sbc.public_methods import delete_sold_items, set_sub_log, \
    sell_items, set_sbc_status, get_trade_pile, get_next_price_grade, get_previous_price_grade, get_watchlist, \
    put_item_for_sale, clear_outbid
from accounts.web_login_utils import logout_login
from sbc.sbc_solver import SBCSolver
from trade.models import WebTradeHistory, WebTradeInfo, WebTradeQuality
from utils.ea_settings import fifa_23_address
from utils.realy_public_methods import new_print
from utils.tools import select_platform


class WebTradeRunner(SBCSolver):
    def __init__(self, fifa_account: FifaAccount):
        self.fifa_account = fifa_account
        # self.sbc_worker = SBCWorker.objects.filter(
        #     fifa_account=fifa_account, must_done=False, has_error=False
        # ).last()
        # if not self.sbc_worker:
        self.sbc_worker = SBCWorker.objects.create(fifa_account=fifa_account, is_done=True)
        self.running_platform = 'web'

        self.username = fifa_account.user_name
        self.password = fifa_account.password
        self.platform = fifa_account.platform
        self.manual_loyal = False
        fifa_backup = self.fifa_account.account_backup_code.first()
        self.backup_code = fifa_backup.backup_code
        self.app_auth = fifa_backup.app_code

        self.need_contracts = 0
        self.manager_need_contracts = 0
        self.need_heals = 0
        self.need_position_change = 0
        self.need_players_for_special_squad = []
        self.first_list = True
        self.all_sbc_completed = False
        self.can_get_help_for_discharge = False
        self.need_to_complete_first_sbcs = True
        self.max_delete_club_checked = False
        self.need_play_for_account = False
        self.cant_set_active_squad = False
        self.now_time = timezone.localtime()
        self.main_dic = {}
        self.main_dic.update({
            'first_buy': 0, 'first_sold': 0, 'check_bug': 0,
            'start_time': timezone.localtime(),
            'temp_bid': 0,
            'temp_buy': 0, 'first_check': 0, 'soft_ban_counter': 0, 'bid_controller_count': 0,
            'bid_controller_time': timezone.localtime(),
            'bid_controller_report': 0, 'win_controller_count': 0, 'target_controller_count': 0,
            'weak_target_controller_count': 0,
            'captcha_start_time': '', 'captcha_end_time': '', 'loop_controller_count': 0,
            'temperory_not_bid': 0,
            'bug_count': 0,
            'fixed_bug_count': 0, 'driver': '', 'search_min_time': 0, 'search_max_time': 0,
            'transfer_list_len': 0,
            'transfer_more_than_limit': 0,
            'number_of_searchs': 0, 'temp_number_of_searchs': 0, 'reporter_time': timezone.localtime(),
            'temp_bid_controller': 0,
            'temp_win_controller': 0, 'remaining_buys': 0, 'invest_id': 0, 'invest_sell_check': 0,
            'sleep_time': 0,
            'check_proxy': 0,
            'first_xi': 0, 'puzzle_master': 0, 'no_xi': 0, 'no_master': 0, 'empty_bid_handler': 0,
            'first_buy_items': 0, 'no_credit': 0,
            'no_good_pack': 0, 'begin_new_sid': timezone.localtime(),
            'end_new_sid': timezone.localtime() + timezone.timedelta(seconds=3),
            'third_sbc_problem': 0, 'last_sbc_failed': 0, 'proxy_ip': '', 'proxy_port': '',
            'new_sid_set': 0,
            'soft_ban_handler': 0, 'completed': 0
        })

        self.main_dic['control_bid_time'] = timezone.localtime()
        self.main_dic['control_bid_bid'] = 0
        self.fifa_account.refresh_from_db()
        self.account_id = fifa_account.id
        self.fifa_account.login_status = 0
        self.fifa_account.save()
        self.sbc_worker.last_run_time = timezone.localtime()
        self.sbc_worker.save()
        self.sbc_worker.refresh_from_db()

        self.useful_items = {
            'RW-RM': 5003066,
            'LW-LM': 5003065,
            'CM-CAM': 5003071,
            'CDM-CM': 5003073,
            'CM-CDM': 5003074,
            'CF-CAM': 5003076,
            'CF-ST': 5003077,
            'ST-CF': 5003078,
            'CAM-CM': 5003072,
            'HAWK': 5003100,
            'ENGINE': 5003105,
            'ANCHOR': 5003110,
            'HUNTER': 5003111,
            'SHADOW': 5003113,
            'GK-BASIC': 5003118,
            'POSITION-MODIFIER': 5003181,
        }

        self.can_send_telegram = True

        self.se = requests.Session()
        self.se2 = requests.session() # not using but need in logout_login
        self.se_header = {}

        self.fifa_account = fifa_account
        self.web_driver = None
        self.proxy_ip = None
        self.proxy_port = None
        self.proxy_user = None
        self.proxy_pass = None
        self.web_trade_info = WebTradeInfo.objects.get(fifa_account=fifa_account)
        self.server_key = None
        self.platform_key = select_platform[self.platform]['platform_key']
        self.account_current_credit = self.fifa_account.credit

    def web_trade_bot_core(self):
        self.sbc_worker.status = 'preparing ...'
        self.sbc_worker.last_run_time = timezone.localtime()
        self.sbc_worker.save()
        new_print(self.fifa_account, '## ' * 100, '\nTrade Web Bot started', '\n sbc worker id : ', self.sbc_worker.id)

        try:
            self.trade_history = WebTradeHistory.objects.filter(web_trade_info=self.web_trade_info).last()
            if not self.trade_history or self.trade_history.end_time:
                self.trade_history = WebTradeHistory.objects.create(web_trade_info=self.web_trade_info)
            # else:
            #     self.trade_history = WebTradeHistory.objects.filter(web_trade_info=self.web_trade_info).last()
            self.trade_history.update_time = timezone.localtime()
            self.trade_history.save()
            login_called = False
            # logout_login(self, self.sbc_worker, self.fifa_account)
            if self.web_trade_info.is_running_trade is False:
                if login_called is False:
                    logout_login(self, self.sbc_worker, self.fifa_account)
                    login_called = True
                set_sub_log(self.sbc_worker, 'web_sell_items start')
                for nnn in range(5):
                    try:
                        sell_items(self, self.sbc_worker, self.fifa_account)
                        break
                    except:
                        new_print(self.fifa_account, 'exception on sell items , ', traceback.format_exc())
                        logout_login(self, self.sbc_worker, self.fifa_account)
                    if nnn > 3:
                        raise Exception(traceback.format_exc())
                set_sub_log(self.sbc_worker, 'web_sell_items end')
                if self.web_check_transfer_list_empty() != 'transfer list empty':
                    new_print(self.fifa_account, 'transfer list not empty , sleep 2 minute')
                    time.sleep(120)
                    raise Exception('transfer list not empty , try next round')
            self.sbc_worker.refresh_from_db()
            if self.sbc_worker.must_done:
                raise Exception('SBC Worker Must Done')
            if self.web_trade_info.quality_name:
                trade_quality = WebTradeQuality.objects.filter(
                    name=self.web_trade_info.quality_name
                ).last()
                if not trade_quality:
                    raise Exception('Quality not Fount : ', self.web_trade_info.quality_name)
            else:
                raise Exception('Web Trade Info quality not set for fifa account')
            search_count_1 = self.web_trade_info.fifa_account.account_search.filter(
                search_time__gt=timezone.localtime() - timezone.timedelta(hours=24)).count()

            # if search_count_1 > 50:
            #     new_print(self.fifa_account, 'more than 50 search , current : ', search_count_1)
            #     time.sleep(1)
            #     raise Exception('Account High Search , more than 50 search , current : ', search_count_1)
            if (trade_quality and trade_quality.auto_next_create and
                    trade_quality.create_time < (timezone.localtime() - timezone.timedelta(minutes=30))):
                if login_called is False:
                    logout_login(self, self.sbc_worker, self.fifa_account)
                    login_called = True
                set_sbc_status(self.sbc_worker, 'Web Trade One Get Price')
                if trade_quality.bid_price <= 250:
                    zero_price = 150
                else:
                    zero_price = get_previous_price_grade(get_previous_price_grade(trade_quality.zero_price))
                sell_price, bid_price = self.extract_sell_bid_price(
                    quality=trade_quality,
                    zero_price=zero_price
                )
                last_trade_quality = WebTradeQuality.objects.filter(name=self.web_trade_info.quality_name).last()
                if (
                        last_trade_quality and
                        last_trade_quality.auto_next_create and
                        last_trade_quality.create_time < (timezone.localtime() - timezone.timedelta(minutes=30))
                ):
                    dynamic_upper_price = False
                    if last_trade_quality:
                        if last_trade_quality.dynamic_upper_price:
                            dynamic_upper_price = True
                        win_histories = WebTradeHistory.objects.filter(
                            move_items_from_unassigned__gt=timezone.localtime() - timezone.timedelta(hours=1),
                            quality_name=last_trade_quality.name
                        ).exclude(bid_count__lt=10).annotate(
                            win_rate=(F('win_count') * 100 / F('bid_count'))
                        )
                        if win_histories.count() >= 2:
                            win_rate = win_histories.aggregate(win_rate_avg=Avg('win_rate')).get('win_rate_avg')
                            if win_rate > 47:
                                dynamic_upper_price = False
                            elif win_rate < 20:
                                dynamic_upper_price = True
                    if dynamic_upper_price and bid_price:
                        bid_price = get_next_price_grade(bid_price)
                        sell_price = get_next_price_grade(sell_price)
                    trade_quality = WebTradeQuality.objects.create(
                        name=last_trade_quality.name,
                        player_quality=last_trade_quality.player_quality,
                        consumable_quality=last_trade_quality.consumable_quality,
                        zero_price=last_trade_quality.zero_price,
                        bid_price=get_previous_price_grade(get_previous_price_grade(bid_price)),
                        sell_price=get_next_price_grade(get_next_price_grade(sell_price)),
                        sell_next_grades=last_trade_quality.sell_next_grades,
                        auto_next_create=True,
                        dynamic_upper_price=dynamic_upper_price,
                    )
            self.trade_history.refresh_from_db()
            self.trade_history.quality_name = trade_quality.name
            self.trade_history.bid_price = trade_quality.bid_price
            self.trade_history.sell_price = trade_quality.sell_price
            self.trade_history.save()
            self.sbc_worker.refresh_from_db()
            self.sbc_worker.refresh_from_db()
            if self.sbc_worker.must_done:
                raise Exception('SBC Worker Must Done')
            # for iii in range(4):
            if True:
                self.sbc_worker.refresh_from_db()
                if self.sbc_worker.must_done:
                    raise Exception('SBC Worker Must Done')
                if self.web_trade_info.run_trade and (
                        # self.web_trade_info.is_running_trade is False or
                        self.trade_history.bid_count < 150
                ):
                    if login_called is False:
                        logout_login(self, self.sbc_worker, self.fifa_account)
                        login_called = True
                    set_sbc_status(self.sbc_worker, 'Console Trade One bidding mode')
                    set_sub_log(self.sbc_worker, 'Console Trade One bidding mode start...')
                    new_print(self.fifa_account, 'bidding mode')
                    if trade_quality.bid_price <= 0:
                        new_print(self.fifa_account, 'can`t bid on price 0')
                        set_sub_log(self.sbc_worker, 'Console Trade One bidding mode end. bid price zero')
                    else:
                        if self.trade_history.credit_before == 0:
                            self.trade_history.refresh_from_db()
                            self.trade_history.credit_before = self.fifa_account.credit
                            self.trade_history.save()
                        self.web_trade_info.is_running_trade = True
                        self.web_trade_info.save()
                        # for tt in range(3):
                        tt = 0
                        while self.trade_history.bid_count < 150:
                            tt += 1
                            set_sub_log(self.sbc_worker, f'Web Trade bidding mode round {tt}')
                            set_sbc_status(self.sbc_worker, f'Web Trade bidding round {tt}')
                            new_print(self.fifa_account, f'Web Trade bidding round {tt}')
                            # self.update_credit()
                            bid_count = 150 - self.trade_history.bid_count
                            if bid_count > 49:
                                bid_count = 49
                            self.bided_count = 0
                            bidding_mode_result = self.biding_mode(
                                bid_price=trade_quality.bid_price,
                                bid_count=bid_count,
                                quality=trade_quality)
                            self.trade_history.refresh_from_db()
                            self.trade_history.bid_count += self.bided_count
                            self.trade_history.update_time = timezone.localtime()
                            self.trade_history.save()
                            self.manage_transfer_targets()
                            set_sub_log(self.sbc_worker, 'manage unassign_bought_items end')
                            if bidding_mode_result == 'low credit':
                                try:
                                    self.update_credit()
                                    time.sleep(2)
                                except:
                                    new_print(self.fifa_account, 'error on update credit :', traceback.format_exc())
                                self.fifa_account.refresh_from_db()
                                self.account_current_credit = self.fifa_account.credit
                                if self.fifa_account.credit < (trade_quality.bid_price) * 2:
                                    new_print(self.fifa_account, 'low credit step 2')
                                    break
                            if bidding_mode_result == 'high search':
                                new_print(self.fifa_account, 'bidding result : high search')
                                break
                            if bidding_mode_result == 'watchlist full':
                                self.manage_transfer_targets()
                        try:
                            self.update_credit()
                            time.sleep(2)
                        except:
                            new_print(self.fifa_account, 'error on update credit :', traceback.format_exc())
                        self.manage_transfer_targets()
                        set_sub_log(self.sbc_worker, 'Web Trade bidding mode end')
                        new_print(self.fifa_account, 'Web Trade bidding mode end')
                if self.web_trade_info.is_running_trade and (
                        not self.trade_history.last_list_items_time or
                        self.trade_history.last_list_items_time < timezone.localtime() - timezone.timedelta(hours=3)
                ):
                    if login_called is False:
                        logout_login(self, self.sbc_worker, self.fifa_account)
                        login_called = True
                    set_sub_log(self.sbc_worker, 'Web trade one selling mode start...')
                    set_sbc_status(self.sbc_worker, 'Web Trade One selling mode')
                    new_print(self.fifa_account, 'Web Trade selling mode')

                    bought_item_result = self.manage_transfer_targets()
                    set_sub_log(self.sbc_worker, 'manage_transfer_targets end')
                    selling_mode_price = trade_quality.sell_price
                    for diff_num in range(self.trade_history.list_try_count if
                                          self.trade_history.list_try_count < trade_quality.sell_previous_grades else
                                          trade_quality.sell_previous_grades):
                        selling_mode_price = get_previous_price_grade(selling_mode_price)
                    # for diff_num in range(trade_quality.sell_next_grades - self.trade_history.list_try_count):
                    #     selling_mode_price = get_next_price_grade(get_next_price_grade(selling_mode_price))
                    new_print(self.fifa_account, f'sell with next grades , price : {selling_mode_price}')
                    selling_mode_result = self.selling_mode(
                        sell_price=selling_mode_price,
                        quality=trade_quality.name)
                    if bought_item_result == 'transfer list and unassigned empty':
                        new_print(self.fifa_account, 'after selling items , transfer list and unassigned empty')
                        self.web_trade_info.refresh_from_db()
                        self.web_trade_info.is_running_trade = False
                        self.web_trade_info.save()
                        self.trade_history.refresh_from_db()
                        self.trade_history.credit_after = self.fifa_account.credit
                        self.trade_history.end_time = timezone.localtime()
                        self.trade_history.save()
                        # break
                    # elif selling_mode_result == 'transfer list empty':
                    #     new_print(self.fifa_account, 'after selling items , transfer list empty')
                    #     self.web_trade_info.refresh_from_db()
                    #     self.web_trade_info.is_running_trade = False
                    #     self.web_trade_info.save()
                    #     self.trade_history.refresh_from_db()
                    #     self.trade_history.credit_after = self.fifa_account.credit
                    #     self.trade_history.end_time = timezone.localtime()
                    #     self.trade_history.save()
                    #     # break
                    else:
                        self.trade_history.refresh_from_db()
                        self.trade_history.list_try_count = self.trade_history.list_try_count + 1
                        self.trade_history.update_time = timezone.localtime()
                        self.trade_history.save()
                        set_sub_log(self.sbc_worker, 'console trade one selling mode end and not empty')
                        # break

            self.trade_history.refresh_from_db()
            self.trade_history.update_time = timezone.localtime()
            self.trade_history.save()
        except Exception as error:
            new_print(self.fifa_account, 'exception error 101 : ', traceback.format_exc())
            self.sbc_worker.refresh_from_db()
            self.sbc_worker.description = ''
            self.sbc_worker.description_editor = None
            self.sbc_worker.status = str('end web trade with exception')
            self.sbc_worker.status_change_time = timezone.localtime()
            self.sbc_worker.has_error = True
            self.sbc_worker.error_description = str(error)
            self.sbc_worker.save()
            time.sleep(10)
            new_print(self.fifa_account, 'end web trade with exception')
            return
        self.sbc_worker.refresh_from_db()
        self.sbc_worker.is_done = True
        self.sbc_worker.save()
        set_sbc_status(self.sbc_worker, 'Web Trade End')
        new_print(self.fifa_account, 'end web trade')

    def web_check_transfer_list_empty(self):
        delete_sold_items(self.se, self.se_header)
        try:
            self.update_credit()
            time.sleep(2)
        except:
            new_print(self.fifa_account, 'error on update credit :', traceback.format_exc())
        resp = get_trade_pile(self.fifa_account, self.se, self.main_dic)
        try:
            json_resp = resp.json()
            trades = json_resp['auctionInfo']
            if len(trades) < 1:
                return 'transfer list empty'
        except:
            new_print(self.fifa_account, 'exception in get trade pile : ', traceback.format_exc())

    def extract_sell_bid_price(self, quality: WebTradeQuality, zero_price=150, try_counter=0):
        if self.web_trade_info.fifa_account.account_search.filter(
                search_time__gt=timezone.localtime() - timezone.timedelta(hours=24)).count() > 50:
            raise Exception('Account High Search , more than 50 search , extract price')
        search_player_resp = self.custom_search_player(quality=quality, price=zero_price, search_type='max_buy')
        # print('search player resp : ', search_player_resp, search_player_resp.text)
        remaining_time = 60 * 60
        try:
            search_result_json = search_player_resp.json()
            if search_result_json.get('reason', '') == 'expired session':
                logout_login(self, self.sbc_worker, self.fifa_account)
            remaining_time = search_result_json['auctionInfo'][0]['expires']
        except:
            new_print(self.fifa_account, 'error on get first expire : ', traceback.format_exc())
        if remaining_time < 60 * 10:
            g_p_p = get_previous_price_grade
            return g_p_p(zero_price), g_p_p(g_p_p(g_p_p(zero_price)))
        return self.extract_sell_bid_price(quality=quality, zero_price=get_next_price_grade(zero_price),
                                           try_counter=try_counter)

    def manage_transfer_targets(self, try_counter=0):
        delete_sold_items(self.se, self.se_header)
        try:
            json_watchlist = get_watchlist(self.fifa_account, self.se, self.main_dic['options_header'],
                                           self.se_header).json()
        except:
            new_print(self.fifa_account, 'manage transfer targets error : ', traceback.format_exc())
            json_watchlist = {}
        if json_watchlist.get('reason', '') == 'expired session':
            if try_counter < 5:
                logout_login(self, self.sbc_worker, self.fifa_account)
                self.manage_transfer_targets(try_counter=try_counter + 1)
            else:
                raise Exception('can not login to account in trade bot')
        win_list = []
        if json_watchlist.get('auctionInfo'):
            watch_items = json_watchlist['auctionInfo']
        else:
            new_print(self.fifa_account, 'trade info wrong : ', json_watchlist)
            watch_items = []
        for watch_item in watch_items:
            if watch_item['tradeState'] == 'closed' and watch_item['bidState'] == 'highest':
                data = '{"itemData":[{"id":%s,"pile":"trade","tradeId":"%s"}]}' % (
                    watch_item['itemData']['id'], watch_item['tradeId'])
                # new_print(self.fifa_account, 'item send to trade pile : ', data)
                move_to_transfer_list_result = put_item_for_sale(self.se, self.se_header, data)
                try:
                    move_result = move_to_transfer_list_result.json().get('itemData', [{}])[0].get('success', False)
                    if move_result is True:
                        win_list.append(move_to_transfer_list_result.text)
                except:
                    pass
                time.sleep(1)
            elif watch_item['tradeState'] == 'closed' and watch_item['bidState'] == 'outbid':
                clear_outbid(self.fifa_account, self.se, self.se_header, watch_item['tradeId'])
        self.trade_history.refresh_from_db()
        self.trade_history.win_count += len(win_list)
        self.trade_history.move_items_from_unassigned = timezone.localtime()
        self.trade_history.save()
        trade_pile_items = get_trade_pile(self.fifa_account, self.se, self.main_dic).json()['auctionInfo']
        unassigned_items = self.get_items().json()['itemData']
        if len(unassigned_items) == 0 and len(trade_pile_items) == 0:
            return 'transfer list and unassigned empty'
        elif len(trade_pile_items) == 0:
            return 'transfer list empty'

    def biding_mode(self, bid_price, bid_count, quality: WebTradeQuality):
        bided_count = 0
        try_to_bid = 0
        higher_price_counter = 0
        remaining_time = False
        time.sleep(1)
        # missed_way_counter = 0
        last_remain_secs = 0
        num_search = 21
        start_search = num_search
        error_text = None
        while bided_count <= bid_count:
            self.sbc_worker.refresh_from_db()
            if self.sbc_worker.must_done:
                raise Exception('SBC Worker Must Done')
            if error_text:
                break
            current_search_count = self.fifa_account.account_search.filter(
                search_time__gt=timezone.localtime() - timezone.timedelta(hours=24)).count()
            if current_search_count > 50:
                # if last_remain_secs < 300:
                #     last_remain_secs = 300
                # new_print(self.fifa_account, 'search more than 50 , current : ', current_search_count,
                #           ' last remain secs : ', last_remain_secs)
                # set_sub_log(self.sbc_worker, f'high search last remain secs : {last_remain_secs}')
                # time.sleep(last_remain_secs)
                # return 'high search'
                new_print(self.fifa_account, 'search more than 50 , current : ', current_search_count)
                error_text = 'high search'
                break
            search_result = self.custom_search_player(
                quality=quality, search_type='max_bid', price=quality.bid_price, start=start_search
            )
            try:
                search_result = search_result.json()
            except JSONDecodeError:
                raise Exception('can not search player , maybe transfer ban')
            start_search += num_search
            if not search_result and search_result != 'sid':
                new_print(self.fifa_account, 'search result : sid')
                return
            try:
                search_result['auctionInfo']
            except:
                if search_result.get("reason", None) == "expired session":
                    new_print(self.fifa_account, 'session expired')
                    logout_login(self, self.sbc_worker, self.fifa_account)
                    continue
            for search_item in search_result['auctionInfo']:
                bid_item_result = self.bid_item(price=bid_price, item=search_item)
                time.sleep(2)
                try_to_bid += 1
                if try_to_bid % 50 == 0:
                    new_print(self.fifa_account, 'bidding mode , try to bid : ', try_to_bid)
                if last_remain_secs > 30 * 60:
                    new_print(self.fifa_account, 'last remain time more than 30 min : ',
                              last_remain_secs, ' try search again')
                    time.sleep(100)
                    return self.biding_mode(bid_price=bid_price, bid_count=bid_count - bided_count, quality=quality)
                # if not bid_item_result:
                #     new_print(self.fifa_account, 'missed way 2, try again')
                #     if self.public_moves.just_find_state():
                #         # print('ok i find state')
                #         return False
                #     missed_way_counter += 1
                #     if missed_way_counter > 5:
                #         return False
                #     continue
                # if bid_item_result == 'transfer expired':
                #     new_print(self.fifa_account, 'transfer expired')
                #     self.public_moves.ps4_buttons.r1()
                #     time.sleep(.5)
                # continue
                # elif bid_item_result == 'higher price':
                #     # print('higher price')
                #     # self.public_moves.ps4_buttons.circle()
                #     # time.sleep(.5)
                #     next_page_count = 6
                #     # higher_price_counter += 1
                #     # if higher_price_counter > 5:
                #     #     higher_price_counter = 0
                #     #     self.public_moves.ps4_buttons.r1()
                #     #     time.sleep(.5)
                #     # else:
                #     #     self.public_moves.ps4_buttons.right(sleep_after=.5)
                #     # continue
                # elif bid_item_result == 'already bided':
                #     next_page_count = 6
                if bid_item_result == 'low credit':
                    new_print(self.fifa_account, 'low credit , end of bidding mode')
                    # new_print(self.fifa_account, 'low credit , end of bidding mode',
                    #           ' last remain secs : ', last_remain_secs)
                    # set_sub_log(self.sbc_worker, f'low credit last remain secs : {last_remain_secs}')
                    # time.sleep(last_remain_secs)
                    error_text = 'low credit'
                    break
                elif bid_item_result == 'transfer error':
                    pass
                elif bid_item_result == 'watchlist full':
                    new_print(self.fifa_account, 'watchlist full')
                    error_text = 'watchlist full'
                    break
                elif bid_item_result is True:
                    bided_count += 1
                    self.bided_count += 1
                    time.sleep(1)
                if search_item['expires'] > last_remain_secs:
                    last_remain_secs = search_item['expires']
        if last_remain_secs < 300:
            last_remain_secs = 300
        new_print(self.fifa_account, 'last remain secs : ', last_remain_secs)
        set_sub_log(self.sbc_worker, f'last remain secs : {last_remain_secs}')
        time.sleep(last_remain_secs)
        return error_text

    def selling_mode(self, sell_price, quality=None):
        set_sub_log(self.sbc_worker, 'selling items in console start')
        sell_result = self.sell_transfer_list_items(buy_now_price=sell_price)
        set_sub_log(self.sbc_worker, 'selling items in console end')
        try:
            self.update_credit()
            time.sleep(2)
        except:
            new_print(self.fifa_account, 'error on update credit :', traceback.format_exc())
        if sell_result == 'transfer list empty':
            return 'transfer list empty'

    def sell_transfer_list_items(self, buy_now_price):
        new_print(self.fifa_account, 'searching transfer list items')
        transfer_list_items = get_trade_pile(self.fifa_account, self.se, self.main_dic).json()['auctionInfo']
        if transfer_list_items == []:
            return 'transfer list empty'
        for trade in transfer_list_items:
            item_id = trade['itemData']['id']
            asset_id = trade['itemData']['assetId']
            resource_id = trade['itemData'].get('resourceId', 0)
            last_sale_price = trade['itemData'].get('lastSalePrice', 0)
            if last_sale_price:
                data = '{"itemData":{"id":%s},"startingBid":%d,"duration":3600,"buyNowPrice":%d}' % (
                    item_id, get_previous_price_grade(buy_now_price), buy_now_price)
                sell_resp = self.put_item_in_auction_house(data)
                try:
                    if sell_resp.json().get("reason", None) == "expired session":
                        new_print(self.fifa_account, 'session expired')
                        logout_login(self, self.sbc_worker, self.fifa_account)
                except:
                    new_print(self.fifa_account, 'can not get put for sale data : ',
                              sell_resp.status_code, sell_resp.text)
                time.sleep(2)
            time.sleep(2)
        return True

    def custom_search_player(self, quality: WebTradeQuality, search_type='max_buy', price=150, start=0, num=21):
        if quality.player_quality:
            payload = {'start': start, 'num': num, 'type': 'player'}
            player_filter = quality.player_quality
            if player_filter.asset_id:
                payload.update({'maskedDefId': player_filter.asset_id})
            if player_filter.position:
                payload.update({'pos': player_filter.position})
            if player_filter.rarity_ids:
                payload.update({'rarityIds': player_filter.rarity_ids})
            if player_filter.level:
                payload.update({'lev': player_filter.level})
            if player_filter.nation:
                payload.update({'nat': player_filter.nation})
            if player_filter.team:
                payload.update({'team': player_filter.team})
            if player_filter.league:
                payload.update({'leag': player_filter.league})
            if player_filter.chemistry_style:
                payload.update({'playStyle': player_filter.chemistry_style})

            if search_type == 'max_buy':
                payload.update({'maxb': price})
            elif search_type == 'max_bid':
                payload.update({'macr': price})
                random_max_buy = 14000000 - (1000 * random.randint(1, 100))
                payload.update({'maxb': random_max_buy})
            player_link = f'{fifa_23_address}/transfermarket?' + str(urlencode(payload))
            search_player_resp = self.search_player(
                player_filter.asset_id, price, 'max_bid', link=player_link)
        elif quality.consumable_quality:
            payload = {'start': start, 'num': num, 'type': 'training'}
            consumable_filter = quality.consumable_quality
            if consumable_filter.category:
                payload.update({'cat': consumable_filter.category})
            if consumable_filter.level:
                payload.update({'lev': consumable_filter.level})

            if search_type == 'max_buy':
                payload.update({'maxb': price})
            elif search_type == 'max_bid':
                payload.update({'macr': price})
                random_max_buy = 14000000 - (1000 * random.randint(1, 100))
                payload.update({'maxb': random_max_buy})
            consumable_link = f'{fifa_23_address}/transfermarket?' + str(urlencode(payload))
            search_player_resp = self.search_player(1, price, 'max_bid', link=consumable_link)
        else:
            raise Exception('quality has no filter')
        return search_player_resp

    def bid_item(self, price, item):
        if self.account_current_credit < price:
            new_print(self.fifa_account, 'low credit : ', self.account_current_credit, ' , need : ', price)
            return 'low credit'
        try:
            check_resp = self.check_trade(item['tradeId'])
            check_resp_json = check_resp.json()
        except json.decoder.JSONDecodeError:
            return 'transfer error'
        # print(check_resp_json)
        if not check_resp_json.get('auctionInfo', None):
            return 'transfer error'
        if check_resp_json.get('auctionInfo') and check_resp_json['auctionInfo'][0]['tradeState'] == 'closed':
            # print('transfer expired')
            return 'transfer expired'
        current_bid_price = check_resp_json['auctionInfo'][0]['currentBid']
        if int(current_bid_price) >= int(price):
            # print('higher price')
            return 'higher price'
        data = '{"bid":%d}' % int(price)
        bid_resp = self.bid_trade(item['tradeId'], data)
        # print('bid trade resp : ', bid_resp)
        if (bid_resp.text.find('Permission Denied') != -1 or
                bid_resp.text == '' or
                bid_resp.text == 'You are not allowed to bid on this trade'):
            # print('already bided')
            return 'already bided'
        try:
            if bid_resp.text == 'Watchlist is full':
                return 'watchlist full'
            self.account_current_credit = bid_resp.json()['credits']
        except json.decoder.JSONDecodeError:
            new_print(self.fifa_account, 'error on getting credits : ', bid_resp.status_code, bid_resp.text)
            pass
        return True
