import django_tables2
import pyotp
from django.contrib.auth.models import User
from django.db.models import OuterRef, Count, Subquery, F, Case, When, IntegerField, Q
from django.utils import timezone
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
from django_tables2 import Table, LinkColumn, A, Column, BooleanColumn, TemplateColumn, DateTimeColumn
from rolepermissions.roles import get_user_roles

from accounts.consts import CREATE_OUTLOOK_TRANSLATE
from accounts.models import FifaAccount, FifaAccountLog, FifaAccountBackupCode, MuleAccounts, FifaProxy, PlayerCard, \
    Console, FifaAccountWorkError, OutlookCreateWorker, PCPowerCommand, ConsolePowerCommand
from sbc.models import SBCWorker
from sniper.models import SniperTradeItemLog
from utils.models import SystemLog
from utils.table_fields import CounterColumn, secondary_button, danger_button


class FifaAccountsTable(Table):
    user_name = TemplateColumn(
        verbose_name=_('User Name'),
        template_code='''
        <a href="{% url "fifa-account-update" pk=record.id %}">
        {{ record.user_name }}</a>''',
        order_by='discharge_state')
    logs = LinkColumn('fifa-account-log', text='LOG', verbose_name='--', args=[A('pk')],
                      attrs={'a': {'class': 'btn btn-info'}})
    app_code = Column(accessor='id', verbose_name='App Code')
    totp = Column(accessor='id', verbose_name='TOTP')
    console_name = Column(accessor='id', verbose_name='Console')
    any_desk_code = Column(accessor='id', verbose_name='AnyDesk')

    def render_app_code(self, value, record):
        return record.app_code if record.app_code else '---'

    def render_totp(self, value, record):
        app_code = record.app_code
        if app_code:
            try:
                return pyotp.TOTP(app_code).now()
            except Exception as error:
                return f'ERROR : {error}'
        return '---'

    def render_console_name(self, value, record):
        if record.console:
            return f'{record.name_in_console} - {record.console.name}'
        return f'{record.name_in_console} - 000'

    def render_any_desk_code(self, value, record):
        if record.pc:
            if record.pc.any_desk_code_2:
                return f'{record.pc.any_desk_code} - {record.pc.any_desk_code_2}'
            return record.pc.any_desk_code
        return '---'

    class Meta:
        template_name = "django_tables2/bootstrap.html"
        model = FifaAccount
        fields = ('user_name', 'password', 'platform', 'app_code', 'totp', 'console_name', 'any_desk_code', 'logs')
        attrs = {'class': 'table table-stripped'}


class FifaAccountLogsTable(Table):
    description = Column(attrs={'td': {'style': 'word-break: break-word;'}})
    log_time = DateTimeColumn(accessor='log_time', verbose_name='Time', format='Y/m/d H:i:s')

    class Meta:
        template_name = "django_tables2/bootstrap.html"
        model = FifaAccountLog
        fields = ('log_time', 'description')
        attrs = {'class': 'table table-stripped'}


class SystemLogsTable(Table):
    description = Column(attrs={'td': {'style': 'word-break: break-word;'}})

    class Meta:
        template_name = "django_tables2/bootstrap.html"
        model = SystemLog
        fields = ('log_time', 'description')
        attrs = {'class': 'table table-stripped'}


class AccountTable(django_tables2.Table):
    counter = CounterColumn()
    get_roles = Column(_('Roles'), accessor='id', orderable=False)
    is_active = BooleanColumn(_('Active'))
    # profile = default_button(_('Profile'), 'userprofile-detail', css_class='btn-green mdi-account', user_id=A('id'))
    _perm = secondary_button(_('Permission'), 'user-permission', css_class='mdi-key-change', user_id=A('id'), dim=True)

    def render_get_roles(self, value):
        roles = get_user_roles(User.objects.get(id=value))
        return ', '.join(
            force_str(role.verbose_name_short)
            for role in sorted(roles, key=lambda role: role.order)
        )

    class Meta:
        model = User
        fields = ('counter', 'username', 'is_active', 'last_login')
        sequence = ('counter', 'username', 'last_login', 'is_active', 'get_roles', '...')
        attrs = {'class': 'table table-striped'}


class MuleAccountsTable(Table):
    counter = CounterColumn()
    search_count = Column(accessor='fifa_account', verbose_name='Search Count')
    fifa_account = TemplateColumn(template_code='''
            <div class="btn-group">
              <a href="{% url "fifa-account-update" pk=record.fifa_account.id %}"
               class="btn btn-warning">admin</a>
              <a href="{% url "fifa-account-log" email=record.fifa_account.id %}" class="btn btn-info">log</a>
            </div>
            ''', verbose_name='Account')
    # fifa_account_log = LinkColumn('fifa-account-log', text='Log', verbose_name='--',
    #                               args=[A('fifa_account.id')], attrs={'a': {'class': 'btn btn-info'}})
    # fifa_account_admin = LinkColumn('admin:accounts_fifaaccount_change', args=[A('fifa_account.id')],
    #                                 verbose_name='Account', attrs={'a': {'class': 'btn btn-info'}}, text='admin')
    mule_account_admin = LinkColumn('admin:accounts_muleaccounts_change', args=[A('id')],
                                    verbose_name='Mule', attrs={'a': {'class': 'btn btn-info'}}, text='admin')

    error_description_text = Column(accessor='id', verbose_name='Error')
    trade_access = Column(accessor='fifa_account__trade_access', verbose_name='Access')
    last_used = DateTimeColumn(accessor='last_used', verbose_name='Last', format='Y/m/d H:i:s')
    archive = TemplateColumn(template_code='''
    <a href="{% url "archive-mule-account" %}?is_deleted=False&archive_mule_account_id={{ record.id }}" class="btn btn-danger">Archive</a>
            ''', verbose_name='Archive')

    def render_search_count(self, value):
        search_24_hour = value.account_search.filter(
            search_time__gt=timezone.localtime() - timezone.timedelta(hours=24)).count()
        search_48_hour = value.account_search.filter(
            search_time__gt=timezone.localtime() - timezone.timedelta(hours=48)).count()
        return f'{search_24_hour} - {search_48_hour}'

    def render_error_description_text(self, value, record):
        text = '---'
        if record.error_description:
            text = record.error_description
        if record.fifa_account.need_captcha:
            text += ' - need captcha'
        last_sbc_worker = SBCWorker.objects.filter(fifa_account=record.fifa_account).last()
        if last_sbc_worker and last_sbc_worker.has_error:
            text += f' -- {last_sbc_worker.error_description}'
        if record.is_disabled:
            text += ' - Account Disabled'
        return text

    class Meta:
        model = MuleAccounts
        fields = (
            'fifa_account.id', 'fifa_account.user_name', 'fifa_account.credit', 'error_description_text', 'investors',
            'in_use', 'archive'
        )
        sequence = ('counter', 'fifa_account', 'mule_account_admin', '...', 'in_use', 'archive')
        attrs = {'class': 'table table-stripped'}


class FifaProxyListTable(Table):
    counter = CounterColumn()
    delete_btn = danger_button(_('Delete'), 'delete-fifa-proxy', pk=A('id'))

    class Meta:
        model = FifaProxy
        fields = (
            'counter', 'ip_address', 'port', 'user_name', 'type_name', 'usage_count'
        )
        attrs = {'class': 'table table-stripped'}


class PlayerCardTable(django_tables2.Table):
    counter = CounterColumn()
    miss_count = Column(accessor='id', verbose_name='Sniper Miss Count')
    success_count = Column(accessor='id', verbose_name='Sniper Success Count')
    miss_rate = Column(accessor='id', verbose_name='Miss Rate')

    # profile = default_button(_('Profile'), 'userprofile-detail', css_class='btn-green mdi-account', user_id=A('id'))

    class Meta:
        model = PlayerCard
        fields = ('counter', 'asset_id', 'special_name',)
        sequence = ('counter', 'asset_id', 'special_name', 'miss_count', 'success_count', '...')
        attrs = {'class': 'table table-striped'}

    def render_miss_count(self, value):
        return SniperTradeItemLog.objects.filter(player_card_id=value, status=0).count()

    def render_success_count(self, value):
        return SniperTradeItemLog.objects.filter(player_card_id=value, status=1).count()

    def render_miss_rate(self, value):
        miss = SniperTradeItemLog.objects.filter(player_card_id=value, status=0).count()
        success = SniperTradeItemLog.objects.filter(player_card_id=value, status=1).count()
        if success > 0:
            return round(miss / success, ndigits=2)
        return 0

    def order_miss_count(self, queryset, is_descending):
        queryset = queryset.annotate(
            miss_count=Subquery(SniperTradeItemLog.objects.filter(
                player_card_id=OuterRef('pk'), status=0
            ).values('player_card').annotate(miss_count1=Count('pk')).values('miss_count1'),
                                output_field=IntegerField()),
        ).order_by(("-" if is_descending else "") + "miss_count")
        return (queryset, True)

    def order_success_count(self, queryset, is_descending):
        queryset = queryset.annotate(
            success_count=Subquery(SniperTradeItemLog.objects.filter(
                player_card_id=OuterRef('pk'), status=1
            ).values('player_card').annotate(success_count1=Count('pk')).values('success_count1'),
                                   output_field=IntegerField()),
        ).order_by(("-" if is_descending else "") + "success_count")
        return (queryset, True)

    def order_miss_rate(self, queryset, is_descending):
        queryset = queryset.annotate(
            miss_count=Subquery(SniperTradeItemLog.objects.filter(
                player_card_id=OuterRef('pk'), status=0
            ).values('player_card').annotate(miss_count1=Count('pk')).values('miss_count1'),
                                output_field=IntegerField()),
            success_count=Subquery(SniperTradeItemLog.objects.filter(
                player_card_id=OuterRef('pk'), status=1
            ).values('player_card').annotate(success_count1=Count('pk')).values('success_count1'),
                                   output_field=IntegerField()),
            miss_rate=Case(
                When(success_count__gt=0, then=F('miss_count') * 100 / F('success_count')),
                default=0,
                output_field=IntegerField()
            )

        ).order_by(("-" if is_descending else "") + "miss_rate")
        # queryset = queryset.annotate(
        #     length=Length("first_name")
        # ).order_by(("-" if is_descending else "") + "length")
        return (queryset, True)


class ConsoleTable(django_tables2.Table):
    counter = CounterColumn()
    # name = Column(accessor='name', verbose_name='Name')
    fifa_accounts = Column(accessor='fifaaccount_set', verbose_name='Fifa accounts id')
    trade_quality = Column(accessor='fifaaccount_set', verbose_name='Trade Quality')
    c_name = TemplateColumn(
        verbose_name=_('Name'),
        template_code='''<a href="{% url "console-update" pk=record.id %}">{{ record.name }}</a>''',
        order_by='name')

    console_trade_one = TemplateColumn(
        verbose_name=_('Trade One'),
        template_code='''
        <a href="{% url "action-console" %}?console_id={{record.id}}&action=trade_one_one&state={{record.trade_one_state}}"
         class="btn {% if record.trade_one_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.trade_one_text }}</a>''',
        order_by='trade_one_state')
    discharge = TemplateColumn(
        verbose_name=_('Discharge'),
        template_code='''
        <a href="{% url "action-console" %}?console_id={{record.id}}&action=discharge_one&state={{record.discharge_state}}"
         class="btn {% if record.discharge_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.discharge_text }}</a>''',
        order_by='discharge_state')
    squad = TemplateColumn(
        verbose_name=_('Squad'),
        template_code='''
        <a href="{% url "action-console" %}?console_id={{record.id}}&action=squad_one&state={{record.squad_state}}"
         class="btn {% if record.squad_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.squad_text }}</a>''',
        order_by='squad_state')

    sbc = TemplateColumn(
        verbose_name=_('SBC'),
        template_code='''
        <a href="{% url "action-console" %}?console_id={{record.id}}&action=sbc_one&state={{record.sbc_state}}"
         class="btn {% if record.sbc_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.sbc_text }}</a>''',
        order_by='sbc_state')
    is_active = TemplateColumn(
        verbose_name=_('Status'),
        template_code='''
        <a href="{% url "action-console" %}?console_id={{record.id}}&action=active_one&state={{record.active_state}}"
         class="btn {% if record.active_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.active_text }}</a>''',
        order_by='active_state')

    # is_active = warning_button('Deactive', 'action-console',
    #                            query={'console_id': A('id'), 'action': 'active_one', 'state': 'deactive'})

    def render_name(self, value, record):
        if record.fifa_key_is_home:
            return f'{value}*'
        return f'{value}'

    def render_fifa_accounts(self, value):
        return str(list(value.filter(
            Q(delete_console_reason=None) | Q(delete_console_reason=''),
        ).values_list('id', flat=True)))

    def render_trade_quality(self, value):
        return str(list(value.filter(
            Q(delete_console_reason=None) | Q(delete_console_reason=''),
        ).values('console_trade_one_quality').annotate(
            quality=Count('id')).order_by('quality').values_list('console_trade_one_quality', flat=True)))

    class Meta:
        model = Console
        fields = ('counter',)
        sequence = ('counter', 'c_name', '...')
        attrs = {'class': 'table table-striped'}


class ConsolesCommandPowerTable(django_tables2.Table):
    counter = CounterColumn()
    # name = Column(accessor='name', verbose_name='Name')
    c_name = TemplateColumn(
        verbose_name=_('Name'),
        template_code='''{{ record.console.name }}''',
        order_by='name')

    turn_on_command = TemplateColumn(
        verbose_name='-',
        template_code='''
        <a href="{% url "console-power-command-action" %}?console_id={{record.console.id}}&command=turn_on_one"
         class="btn btn-success">Turn On</a>''',
        orderable=False)

    shutdown_command = TemplateColumn(
        verbose_name='-',
        template_code='''
        <a href="{% url "console-power-command-action" %}?console_id={{record.console.id}}&command=shutdown_one"
         class="btn btn-success">ShutDown</a>''',
        orderable=False)

    def render_name(self, value, record):
        return f'{value}'

    class Meta:
        model = ConsolePowerCommand
        fields = ('counter', 'command_status', 'update_time', )
        sequence = ('counter', 'c_name', '...')
        attrs = {'class': 'table table-striped'}


class PCsCommandPowerTable(django_tables2.Table):
    counter = CounterColumn()
    # name = Column(accessor='name', verbose_name='Name')
    c_name = TemplateColumn(
        verbose_name=_('Name'),
        template_code='''{{ record.pc.name }}''',
        order_by='name')

    sleep_command = TemplateColumn(
        verbose_name='-',
        template_code='''
        <a href="{% url "pc-power-command-action" %}?pc_id={{record.id}}&command=sleep_one"
         class="btn btn-success">Sleep</a>''',
        orderable=False)

    shutdown_command = TemplateColumn(
        verbose_name='-',
        template_code='''
            <a href="{% url "pc-power-command-action" %}?pc_id={{record.id}}&command=shutdown_one"
             class="btn btn-success">Shutdown</a>''',
        orderable=False)

    class Meta:
        model = PCPowerCommand
        fields = ('counter', 'last_command', 'command_status', 'update_time')
        sequence = ('counter', 'c_name', 'last_command', 'command_status', 'update_time', '...')
        attrs = {'class': 'table table-striped'}


class PackItemTable(django_tables2.Table):
    counter = CounterColumn()
    pack_name = Column(accessor='pack_name', verbose_name='Pack Name')
    # pack_id = Column(accessor='pack_id', verbose_name='Pack Id')
    pack_id = TemplateColumn(
        verbose_name=_('Pack Id'),
        template_code='''
            <a href="https://futmind.com/pack/{{ record.pack_id }}">
            {{ record.pack_id }}</a>''',
        orderable=False)
    count_pack_id = Column(accessor='count_pack_id', verbose_name='Pack Count')
    sum_pack_id = Column(accessor='sum_pack_id', verbose_name='Sum Packs')
    count_pack_id_7_days = Column(accessor='count_pack_id_7_days', verbose_name='Count 7 days')
    sum_pack_id_7_days = Column(accessor='sum_pack_id_7_days', verbose_name='Sum 7 days')
    avg_pack_id = Column(accessor='avg_pack_id', verbose_name='AVG Packs')
    avg_pack_id_7_days = Column(accessor='avg_pack_id_7_days', verbose_name='AVG 7 days')
    count_pack_id_last_sbc_day = Column(accessor='count_pack_id_last_sbc_day', verbose_name='Last SBC Day')

    class Meta:
        fields = ('counter', 'pack_name', 'pack_id', 'count_pack_id', 'sum_pack_id', 'avg_pack_id',
                  'count_pack_id_7_days', 'sum_pack_id_7_days', 'avg_pack_id_7_days', 'count_pack_id_last_sbc_day')
        attrs = {'class': 'table table-striped'}


class SummaryTable(django_tables2.Table):
    class Meta:
        attrs = {'class': 'table table-striped hover'}
        empty_text = _('No data')

    title = Column(verbose_name=_('Title'), accessor='title', orderable=False)
    sum = Column(verbose_name=_('Cumulative'), accessor='sum', orderable=False,
                 attrs={'td': {'class': 'shrink text-right'}})


class FifaAccountWorkErrorListTable(django_tables2.Table):
    counter = CounterColumn()
    # logs = LinkColumn('fifa-account-worker-error-detail',
    #                   text='Detail', verbose_name='--', args=[A('fifa_account__pk')],
    #                   attrs={'a': {'class': 'btn btn-info'}})
    logs = TemplateColumn(
        verbose_name=_('Detail'),
        template_code='''
            <a href="{% url "fifa-account-worker-error-detail" pk=record.fifa_account.pk %}?solve_status_f=-"
             class="btn btn-info">Detail</a>''',
        order_by='solve_status')

    class Meta:
        model = FifaAccountWorkError
        fields = ('counter', 'create_time', 'fifa_account', 'fifa_account__console__name', 'error_text')
        attrs = {'class': 'table table-striped'}


class FifaAccountDetailWorkErrorListTable(django_tables2.Table):
    counter = CounterColumn()
    # logs = LinkColumn('fifa-account-worker-error-solve', text='X', verbose_name='--', args=[A('pk')],
    #                   attrs={'a': {'class': 'btn btn-danger'}})
    logs = TemplateColumn(
        verbose_name=_('Solve Status'),
        template_code='''
                <a href="{% url "fifa-account-worker-error-solve" pk=record.pk %}?solve_status_f=-"
                 class="btn {% if record.solve_status == 'solved' %}btn-success{% else %}btn-danger{% endif %}"
                 >{% if record.solve_status == 'solved' %}-{% else %}X{% endif %}</a>''',
        order_by='solve_status')

    class Meta:
        model = FifaAccountWorkError
        fields = ('counter', 'create_time', 'fifa_account', 'fifa_account__console__name', 'error_text')
        attrs = {'class': 'table table-striped'}


class OutlookCreateWorkerTable(Table):
    counter = CounterColumn()

    console_name = Column(accessor='outlook_account__console__name', verbose_name='Console')
    account_name = Column(accessor='outlook_account__user_name', verbose_name='Outlook')
    browser_name = Column(accessor='outlook_account__browser', verbose_name='Browser')
    pc = Column(accessor='pc_name', verbose_name='PC')
    in_this_status_time = Column(accessor='status_change_time', verbose_name='status_time')
    any_desk = Column(accessor='any_desk', verbose_name='AnyDesk')
    sys_logs = TemplateColumn('{% if record.log_worker_name %}<a href="{% url "system-logs" worker_name=record.log_worker_name %}" class="btn btn-info">log</a>{% endif %}', verbose_name='Log')
    has_error = TemplateColumn('<a href="{% url "create-outlook-has-error" pk=record.outlook_account.id %}" class="btn btn-danger">has error</a>', verbose_name='Error')

    def render_in_this_status_time(self, value):
        diff = int((timezone.localtime() - value).total_seconds() / 60)
        # print(diff)
        return str(diff) + ' mins'

    def render_status(self, value):
        return CREATE_OUTLOOK_TRANSLATE.get(value, value)

    # def render_console_name(self, value, record):
    #     if record.get('fifa_account') and record.get('fifa_account').run_console_invest_trade_one:
    #         return f'{value}*'
    #     return value

    class Meta:
        template_name = "django_tables2/bootstrap.html"
        model = OutlookCreateWorker
        fields = ('counter', 'pc', 'console_name', 'account_name', 'browser_name', 'status', 'in_this_status_time', 'any_desk')
        attrs = {'class': 'table table-stripped'}
        row_attrs = {
            "data-status": lambda record: "red" if (
                    record.status in ['wait to solve captcha', 'need reset modem']
                # ) else record['status_color'] if (
                #         record['status'] == 'resting ...'
            ) else ''
        }


class ConsoleAccountsActionTable(django_tables2.Table):
    counter = CounterColumn()
    c_name = TemplateColumn(
        verbose_name=_('Name'),
        template_code='''<a href="{% url "console-update" pk=record.id %}">{{ record.name }}</a>''',
        order_by='name')

    console_trade_one = TemplateColumn(
        verbose_name=_('Add Accounts'),
        template_code='''
        <a href="{% url "console-accounts-actions" %}?console_id={{record.id}}&action=add_accounts_one&state={{record.add_accounts_state}}"
         class="btn {% if record.add_accounts_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.add_accounts_text }}</a>''',
        order_by='add_accounts_state')
    discharge = TemplateColumn(
        verbose_name=_('Remove Accounts'),
        template_code='''
        <a href="{% url "console-accounts-actions" %}?console_id={{record.id}}&action=remove_accounts_one&state={{record.remove_accounts_state}}"
         class="btn {% if record.remove_accounts_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.remove_accounts_text }}</a>''',
        order_by='remove_accounts_state')
    squad = TemplateColumn(
        verbose_name=_('Stop After'),
        template_code='''
        <a href="{% url "console-accounts-actions" %}?console_id={{record.id}}&action=stop_after_one&state={{record.stop_after_state}}"
         class="btn {% if record.stop_after_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
        {{ record.stop_after_text }}</a>''',
        order_by='stop_after_state')
    check = TemplateColumn(
        verbose_name=_('Check Accounts'),
        template_code='''
            <a href="{% url "console-accounts-actions" %}?console_id={{record.id}}&action=check_accounts_one&state={{record.check_accounts_state}}"
             class="btn {% if record.check_accounts_state == 'active' %}btn-success{% else %}btn-danger{% endif %}">
            {{ record.check_accounts_text }}</a>''',
        order_by='check_accounts_state')

    class Meta:
        model = Console
        fields = ('counter',)
        sequence = ('counter', 'c_name', '...')
        attrs = {'class': 'table table-striped'}


class AddAccountsViewTable(django_tables2.Table):
    new_HEADERS = [
        'EA Email', 'EA Password', 'Platform', 'App Code', 'Console Name',
        'Name in Console', 'PC Name', 'PC AnyDesk Code', 'PC AnyDesk Code 2',
        'Delete Club Renewal', 'XBOX Password', 'Previous Console Name',
        'BackUp Code', 'XBOX Email'
    ]

    def __new__(cls, *args, **kwargs):
        for header in cls.new_HEADERS:
            field_name = header.replace(" ", "_")
            if not hasattr(cls, field_name):
                setattr(cls, field_name, django_tables2.Column(verbose_name=header))
        return super().__new__(cls)

    class Meta:
        model = FifaAccount
        fields = [header.replace(" ", "_") for header in [
            'EA Email', 'EA Password', 'Platform', 'App Code', 'Console Name',
            'Name in Console', 'PC Name', 'PC AnyDesk Code', 'PC AnyDesk Code 2',
            'Delete Club Renewal', 'XBOX Password', 'Previous Console Name',
            'BackUp Code', 'XBOX Email']]
        attrs = {'class': 'table table-striped'}
