# -*- coding: UTF-8 -*-

import json
import datetime
import requests
from django.conf import settings
from rpc.decorators import bind_context, bind
from rpc.tool.dict_mixin import to_dict
from rpc.tool.datatables import DataTable
from rpc.tool.log_tool import exception_logger
from rpc.exceptions import RPCNotFoundException
from channel.models import Channel, Version, VersionToChannel, ChannelVendor
from ..datatables import VersionToChannelDT, ChannelDT
from ..queries.channelbuild import ChannelDQ, VersionChannelDQ, VersionDQ, ChannelVendorDQ
from hera.utils import model_edit, get_mail_instance
from hera.queries.choice_query import choice_query
from api.tool.user_tool import get_user_from_context


uri_pre = 'hera/channelbuild'


@bind_context(uri_pre + '/version_query')
def version_query(ctx, options):
    dqobj = VersionDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/version_datatable')
def version_datatable(ctx, req_data=None):
    dtobj = DataTable(Version)
    return dtobj.process(req_data)


@bind_context(uri_pre + '/channel_query')
def channel_query(ctx, options):
    dqobj = ChannelDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/channel_datatable')
def channel_datatable(ctx, req_data=None):
    dtobj = ChannelDT(Channel)
    return dtobj.process(req_data)


@bind_context(uri_pre + '/get_channels')
def channel_channels(ctx):
    return [channel.url_name for channel in Channel.objects.filter(pack=True)]


@bind_context(uri_pre+'/channel_get')
def channel_detail(ctx, channel_id, options=None):
    try:
        channel = Channel.objects.get(id=channel_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    channel_data = to_dict(channel, **options)
    return channel_data


@bind_context(uri_pre + '/channel_edit')
def channel_edit(ctx, channel_id=None, channel_info=None):
    if channel_info is None:
        return None
    if channel_info.get('vendor'):
        vendor = ChannelVendor(id=channel_info.get('vendor'))
        channel_info['vendor'] = vendor
    channel = model_edit(Channel, channel_id, channel_info)
    version = Version.objects.last()
    # 给数据组发请求
    if channel_id is None:
        data = [{
            'code': channel.url_name,
            'name': channel.name,
            'vendor_name': ChannelVendor.objects.get(id=channel.vendor_id).name,
            'platform': 'Android'
        }, ]

        url = 'http://62.234.191.59:8005/api/device_channel_vendor_mapping' if settings.DEBUG \
            else 'http://mars.igengmei.com/api/device_channel_vendor_mapping'
        try:
            res = requests.post(url=url, data={'data': json.dumps(data)}, timeout=3)
            if res.status_code == 200:
                pass  # 暂时不处理
        except requests.Timeout as e:
            exception_logger.info(str(e))
        except Exception as e:
            exception_logger.info(str(e))

    return {'channel_id': channel.id, 'version': version.version if version else ''}


@bind_context(uri_pre + '/versionchannel_query')
def versionchannle_query(ctx, options):
    dqobj = VersionChannelDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/versionchannel_datatable')
def versionchannel_datatable(ctx, req_data=None):
    dtobj = VersionToChannelDT(VersionToChannel)
    return dtobj.process(req_data)


@bind_context(uri_pre+'/versiontochannel_get')
def versiontochannel_detail(ctx, id, options=None):
    try:
        versiontochannel = VersionToChannel.objects.get(id=id)
    except:
        raise RPCNotFoundException
    versiontochannel_data = {
        'version': versiontochannel.version.version,
        'channel': versiontochannel.channel.url_name,
        'is_confirm': versiontochannel.version.is_confirm,
    }
    return versiontochannel_data


@bind_context(uri_pre+'/versiontochannel_release')
def versiontochannel_release(ctx, id):
    try:
        versiontochannel = VersionToChannel.objects.get(id=id)
    except:
        raise RPCNotFoundException
    versiontochannel.is_released = True
    versiontochannel.release_time = datetime.datetime.now()
    versiontochannel.save()
    versiontochannel.channel.released_version = versiontochannel.version.version
    versiontochannel.channel.save()


@bind_context(uri_pre + '/fetch_all_packed_channels')
def fetch_all_packed_channels(ctx, version_id):
    version = Version.objects.filter(id=version_id).first()
    if version is None:
        return []
    chns_packed = VersionToChannel.objects.filter(version=version, packed=True)
    data = [
        {
            'id': vtc.id,
            'version': vtc.version.version,
            'channel': vtc.channel.url_name,
            'is_released': vtc.is_released,
        } for vtc in chns_packed
    ]
    return data


@bind_context(uri_pre+'/version_get')
def version_detail(ctx, version_id, options=None):
    try:
        version = Version.objects.get(id=version_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    version_data = to_dict(version, **options)
    return version_data


@bind_context(uri_pre + '/version_edit')
def version_edit(ctx, version_id=None, version_info=None):
    if version_info is None:
        return None
    ver = version_info.get('version', '')
    if ver:
        ver_obj = Version.objects.filter(version=ver).first()
        if ver_obj:
            version_id = ver_obj
    version = model_edit(Version, version_id, version_info)
    return version.id


@bind_context(uri_pre + '/version_release_notify')
def version_release_notify(ctx, version, channels=None):
    user = get_user_from_context(ctx)
    mail_title = u'apk版本一键发布状态'
    mail_body = u'版本(%s)已经全部发布' % (version)
    channels_str = u''
    if channels is not None:
        if isinstance(channels, list):
            channels_str = u'\n发布的渠道有:\n%s' % ('\n'.join(channels))
        else:
            channels_str = u'\n发布的渠道有:\n%s' % (str(channels))
    mail_body += channels_str
    mail = get_mail_instance(mail_title, mail_body, [user.email])
    mail.send()


@bind(uri_pre + '/done')
def task_done(version=None, channel=None):
    version = Version.objects.get(version=version)
    channel = Channel.objects.get(url_name=channel)
    vs, _ = VersionToChannel.objects.get_or_create(version=version, channel=channel)
    vs.packed = True
    vs.packed_time = datetime.datetime.now()
    vs.save()


@bind_context(uri_pre + '/vendor_query')
def vendor_query(ctx, options):
    dqobj = ChannelVendorDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/vendor_choices')
def vendor_choices(ctx, q='', page=1, num=30, initial=None):
    page = int(page)
    num = int(num)

    query = choice_query(ChannelVendor, ['id', 'name'], 'id', q, initial)
    query = query.filter(is_online=True)

    total_count = 0
    start_pos = (page - 1) * num
    start_pos = start_pos if start_pos >= 0 else 0
    results = [
        {
            'id': obj.id,
            'text': u'{}:{}'.format(
                obj.id, obj.name,
            ),
        } for obj in query[start_pos: start_pos + num]]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}


@bind_context(uri_pre + '/vendor_get')
def vendor_detail(ctx, vendor_id, options=None):
    try:
        vendor = ChannelVendor.objects.get(id=vendor_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    vendor_data = to_dict(vendor, **options)
    return vendor_data


@bind_context(uri_pre + '/vendor_edit')
def vendor_edit(ctx, vendor_id=None, vendor_info=None):
    if vendor_info is None:
        return None
    vendor = model_edit(ChannelVendor, vendor_id, vendor_info)
    return {'id': vendor.id}


@bind_context(uri_pre + '/version_confirm')
def version_confirm(ctx, version_id=None, is_confirm=False):
    if version_id is None:
        return
    return Version.objects.filter(id=version_id).update(is_confirm=is_confirm)

@bind_context(uri_pre + '/get_is_confirm')
def get_is_confirm(ctx, version_id=None):
    version = Version.objects.filter(id=version_id)
    if version:
        return version.first().is_confirm
    return False