import datetime
import os
import threading
import time
import traceback

import django
from django.utils import timezone

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'futplus.settings')
django.setup()

from sbc.public_methods import get_next_price_grade
from accounts.web_login_utils import logout_login
from sbc.models import SBCWorker
from accounts.models import MuleAccounts, CloseWebAppSnipes
from sbc.sbc_solver import SBCSolver


def run_discharge_snipe(transfer: CloseWebAppSnipes):
    workers = []
    while len(workers) < 4:
        print('len(workers) = ', len(workers))
        worker = get_worker(transfer)
        if not worker:
            print('no worker found')
            time.sleep(120)
            continue
        worker.last_run_time = timezone.localtime()
        worker.must_done = False
        worker.save()
        worker.fifa_account.last_run_time = timezone.localtime()
        worker.fifa_account.save()

        fifa_account = worker.fifa_account
        # if not fifa_account.active:
        # if True:
        fifa_account.need_captcha = 0
        fifa_account.active = 1
        fifa_account.save()

        sbc_solver_item = SBCSolver(worker.id, fifa_account.id, fifa_account.user_name,
                                    fifa_account.password,
                                    fifa_account.platform, worker.manual_loyal)
        try:
            print(logout_login(sbc_solver_item, worker, fifa_account, ))
            print('after login')
        except Exception as e:
            traceback.print_exc()
            MuleAccounts.objects.filter(fifa_account=worker.fifa_account).update(in_use=False)
            continue
            # handle_end_bot()
        fifa_account.refresh_from_db()
        print('fifa_account.active', fifa_account.active)
        if not fifa_account.active:
            MuleAccounts.objects.filter(fifa_account=worker.fifa_account).update(in_use=False)
            continue
        if not sbc_solver_item.web_app_discharge_with_snipe_first:
            print('account first things failed')
            MuleAccounts.objects.filter(fifa_account=worker.fifa_account).update(in_use=False)
            continue
        workers.append(sbc_solver_item)
    all_accounts = ''
    for sbc_solver_item in workers:
        all_accounts += str(sbc_solver_item.fifa_account.id) + ' '
    transfer.refresh_from_db()
    transfer.all_accounts_ids = all_accounts
    transfer.second_side_ready = True
    transfer.save()
    while True:
        transfer.refresh_from_db()
        if transfer.first_side_done:
            break
        time.sleep(0.1)
    time.sleep(1.1)
    done = False
    count = 0
    thread_list = []
    while True:
        account_number = 0
        for sbc_solver_item in workers:
            transfer.refresh_from_db()
            if transfer.second_side_done or transfer.error:
                done = True
                break
            th = threading.Thread(target=sbc_solver_item.web_app_discharge_with_snipe, kwargs={
                'transfer': transfer, 'count': count, 'account_number': account_number})
            th.daemon = True
            th.start()
            thread_list.append(th)
            time.sleep(0.09)
            account_number += 1
        if done:
            break
        count += 1
        if count >= 4:
            break
        # if count > 2:
        #     time.sleep(3)
        # time.sleep(1)
        # break
    print('set accounts in_use to false')
    for sbc_solver_item in workers:
        MuleAccounts.objects.filter(fifa_account=sbc_solver_item.fifa_account).update(in_use=False)
        try:
            sbc_solver_item.main_dic['driver'].close()
        except:
            pass
    del workers
    print('transfer job is done ...')
    time.sleep(2)
    transfer.refresh_from_db()
    if not transfer.second_side_done:
        transfer.error = True
        transfer.error_desc = 'missed'
        transfer.save()
    for thread in thread_list:
        thread.join()
        del thread


def get_worker(transfer):
    print('need a worker')
    # buy_now_price = self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(
    #     self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(
    #         self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(self.get_next_price_grade(transfer.player_min_price_from_futbin)))))
    #     )))))
    # )))))
    # buy_now_price = get_previous_price_grade(get_previous_price_grade(
    #     get_previous_price_grade(transfer.player_price)))
    buy_now_price = get_next_price_grade(get_next_price_grade(get_next_price_grade(
        get_next_price_grade(get_next_price_grade(get_next_price_grade(transfer.player_min_price_from_futbin))))))

    accounts = MuleAccounts.objects.filter(fifa_account__credit__gt=buy_now_price, in_use=False,
                                           error=False).order_by(
        'last_used').all()
    for account in accounts:
        sbc_worker, created = SBCWorker.objects.get_or_create(
            fifa_account=account.fifa_account, running_platform='inject')
        sbc_worker.first_xi = True
        sbc_worker.puzzle_master = True
        sbc_worker.manual_loyal = True
        sbc_worker.save()
        if sbc_worker.has_error:
            account.error = True
            account.error_description = sbc_worker.error_description
            account.save()
        else:
            print('account = ', account.fifa_account.user_name, 'will participate in ', transfer.player_price)
            account.last_used = timezone.localtime()
            account.in_use = True
            account.save()
            print('worker id = ', sbc_worker.id)
            return sbc_worker


# main_thread_list = []
for i in range(27):
    transfer = CloseWebAppSnipes.objects.filter(error=False, first_side_ready=True,
                                                second_side_done=False, web_app_is_on_it=False).first()
    if transfer:
        transfer.web_app_is_on_it = True
        transfer.save()
        th = threading.Thread(target=run_discharge_snipe, kwargs={'transfer': transfer})
        th.daemon = True
        th.start()
        # main_thread_list.append([th,datetime.datetime.now()])

        # for i in range(len(main_thread_list)):
        #     if main_thread_list[i][1] < datetime.datetime.now() - datetime.timedelta(minutes=15):
        #         main_thread_list[i][0].join()
        #         del main_thread_list[i]
        #         break

        old_transfer = CloseWebAppSnipes.objects.filter(error=False, first_side_ready=True,
                                                        second_side_done=False, web_app_is_on_it=True,
                                                        id__lt=transfer.id - 100).first()
        if old_transfer:
            old_transfer.error = True
            old_transfer.first_side_done = True
            old_transfer.save()
    time.sleep(2)
    MuleAccounts.objects.filter(in_use=True,
                                last_used__lt=timezone.localtime() - datetime.timedelta(minutes=60)).update(
        in_use=False)

time.sleep(600)
