#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
__title__ = '各个平台的订单API接口'

@Time    : 2020/9/30 12:33
@Author  : Kenny-PC
@Software: PyCharm

# code is far away from bugs with the god animal protecting
    I love animals. They taste delicious.
              ┏┓      ┏┓
            ┏┛┻━━━┛┻┓
            ┃      ☃      ┃
            ┃  ┳┛  ┗┳  ┃
            ┃      ┻      ┃
            ┗━┓      ┏━┛
                ┃      ┗━━━┓
                ┃  神兽保佑    ┣┓
                ┃　永无BUG！   ┏┛
                ┗┓┓┏━┳┓┏┛
                  ┃┫┫  ┃┫┫
                  ┗┻┛  ┗┻┛
"""

import datetime
import hashlib
import math
import time
from concurrent.futures import ProcessPoolExecutor
from urllib import parse

import requests

from util import date_util
from util import platform_config_util
from util import robust_util


# md5加密，使用utf-8编码
def md5(s):
    md5 = hashlib.md5()
    md5.update(s.encode("utf-8"))
    return md5.hexdigest()


# 阅文
@robust_util.catch_exception
def get_yuewen_order(st, et):
    start_exec_seconds = date_util.getCurrentSecondTime()
    total_order_list = ()
    account_list = platform_config_util.get_yuewen_account_list()

    executor = ProcessPoolExecutor(max_workers=5)

    futures = []
    for account in account_list:
        future = executor.submit(get_yuewen_order_task, st, et, account)
        futures.append(future)

    executor.shutdown(True)

    for future in futures:
        order_list = future.result()
        if len(order_list) > 0:
            total_order_list = order_list + total_order_list

    print('阅文订单数量：', len(total_order_list), '执行时长（秒）：', date_util.getCurrentSecondTime() - start_exec_seconds)
    return total_order_list


def get_yuewen_order_task(st, et, account):
    order_list = ()

    email = account[0]
    appsecert = account[1]

    url = 'https://open.yuewen.com/cpapi/wxRecharge/querychargelog'
    version = 1
    order_status = 2  # 已支付
    page_count = 100  # 每页100条数据
    start_time = st

    for i in range((et - st) // 86400 + 1):
        page = 1
        last_min_id = ''
        last_max_id = ''
        total_count = ''
        last_page = ''

        while True:
            if start_time == et:
                break

            end_time = min(start_time + 86400, et)
            timestamp = int(time.time())

            params = {
                'email': email,
                'version': version,
                'timestamp': timestamp,
                'start_time': start_time,
                'end_time': end_time,
                'page': page,
                'order_status': order_status
            }

            if page > 1:
                params['last_min_id'] = last_min_id
                params['last_max_id'] = last_max_id
                params['total_count'] = total_count
                params['last_page'] = last_page

            sorted_data = sorted(params.items())
            str_params = ''
            for k, v in sorted_data:
                str_params = str_params + str(k) + str(v)

            sign = md5(appsecert + str_params).upper()

            # 放入签名
            params['sign'] = sign
            response_result_json = requests.get(url=url, params=params).json()

            code = response_result_json['code']
            ## 此接口有调用频率限制，相同查询条件每分钟仅能请求一次
            if code != 0:
                print('阅文查询充值接口异常：', response_result_json, '参数', params)
                break
                # if code == 10408:
                #     if fail_count > 0:
                #         break
                #
                #     sleep_seconds = random.randint(60, 70)
                #     print('阅文获取订单数据线程休眠【{sleep_seconds}】秒，因为该接口有一分钟的限制'.format(sleep_seconds=sleep_seconds))
                #     time.sleep(sleep_seconds)
                #
                #     print('重试一次')
                #     fail_count = fail_count + 1
                #     get_yuewen_order_task(st, et, account, fail_count)

            response_data = response_result_json['data']
            total_count = response_data['total_count']

            if total_count == 0:
                continue

            last_min_id = response_data['min_id']
            last_max_id = response_data['max_id']
            last_page = response_data['page']
            order_item_list = response_data['list']

            for order_item in order_item_list:
                order_time = order_item['order_time']
                dtime = datetime.datetime.strptime(order_time, "%Y-%m-%d %H:%M:%S")
                order_time_unix = int(time.mktime(dtime.timetuple()))
                order_id = order_item['order_id']
                if date_util.checkInterval(start_time, end_time, order_time_unix) == False:
                    print('阅文账号【{key}】，查询时间【{start_time} - {end_time}】，有不符合该时间范围的订单，订单Id【{order_id}】的时间为【{order_time}】'
                          .format(key=email, start_time=date_util.getSecondsToDatetime(start_time),
                                  end_time=date_util.getSecondsToDatetime(end_time), order_id=order_id,
                                  order_time=order_time))
                    # continue

                order = {}
                order['date'] = ((order_time_unix + 8 * 3600) // 86400) * 86400 - 8 * 3600
                order['platform'] = '阅文'
                order['channel'] = order_item['app_name']
                order['from_novel'] = order_item['book_name']
                order['user_id'] = order_item['openid']
                order['stage'] = ''
                order['channel_id'] = 0
                order['order_time'] = order_time
                order['amount'] = order_item['amount']
                order['reg_time'] = order_item['reg_time']
                order['order_id'] = order_id

                order = sorted(order.items(), key=lambda item: item[0])
                order = dict(order)
                order = tuple(order.values())
                order_list = order_list + ((order),)

            # print('阅文账号【{key}】, 查询时间【{start_time} - {end_time}】，当前页【{page}】，本次查询订单数量【{total_count}】'
            #       .format(key=email, start_time=date_util.getSecondsToDatetime(start_time),
            #               end_time=date_util.getSecondsToDatetime(end_time),page=page, total_count=total_count))

            if int(page) >= math.ceil(total_count / int(page_count)):
                break

            page = page + 1

        start_time = start_time + 86400  # 天数加1

        # sleep_seconds = random.randint(60, 70)
        # print('阅文获取订单数据线程休眠【{sleep_seconds}】秒，因为该接口有一分钟的限制'.format(sleep_seconds=sleep_seconds))
        # time.sleep(sleep_seconds)

    return order_list


# 掌读
@robust_util.catch_exception
def get_zhangdu_order(st, et):
    start_exec_seconds = date_util.getCurrentSecondTime()
    total_order_list = ()
    account_list = platform_config_util.get_zhangdu_account_list()

    executor = ProcessPoolExecutor(max_workers=5)

    futures = []
    for account in account_list:
        future = executor.submit(get_zhangdu_order_task, st, et, account)
        futures.append(future)
    executor.shutdown(True)

    for future in futures:
        order_list = future.result()
        if len(order_list) > 0:
            total_order_list = order_list + total_order_list

    print('掌读订单数量：', len(total_order_list), '执行时长（秒）：', date_util.getCurrentSecondTime() - start_exec_seconds)
    return total_order_list


def get_zhangdu_order_task(st, et, account):
    order_list = ()
    url = 'https://api.zhangdu520.com/channel/getorder'

    uid = account[0]
    appsecert = account[1]
    channel = account[2]
    timestamp = int(time.time())
    sign = md5(str(uid) + '&' + appsecert + '&' + str(timestamp))
    starttime = st
    timespace = 90 * 3600 * 24
    endtime = min(et, st + timespace)

    for x in range((et - st) // timespace + 1):  # 分时段
        if x > 0:
            print('掌读跨天数查询:', x)

        page = 1
        while True:
            params = {
                'uid': uid,
                'timestamp': timestamp,
                'sign': sign,
                'starttime': starttime,
                'endtime': endtime,
                'page': page
            }
            response_result_json = requests.get(url=url, params=params).json()
            if 'data' not in response_result_json.keys():
                print('掌读账号【{key}】, 查询时间【{start_time} - {end_time}】，本次请求数据异常，响应报文【{result}】'
                      .format(key=uid, start_time=date_util.getSecondsToDatetime(starttime),
                                  end_time=date_util.getSecondsToDatetime(endtime), result=response_result_json))
                break

            result_data = response_result_json['data']
            page_count = result_data['pageCount']
            if page_count == 0:
                break

            order_item_list = result_data['list']
            for order_item in order_item_list:
                if order_item['status'] != '1':#1为已支付
                    continue

                order = {}
                order['amount'] = order_item['amount']
                order['channel_id'] = uid
                order['order_id'] = str(order_item['orderno'])
                order['order_time'] = order_item['ctime']
                order['user_id'] = order_item['openid']
                order['platform'] = '掌读'
                order['channel'] = channel
                order['reg_time'] = order_item['regtime']
                order['from_novel'] = ''
                order['stage'] = ''
                order['date'] = ((int(order_item['ctime']) + 8 * 3600) // 86400) * 86400 - 8 * 3600

                x = sorted(order.items(), key=lambda item: item[0])
                x = dict(x)
                x = tuple(x.values())
                order_list = order_list + ((x),)

            if page == page_count: #是最后一页
                break

            page = page + 1


        starttime = starttime + timespace
        endtime = min(et, starttime + timespace)

    return order_list


# 花生
@robust_util.catch_exception
def get_huasheng_order(st, et):
    start_exec_seconds = date_util.getCurrentSecondTime()
    total_order_list = ()
    account_list = platform_config_util.get_huasheng_account_list()

    executor = ProcessPoolExecutor(max_workers=5)

    futures = []
    for account in account_list:
        url = 'https://vip.rlcps.cn/api/getMerchants'
        apiKey = str(account[0])
        apiSecurity = account[1]
        timestamp = str(int(time.time()))
        sign = md5(apiKey + timestamp + apiSecurity).upper()
        params = {
            'apiKey': apiKey,
            'apiSecurity': apiSecurity,
            'timestamp': timestamp,
            'sign': sign
        }
        response_result_json = requests.post(url, params).json()

        if 'data' not in response_result_json.keys():
            print('花生账号【{apiKey}】本次请求数据异常，响应报文【{result}】'.format(apiKey=apiKey, result=response_result_json))
            continue

        for merchant in response_result_json['data']:
            future = executor.submit(get_huasheng_order_task, st, et, account, merchant)
            futures.append(future)

    executor.shutdown(True)

    for future in futures:
        order_list = future.result()
        if len(order_list) > 0:
            total_order_list = order_list + total_order_list

    print('花生订单数量：', len(total_order_list), '执行时长（秒）：', date_util.getCurrentSecondTime() - start_exec_seconds)
    return total_order_list


def get_huasheng_order_task(st, et, account, merchant):
    order_list = ()

    apiKey = str(account[0])
    apiSecurity = account[1]
    stage = account[2]
    timestamp = str(int(time.time()))

    order_url = 'https://vip.rlcps.cn/api/orderList'
    merchant_id = merchant['merchant_id']
    merchant_name = merchant['merchant_name']
    start_time = st
    limit = 500

    for i in range((et - st) // 86400 + 1):
        page = 1

        while True:
            date = time.strftime("%Y-%m-%d", time.localtime(start_time))
            sign = md5(apiKey + date + str(merchant_id) + timestamp + apiSecurity).upper()
            order_params = {
                'apiKey': apiKey,
                'apiSecurity': apiSecurity,
                'timestamp': timestamp,
                'date': date,
                'merchant_id': merchant_id,
                'sign': sign,
                'page': page,
                'limit': limit
            }
            response_result_json = requests.post(order_url, order_params).json()

            if 'data' not in response_result_json.keys():
                print('花生账号【{key}】, 查询时间【{date}】, 渠道【{merchant_id}:{merchant_name}】本次请求数据异常，响应报文【{result}】'
                      .format(key=apiKey, date=date, merchant_id=merchant_id, merchant_name=merchant_name,
                              result=response_result_json))
                break

            if len(response_result_json['data']) == 0:
                break

            total_count = response_result_json['count']
            order_item_list = response_result_json['data']

            for order_item in order_item_list:
                if order_item['order_status'] == 1:  # 1为已支付
                    order = {}
                    ##dtime = datetime.datetime.strptime(order_item['pay_at'],"%Y-%m-%d")
                    ##order['date']= ((int(time.mktime(dtime.timetuple()))+8*3600)//86400)*86400-8*3600
                    order['user_id'] = order_item['openid']
                    order['order_id'] = order_item['trans_id']
                    order['order_time'] = order_item['pay_at']
                    order['reg_time'] = order_item['join_at']
                    # TODO 花生的时间需要统一
                    order['date'] = (start_time + 8 * 3600) // 86400 * 86400 - 8 * 3600
                    order['channel'] = merchant_name
                    order['channel_id'] = merchant_id
                    order['platform'] = '花生'
                    order['stage'] = stage
                    order['from_novel'] = order_item['book_name']
                    order['amount'] = order_item['amount']

                    order = sorted(order.items(), key=lambda item: item[0])
                    order = dict(order)
                    order = tuple(order.values())
                    order_list = order_list + ((order),)

            if int(page) >= math.ceil(total_count / int(limit)):
                break

            # print('花生账号【{key}】, 渠道【{merchant_id}:{merchant_name}】当前页【{page}】，本次查询订单数【{total_count}】，即将查询下一页'
            #       .format(key=apiKey, merchant_id=merchant_id, merchant_name=merchant_name, page=page, total_count=total_count))

            page = page + 1

        start_time = start_time + 86400  # 天数加1

    return order_list


# 掌中云
@robust_util.catch_exception
def get_zhangzhongyun_order(st, et):
    start_exec_seconds = date_util.getCurrentSecondTime()
    total_order_list = ()
    account_list = platform_config_util.get_zhangzhongyun_account_list()

    executor = ProcessPoolExecutor(max_workers=5)

    futures = []
    for account in account_list:
        #url = 'https://openapi.818tu.com/partners/channel/channels/list?'
        url = 'https://inovel.818tu.com/partners/channel/channels/list?'
        key = account[0]
        secert = account[1]
        sign = md5(secert + 'key=' + key)
        params = 'key=' + key + '&sign=' + sign
        response_result_json = requests.get(url + params).json()  # 获取子渠道列表

        if 'data' not in response_result_json.keys():
            print('掌中云账号【{key}】本次请求数据异常，响应报文【{result}】'.format(key=key, result=response_result_json))
            continue

        items = response_result_json['data']['items']
        for channel in items:
            # 获取channel_id 后逐个拉取历史orders
            future = executor.submit(get_zhangzhongyun_order_task, st, et, account, channel)
            futures.append(future)

    executor.shutdown(True)

    for future in futures:
        order_list = future.result()
        if len(order_list) > 0:
            total_order_list = order_list + total_order_list

    print('掌中云订单数量：', len(total_order_list), '执行时长（秒）：', date_util.getCurrentSecondTime() - start_exec_seconds)
    return total_order_list


def get_zhangzhongyun_order_task(st, et, account, channel):
    # 掌中云的时间格式比较特殊,转换下
    get_time, limit_time = platform_config_util.get_zhangzhongyun_query_time(st, et)

    order_list = ()

    key = account[0]
    secert = account[1]
    stage = account[2]

    order_url = 'https://openapi.818tu.com/partners/channel/orders/list?'
    channel_id = channel['id']
    channel_name = channel['nickname']
    status = str(1)
    page = str(1)
    per_page = str(1000)
    gte = parse.urlencode({'created_at[gte]': get_time})  # gte就是ge 大于等于开始时间
    lt = parse.urlencode({'created_at[lt]': limit_time})  # 小于 结束时间

    while True:
        sign = md5(secert + 'channel_id=' + str(
            channel_id) + '&created_at[gte]=' + get_time + '&created_at[lt]=' + limit_time + '&key=' + key + '&page=' + str(
            page) + '&per_page=' + per_page + '&status=' + status)
        params = 'channel_id=' + str(channel_id) + '&' + gte + '&' + lt + '&page=' + str(
            page) + '&per_page=' + per_page + '&status=' + status + '&key=' + key + '&sign=' + sign

        response_result_json = requests.get(order_url + params).json()

        if 'data' not in response_result_json.keys():
            print('掌中云账号【{key}】，查询时间【{start_time} - {end_time}】，渠道【{channel_id}:{channel_name}】本次请求数据异常，响应报文【{result}】'
                  .format(key=key, start_time=date_util.getSecondsToDatetime(get_time),
                                  end_time=date_util.getSecondsToDatetime(limit_time),channel_id=channel_id, channel_name=channel_name, result=response_result_json))
            break

        total_count = response_result_json['data']['count']  # 总数量
        order_item_list = response_result_json['data']['items']  # 订单列表

        for order_item in order_item_list:
            order = {}
            order['user_id'] = str(order_item['member']['openid'])
            order['channel'] = channel_name
            order['reg_time'] = order_item['member']['created_at']
            order['channel_id'] = channel_id
            order['amount'] = round(order_item['price'] / 100, 2)
            order['order_id'] = str(order_item['id'])
            order['order_time'] = order_item['created_at']
            order['platform'] = '掌中云'
            order['stage'] = stage
            dtime = datetime.datetime.strptime(order_item['created_at'][0:10], "%Y-%m-%d")
            order['date'] = ((int(time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600

            if str(order_item['from_novel_id']) != 'None':
                order['from_novel'] = order_item['from_novel']['title']
            else:
                order['from_novel'] = 'None'

            x = sorted(order.items(), key=lambda item: item[0])
            x = dict(x)
            x = tuple(x.values())
            order_list = order_list + ((x),)

        if int(page) >= math.ceil(total_count / int(per_page)):
            break

        # print('掌中云账号【{key}】, 渠道【{channel_id}:{channel_name}】当前页【{page}】，本次查询订单数【{total_count}】，即将查询下一页'
        #       .format(key=key, channel_id=channel_id, channel_name=channel_name, page=page, total_count=total_count))

        page = int(page) + 1

    return order_list


# 悠书阁
@robust_util.catch_exception
def get_youshuge_order(st, et):
    start_exec_seconds = date_util.getCurrentSecondTime()
    total_order_list = ()
    account_list = platform_config_util.get_youshuge_account_list()

    executor = ProcessPoolExecutor(max_workers=5)

    futures = []
    for account in account_list:
        future = executor.submit(get_youshuge_order_task, st, et, account)
        futures.append(future)

    executor.shutdown(True)

    for future in futures:
        order_list = future.result()
        if len(order_list) > 0:
            total_order_list = order_list + total_order_list

    print('悠书阁订单数量：', len(total_order_list), '执行时长（秒）：', date_util.getCurrentSecondTime() - start_exec_seconds)
    return total_order_list


def get_youshuge_order_task(st, et, account):
    # 悠书阁的查询end_date时间必须要大于start_date
    start_date, end_date = platform_config_util.get_youshuge_order_query_time(st, et)

    order_list = ()

    host_name = account[0]
    channel_id = int(account[1])
    secert_key = account[2]
    channel = account[3]
    stage = account[4]

    url = 'https://novel.youshuge.com/v2/open/orders'
    page = 1
    timestamp = int(time.time())

    while True:
        sign = md5('channel_id=' + str(channel_id) + '&end_date=' + end_date + '&host_name=' + host_name + '&page='
                   + str(page) + '&pay_status=1' + '&start_date=' + start_date + '&time=' + str(timestamp) + '&key=' + secert_key).upper()
        params = {
            'sign': sign,
            'host_name': host_name,
            'time': timestamp,
            'channel_id': channel_id,
            'page': page,
            'pay_status': 1,
            'start_date': start_date,
            'end_date': end_date
        }
        respone = requests.post(url, params)
        if respone.status_code == 400:
            print('悠书阁订单查询接口respone', respone)

        response_result_json = respone.json()
        if 'data' not in response_result_json.keys():
            print('悠书阁账号【{key}】，查询时间【{start_time} - {end_time}】，渠道【{channel_id}:{channel_name}】本次请求数据异常，响应报文【{result}】'
                  .format(key=host_name, start_time=start_date, end_time=end_date, channel_id=channel_id, result=response_result_json))
            break

        order_item_list = response_result_json['data']
        if len(order_item_list) == 0:
            break

        for order_item in order_item_list:
            order = {}
            dtime = datetime.datetime.strptime(order_item['create_time'][0:10], "%Y-%m-%d")
            order['date'] = ((int(
                time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
            order['order_id'] = order_item['order_num']
            order['amount'] = round(int(order_item['price']) / 100, 2)
            order['order_time'] = order_item['create_time']
            order['channel'] = channel
            order['from_novel'] = order_item['book_name']
            order['stage'] = stage
            order['user_id'] = order_item['openid']
            order['channel_id'] = channel_id
            order['platform'] = '悠书阁'
            order['reg_time'] = order_item['reg_time']

            order = sorted(order.items(), key=lambda item: item[0])
            order = dict(order)
            order = tuple(order.values())
            order_list = order_list + ((order),)

        total_count = order_item_list[0]['count']

        if page == total_count:
            break

        page = page + 1


    return order_list


def build_ysg_order_data(channel, channel_id, result_json, stage):
    order_list = ()
    if 'data' in result_json.keys():
        data = result_json['data']
        if len(data) > 0:
            for x in data:
                y = {}
                dtime = datetime.datetime.strptime(x['create_time'][0:10], "%Y-%m-%d")
                y['date'] = ((int(
                    time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
                y['order_id'] = x['order_num']
                y['amount'] = round(int(x['price']) / 100, 2)
                y['order_time'] = x['create_time']
                y['channel'] = channel
                y['from_novel'] = x['book_name']
                y['stage'] = stage
                y['user_id'] = x['openid']
                y['channel_id'] = channel_id
                y['platform'] = '悠书阁'
                y['reg_time'] = x['reg_time']

                y = sorted(y.items(), key=lambda item: item[0])
                y = dict(y)
                y = tuple(y.values())
                order_list = order_list + ((y),)
    return order_list

