import traceback

from django import forms
from django.contrib import admin, messages

# Register your models here.
from django.db.models import When, Case, Sum

from sbc.models import SBCType, SBCTarget, SBCWorker, SBCProcess, SBCProcessTarget, SBCOrder, SBCTargetFilter, \
    AccountCheckHealthyWorker, AccountCheckHealthyOrder, SBCSolverServerSideHandlerWorker, AccountSBCNeedPlayer, \
    SBCTargetFilterClubMoves, SBCTargetFilterNationMoves, SBCTargetFilterLeagueMoves, RareFlag, SBCSolvationModel, \
    SBCSolvationModelPlayers, SBCSolvationModelWorker, HourlyAccountSBCDoneHistory, SBCFileWorkTime, SBCFileWorkLog
from utils.realy_public_methods import new_print


class SBCTypeAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'sbc_number', 'priority', 'short_sbc_link', 'sbc_price', 'must_done',
                    'sbc_actual_price', 'father_number', 'console_can_use', 'filters_price']
    search_fields = ['id', 'name']
    actions = ['update_sbc']
    autocomplete_fields = ['checker_account']
    list_filter = ['must_done']
    fields = ['name', 'father_number', 'sbc_number', 'priority', 'sbc_link', 'sbc_special_link', 'must_done',
              'sbc_price', 'sbc_actual_price', 'console_can_use', 'can_pass', 'can_pass_on_error',
              'team_min_rate', 'repeatable', 'max_try_repeats_per_worker',
              'solvation_type', 'expire_time', 'open_packs',
              # read only fields
              'console_cant_use', 'submit_sbc', 'need_recheck', 'need_recheck_time', 'checker_account',
              'updating_price', 'update_time']
    readonly_fields = ['console_cant_use', 'submit_sbc', 'need_recheck', 'need_recheck_time', 'checker_account',
                       'updating_price', 'update_time']

    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            sum_filters_price=Sum('sbctarget__target_filter__buy_now_price')
        )

    @admin.action(description='Update SBC')
    def update_sbc(self, request, queryset):
        from sbc.futbin_tools import FutbinTools
        worker = SBCWorker.objects.first()
        fifa_account = worker.fifa_account
        for item in queryset:
            sbc_solver = FutbinTools(
                worker.id, fifa_account.id, fifa_account.user_name, fifa_account.password, fifa_account.platform,
                False, use_public_moves=False)
            sbc_solver.set_this_staff_to_pass_logout_login()
            try:
                duplicate_sbc_types = SBCType.objects.filter(sbc_number=item.sbc_number).exclude(must_done=2)
                if len(duplicate_sbc_types) > 1:
                    messages.add_message(
                        request, level=messages.INFO,
                        message=f"duplicate sbc type with sbc number {item.sbc_number} , will update last")
                result = sbc_solver.update_sbc_from_futbin(item, must_change=False)
                if result == 'updated':
                    messages.add_message(
                        request, level=messages.INFO,
                        message=f"updating sbc : {item} with number {item.sbc_number} {result},"
                                f" log in {sbc_solver.fifa_account}")
                else:
                    messages.add_message(request, level=messages.INFO,
                                         message=f"error in sbc check {sbc_solver.fifa_account} , {result}")
            except:
                new_print(sbc_solver.fifa_account, 'exception in update sbc 2 : ', traceback.format_exc())
                messages.add_message(request,
                                     level=messages.ERROR, message=f"error in sbc check {sbc_solver.fifa_account}")

    def filters_price(self, obj):
        return obj.sum_filters_price
        # a = SBCTarget.objects.filter(
        #     sbc_type=obj
        # ).annotate(
        #     # use_price=Case(
        #     #     When(sbc_target_tradable_type=1, then=0,
        #     #     default=0,
        #     #     output_field=IntegerField()
        #     # )
        # ).values_list('target_filter_id', flat=True)
        # b = SBCTargetFilter.objects.filter(id__in=list(a)).aggregate(Sum('buy_now_price')).get('buy_now_price__sum')
        # return b

    def short_sbc_link(self, obj):
        if obj.sbc_link:
            return obj.sbc_link[:10]
        return obj.sbc_link


class SBCSolvationModelForm(forms.ModelForm):
    class Meta:
        model = SBCSolvationModel
        fields = '__all__'

    def clean(self):
        cleaned_data = super().clean()
        use_preferred_position = cleaned_data.get('use_preferred_position')
        use_alternate_positions = cleaned_data.get('use_alternate_positions')
        if use_preferred_position is False and use_alternate_positions is False:
            self.add_error('use_preferred_position',
                           'both use_preferred_position and use_alternate_positions cant be False')
        if use_preferred_position is True and use_alternate_positions is True:
            self.add_error('use_preferred_position',
                           'both use_preferred_position and use_alternate_positions cant be True')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not kwargs.get('instance'):
            self.initial['excluded_rarity_ids'] = [
                RareFlag.objects.get(name='TEAM OF THE WEEK'),
                RareFlag.objects.get(name='TEAM OF THE SEASON'),
            ]


class SBCSolvationModelAdmin(admin.ModelAdmin):
    list_display = ['sbc_type', ]
    search_fields = ['id', 'sbc_type__name']
    autocomplete_fields = ['sbc_type', 'excluded_rarity_ids']
    fields = ['sbc_type',
              'update_link',
              'formation', 'num_players',
              'country', 'num_country', 'max_num_country', 'min_num_country', 'num_unique_country',
              'league', 'num_league', 'max_num_league', 'min_num_league', 'num_unique_league',
              'club', 'num_club', 'max_num_club', 'min_num_club', 'num_unique_club',
              'rarity_1', 'num_rarity_1', 'rarity_2', 'num_rarity_2',
              'group_rarity', 'num_group_rarity',
              'min_overall', 'num_min_overall',
              'squad_rating', 'chemistry', 'chem_per_player',
              'min_rating_players', 'max_rating_players',
              'excluded_rarity_ids', 'tradable_type', 'buy_player', 'buy_player_links',
              'players_in_position', 'fix_players', 'remove_players', 'minimize_max_cost', 'maximize_total_cost',
              'use_preferred_position', 'use_alternate_positions',
              'use_all_duplicates', 'use_at_least_half_duplicates', 'use_at_least_one_duplicate',
              'consider_as_rare',
              ]

    form = SBCSolvationModelForm

    actions = ['update_solvation']

    @admin.action(description='Update Solvation')
    def update_solvation(self, request, queryset):
        from sbc.futbin_tools import FutbinTools
        worker = SBCWorker.objects.first()
        fifa_account = worker.fifa_account
        for item in queryset:
            sbc_solver = FutbinTools(
                worker.id, fifa_account.id, fifa_account.user_name, fifa_account.password, fifa_account.platform,
                False, use_public_moves=False)
            sbc_solver.set_this_staff_to_pass_logout_login()
            try:
                duplicate_sbc_types = SBCSolvationModel.objects.filter(sbc_type=item.sbc_type)
                if len(duplicate_sbc_types) > 1:
                    messages.add_message(
                        request, level=messages.INFO,
                        message=f"duplicate sbc type with sbc number {item.sbc_type} , will update last")
                result = sbc_solver.update_solvation_from_futbin_link(item.update_link, item, fifa_account)
                if result == 'updated':
                    messages.add_message(
                        request, level=messages.INFO,
                        message=f"updating sbc : {item} with number {item.sbc_type.sbc_number} {result},"
                                f" log in {sbc_solver.fifa_account}")
                else:
                    messages.add_message(request, level=messages.INFO,
                                         message=f"error in sbc check {sbc_solver.fifa_account} , {result}")
            except:
                new_print(sbc_solver.fifa_account, 'exception in update sbc : ', traceback.format_exc())
                messages.add_message(request,
                                     level=messages.ERROR, message=f"error in sbc check {sbc_solver.fifa_account}")


class SBCSolvationModelPlayersAdmin(admin.ModelAdmin):
    list_display = ['sbc_type', 'fifa_account', 'asset_id', 'rating', 'rare', 'index_composition']
    search_fields = ['id', 'sbc_worker__fifa_account__user_name__icontains']
    autocomplete_fields = ['sbc_worker', 'sbc_type']

    def fifa_account(self, obj):
        if obj.sbc_worker:
            return obj.sbc_worker.fifa_account
        return '--'


class SBCSolvationModelWorkerAdmin(admin.ModelAdmin):
    list_display = ['create_time', 'fifa_account', 'solvation_model', 'is_complete', 'has_error']
    autocomplete_fields = ['fifa_account', 'solvation_model']
    search_fields = ['fifa_account__user_name__icontains', 'solvation_model__sbc_type__name__icontains']


class SBCTargetAdmin(admin.ModelAdmin):
    list_display = ['sbc_type', 'position', 'team', 'asset_id', 'price', 'pos', 'player', 'target_filter']
    list_filter = ['sbc_type']
    search_fields = ['id', 'name']
    autocomplete_fields = ['player', 'target_filter', 'sbc_type']


class SBCWorkerAdmin(admin.ModelAdmin):
    list_display = ['start_time', 'fifa_account', 'is_done', 'last_run_time', 'has_error', 'complete_number',
                    'first_xi', 'task_id']
    list_filter = ['is_done', 'has_error', 'must_done']
    actions = ['make_is_done']
    search_fields = ['fifa_account__console__name__iexact', 'fifa_account__user_name__icontains']
    autocomplete_fields = ['fifa_account']

    @admin.action(description='Set is done = 1')
    def make_is_done(self, request, queryset):
        queryset.update(is_done=True)


class SBCProcessAdmin(admin.ModelAdmin):
    autocomplete_fields = ['worker', 'sbc_type']
    list_display = ['worker', 'sbc_type', 'is_done', 'has_error']
    search_fields = ['id', 'worker__fifa_account__user_name__icontains']
    list_filter = ['is_done']
    actions = ['make_is_done']

    @admin.action(description='Set is done = 1')
    def make_is_done(self, request, queryset):
        queryset.update(is_done=True)


class SBCProcessTargetAdmin(admin.ModelAdmin):
    autocomplete_fields = ['sbc_process']
    list_display = ['sbc_process', 'club_id', 'position']


class SBCOrderAdmin(admin.ModelAdmin):
    list_display = ['creator', 'create_time', 'file_name', 'status']


class SBCTargetFilterForm(forms.ModelForm):
    class Meta:
        model = SBCTargetFilter
        fields = '__all__'

    def clean(self):
        cleaned_data = super().clean()
        min_rating = cleaned_data.get('min_rating') or 0
        max_rating = cleaned_data.get('max_rating') or 0
        if min_rating and max_rating < min_rating:
            self.add_error('max_rating', 'Max rating should be greater than min rating.')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not kwargs.get('instance'):
            self.initial['excluded_rarity_ids'] = [
                RareFlag.objects.get(name='TEAM OF THE WEEK'),
                RareFlag.objects.get(name='TEAM OF THE SEASON'),
            ]


class SBCTargetFilterAdmin(admin.ModelAdmin):
    list_display = ['id', 'level', 'rarity_ids', 'position', 'nation',
                    'league', 'team', 'buy_now_price', 'max_rating', 'min_rating']
    autocomplete_fields = ['excluded_rarity_ids']
    search_fields = ['id', ]

    form = SBCTargetFilterForm


class SBCTargetFilterNationMovesAdmin(admin.ModelAdmin):
    list_display = ['nation', 'move_right', 'move_down', 'move_r1']


class SBCTargetFilterLeagueMovesAdmin(admin.ModelAdmin):
    list_display = ['league', 'move_right', 'move_down', 'move_r1']


class SBCTargetFilterClubMovesAdmin(admin.ModelAdmin):
    list_display = ['team', 'league', 'move_right', 'move_down', 'move_r1']


class AccountCheckHealthyOrderAdmin(admin.ModelAdmin):
    list_display = ['create_time', 'file_name', 'status']


class AccountCheckHealthyWorkerAdmin(admin.ModelAdmin):
    list_display = ['create_time', 'fifa_account', 'is_done', 'has_error', 'current_coins', 'open_preview_gold_pack',
                    'sell_items', 'open_packs', 'create_club']
    search_fields = ['fifa_account__user_name']
    autocomplete_fields = ['fifa_account', 'sbc_worker']


class SBCSolverServerSideHandlerWorkerAdmin(admin.ModelAdmin):
    list_display = ['fifa_account', 'sbc_worker', 'status', 'is_done', 'has_error']
    search_fields = ['fifa_account__user_name']
    autocomplete_fields = ['fifa_account', 'sbc_worker']


class AccountSBCNeedPlayerAdmin(admin.ModelAdmin):
    list_display = ['fifa_account', 'sbc_target']
    search_fields = ['fifa_account__user_name']
    autocomplete_fields = ['fifa_account', 'sbc_target']


class RareFlagAdmin(admin.ModelAdmin):
    list_display = ['name', 'rare_id']
    search_fields = ['name__icontains']


class SBCFileWorkTimeAdmin(admin.ModelAdmin):
    search_fields = ['console__name__iexact']
    list_display = ['console', 'start_time', 'end_time']
    autocomplete_fields = ['console']
    list_filter = ['start_time']


class HourlyAccountSBCDoneHistoryAdmin(admin.ModelAdmin):
    list_display = ['done_count', 'account_done_count']


class SBCFileWorkLogAdmin(admin.ModelAdmin):
    search_fields = ['console__worker_pc__name__iexact']
    autocomplete_fields = ['console', 'fifa_account']
    list_display = ['console', 'work_type', 'work_status', 'work_accounts_count', 'start_time', 'end_time']
    list_filter = ['work_type', 'work_status']


admin.site.register(SBCType, SBCTypeAdmin)
admin.site.register(SBCSolvationModel, SBCSolvationModelAdmin)
admin.site.register(SBCSolvationModelPlayers, SBCSolvationModelPlayersAdmin)
admin.site.register(SBCSolvationModelWorker, SBCSolvationModelWorkerAdmin)
admin.site.register(SBCTarget, SBCTargetAdmin)
admin.site.register(SBCWorker, SBCWorkerAdmin)
admin.site.register(SBCProcess, SBCProcessAdmin)
admin.site.register(SBCProcessTarget, SBCProcessTargetAdmin)
admin.site.register(SBCOrder, SBCOrderAdmin)
admin.site.register(SBCTargetFilter, SBCTargetFilterAdmin)
admin.site.register(SBCTargetFilterNationMoves, SBCTargetFilterNationMovesAdmin)
admin.site.register(SBCTargetFilterLeagueMoves, SBCTargetFilterLeagueMovesAdmin)
admin.site.register(SBCTargetFilterClubMoves, SBCTargetFilterClubMovesAdmin)
admin.site.register(AccountCheckHealthyOrder, AccountCheckHealthyOrderAdmin)
admin.site.register(AccountCheckHealthyWorker, AccountCheckHealthyWorkerAdmin)
admin.site.register(SBCSolverServerSideHandlerWorker, SBCSolverServerSideHandlerWorkerAdmin)
admin.site.register(AccountSBCNeedPlayer, AccountSBCNeedPlayerAdmin)
admin.site.register(RareFlag, RareFlagAdmin)
admin.site.register(SBCFileWorkTime, SBCFileWorkTimeAdmin)
admin.site.register(HourlyAccountSBCDoneHistory, HourlyAccountSBCDoneHistoryAdmin)
admin.site.register(SBCFileWorkLog, SBCFileWorkLogAdmin)
