from dspt_api.util.general.handle_float import f2
from dspt_api.util.general.handle_redis import get_data_from_redis, get_param_from_redis
from dspt_api.util.general.handle_card import get_card_type
import time


def general_seat_params(pay_type, data):
    """
    说明:
    支持现金、联名卡支付,电子券支付,扫码券支付
    现金支付时,可以走电商渠道定价
    联名卡支付时,价格取联名卡的优惠价,支付方式还是现金
    电子券和扫码券都是走鼎新定价,然后通过券接口获取价格,剩余待支付的金额为现金支付
    券只支持如下几种券:

    先从seat_lock接口获取座位价格
    如果seat_lock没有获取到座位价格就到

    返回 结果, seat , ticket_cash, play_id, play_update_time, lock_flag, quan, timestamp
    """
    redis_key_prefix = f'dspt_api_{data["ip"]}_{data["env"]}_{data["member_type"]}_{data["pid"]}_{data["cid"]}'

    # 获取 area_info和partner_price
    request_api_lock = {'name': '3.3.1 座位锁定', 'path': 'seat/lock'}
    redis_key_api_lock = f'{redis_key_prefix}_{request_api_lock["path"]}'
    result_lock, _format_lock, seat_price_from_lock, _timestamp_lock = get_data_from_redis(redis_key_api_lock)
    if not result_lock:
        print('result_lock False')
        return False, None, None, None, None, None, None, None
    area_info = seat_price_from_lock['areaInfo'] if len(seat_price_from_lock['areaInfo']) > 0 else False
    lock_flag = seat_price_from_lock['lockFlag']
    # partner_price = seat_price_from_lock['partnerPrice'] if seat_price_from_lock['partnerPrice'] is not None else False

    # 获取market_price
    request_api_play = {'name': '3.1.5 获取放映计划列表', 'path': 'cinema/plays'}
    redis_key_api_play = f'{redis_key_prefix}_{request_api_play["path"]}'
    result_play, _format_play, seat_price_from_play, _timestamp_play = get_data_from_redis(redis_key_api_play)
    if not result_play:
        print('result_play False')
        return False, None, None, None, None, None, None, None
    market_price = seat_price_from_play['marketPrice']
    play_id = seat_price_from_play['id']
    play_update_time = seat_price_from_play['cineUpdateTime']

    # 获取手续费
    request_api_config = {'name': '3.1.2 获取单个影院配置信息', 'path': 'cinema/config'}
    redis_key_api_config = f'{redis_key_prefix}_{request_api_config["path"]}'
    result_config, _format_config, seat_price_from_config, _timestamp_config = get_data_from_redis(redis_key_api_config)
    if not result_config:
        print('result_config False')
        return False, None, None, None, None, None, None, None
    handle_fee = seat_price_from_config['handleFee']
    partner_type = seat_price_from_config['partnerSubsidyType']  # 1:电商平台补贴;2:合作商补贴

    # 获取座位信息
    request_api_seat = {'name': '3.1.8 获取某场次座位状态', 'path': 'play/seat-status'}
    redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}'
    result_seat, _format_seat, seat_price_from_seat, _timestamp_seat = get_data_from_redis(redis_key_api_seat)
    if not result_seat:
        print('result_seat False')
        return False, None, None, None, None, None, None, None
    seat_id_list = [{'seat_id': seat['cineSeatId'], 'ticket_discount': seat.get('ticketDiscount', 0),
                     'service_discount': seat.get('serviceDiscount', 0)} for seat in seat_price_from_seat]

    # 计算最大时间戳
    last_timestamp = max([_timestamp_lock, _timestamp_play, _timestamp_config, _timestamp_seat])

    # 判断获取到了全部接口数据,就继续,否则报错
    if not (result_lock and result_play and result_config and result_seat):
        return_str = '请手动输入参数,检查相关接口返回值:3.3.1 座位锁定、3.1.5 获取放映计划列表、3.1.8 获取某场次座位状态、3.1.2 获取单个影院配置信息'
        return False, return_str, 0, return_str, return_str, return_str, return_str, last_timestamp

    if pay_type == 'cash':
        """
        -- 当影院合作商是电商平台定价时(partner_type = 1)
        price:不包含手续费,含服务费
        user_real_pay_price:用户真实支付影票金额,不含手续费、服务费,该字段只做记录不参与计算
        service_fee:影厅座位服务费(仅当锁座接口返回的服务费[areaServiceFee]不为零时,才传此参数)
        ticket_discount_price:影票优惠金额; service_fee_discount_price:服务费优惠金额,
        注:如果是鼎新电商平台对合作商价格管控,使用以上两个优惠金额字段需要联系请联系鼎新杰盈公司商务打开开关即可使用,否则直接回传会产生掉单。
        -- 当影院合作商是合作商自主定价时(partner_type = 2)
        price:真实的票价[不含服务费、不含手续费]
        user_real_pay_price:用户真实支付影票金额[不含手续费、服务费] 需要扣减 ticket_discount_price
        service_fee:真实的服务费 
        ticket_discount_price:影票优惠金额,仅做记录
        service_fee_discount_price:服务费优惠金额,仅做记录
        
        测试影院:
        测试影院3.166 乐影网 电商平台补贴 是否允许传递优惠金额 否 影票价格控制 是 卖品价格控制 是
        测试影院3.166 淘票票 电商平台补贴 是否允许传递优惠金额 是 影票价格控制 否 卖品价格控制 否
        测试影院3.166 美团猫眼 电商平台补贴 是否允许传递优惠金额 是 影票价格控制 是 卖品价格控制 是
        测试影院3.166 合作商补贴 合作商补贴 是否允许传递优惠金额 否 影票价格控制 否 卖品价格控制 否
        
        """
        quan = ''
        seat_list = []
        ticket_cash = 0  # 统计cash字段用
        for seat_info in seat_id_list:
            seat = [seat_info["seat_id"], handle_fee]
            ticket_discount = seat_info["ticket_discount"]
            service_discount = seat_info["service_discount"]
            if area_info is not False:
                # 查找座位对应的区域价格
                for area_seat_info in area_info:
                    if int(area_seat_info['seatId']) == int(seat_info['seat_id']):
                        # 获取price字段值
                        price = f2(area_seat_info["areaPrice"])
                        seat.append(str(price))
                        seat.append('0')
                        seat.append(area_seat_info["areaServiceFee"])
                        # if partner_type == '2':  # 合作商定价
                        #     price -= Decimal(area_seat_info["areaServiceFee"]).quantize(Decimal('0.00'), ROUND_HALF_UP)
                        # 计算用户实际支付的值
                        real_pay = f2(area_seat_info["areaPrice"])
                        real_pay -= f2(area_seat_info["areaServiceFee"])
                        # 处理影票和服务费折扣
                        if ticket_discount != 0:
                            real_pay -= f2(ticket_discount)
                            seat.append(str(ticket_discount))
                        if service_discount != 0:
                            if partner_type == '2':
                                real_pay -= f2(service_discount)
                                seat.append(str(service_discount))
                            else:
                                seat.append(str(service_discount))
                        seat[3] = str(real_pay)
                        # seat = f'{seat_info["seat_id"]}-{handle_fee}-{str(price)}-{str(real_pay)}-{area_seat_info["areaServiceFee"]}{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}'
                        seat_list.append('-'.join(seat))
                        ticket_cash += real_pay
            else:
                seat.append(market_price)
                seat.append('0')
                seat.append('0.00')
                real_pay = f2(market_price)
                if ticket_discount != 0:
                    real_pay -= f2(ticket_discount)
                    seat.append(str(ticket_discount))
                if service_discount != 0:
                    real_pay -= f2(service_discount)
                    seat.append(str(service_discount))
                seat[3] = str(real_pay)
                # seat = f'{seat_info["seat_id"]}-{handle_fee}-{market_price}-{str(real_pay)}-0{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}'
                seat_list.append('-'.join(seat))
                ticket_cash += real_pay
        return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp

    elif pay_type == 'ecard':
        quan = ''
        # 获取联名卡价格
        request_api_ecard = {'name': '3.4.6 获取座位的联名卡价格', 'path': 'ecard/seat-price'}
        redis_key_api_ecard = f'{redis_key_prefix}_{request_api_ecard["path"]}'
        result_ecard, _format_ecard, seat_price_from_ecard, _timestamp_ecard = get_data_from_redis(
            redis_key_api_ecard)
        if not result_ecard:
            print('result_ecard False')
            return False, None, None, None, None, None, None, None
        ecard_info = seat_price_from_ecard['seatPrices'] if len(seat_price_from_ecard['seatPrices']) > 0 else False
        # 错误判断
        if ecard_info is False:
            return_str = '请手动输入参数,检查相关接口返回值:3.4.6 获取座位的联名卡价格'
            return False, return_str, 0, return_str, return_str, return_str, last_timestamp
        # 处理价格
        seat_list = []
        ticket_cash = 0  # 统计cash字段用
        for seat_info in seat_id_list:
            seat = [seat_info["seat_id"], handle_fee]
            ticket_discount = seat_info["ticket_discount"]
            service_discount = seat_info["service_discount"]
            for ecard_seat_info in ecard_info:
                if int(ecard_seat_info['seatId']) == int(seat_info['seat_id']):
                    # 获取price字段值
                    price = f2(ecard_seat_info["price"])
                    seat.append(str(price))
                    seat.append('0')
                    seat.append(ecard_seat_info["serviceFee"])
                    # if partner_type == '2':  # 合作商定价
                    #     price -= Decimal(area_seat_info["areaServiceFee"]).quantize(Decimal('0.00'), ROUND_HALF_UP)
                    # 计算用户实际支付的值
                    real_pay = f2(ecard_seat_info["price"])
                    real_pay -= f2(ecard_seat_info["serviceFee"])
                    # 处理影票和服务费折扣
                    if ticket_discount != 0:
                        real_pay -= f2(ticket_discount)
                        seat.append(str(ticket_discount))
                    if service_discount != 0:
                        if partner_type == '2':
                            real_pay -= f2(service_discount)
                            seat.append(str(service_discount))
                        else:
                            seat.append(str(service_discount))
                    seat[3] = str(real_pay)
                    # seat = f'{seat_info["seat_id"]}-{handle_fee}-{str(price)}-{str(real_pay)}-{area_seat_info["areaServiceFee"]}{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}'
                    seat_list.append('-'.join(seat))
                    ticket_cash += real_pay
        return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp

    elif pay_type in ['yushouquan', 'equan']:
        # 获取券价格
        request_api_yushouquan = {'name': '3.6.1 添加券', 'path': 'seat/check-coupon'}
        redis_key_api_yushouquan = f'{redis_key_prefix}_{request_api_yushouquan["path"]}'
        result_yushouquan, _format_yushouquan, seat_price_from_yushouquan, _timestamp_yushouquan = get_data_from_redis(
            redis_key_api_yushouquan)
        if not result_yushouquan:
            print('result_yushouquan False')
            return False, None, None, None, None, None, None, None
        # 获取券码
        req_params = get_param_from_redis(redis_key_api_yushouquan)
        if pay_type == 'yushouquan':
            quan = req_params['coupons'] if req_params.get('coupons', False) else '3.6.1添加券接口中选择的券类型为会员卡赠券,与当前设置不符合'
        elif pay_type == 'equan':
            quan = req_params['card_coupons'] if req_params.get('equan', False) else '3.6.1添加券接口中选择的券类型为扫码券,与当前设置不符合'
        else:
            quan = '请检查3.6.1添加券接口'
        # 获取座位参数
        seat_list = []
        ticket_cash = 0  # 统计cash字段用
        for seat_info in seat_id_list:
            seat = [seat_info["seat_id"], handle_fee]
            ticket_discount = seat_info["ticket_discount"]
            service_discount = seat_info["service_discount"]
            seat.append(market_price)
            seat.append('0')
            seat.append('0.00')
            real_pay = f2(market_price)
            if ticket_discount != 0:
                real_pay -= f2(ticket_discount)
                seat.append(str(ticket_discount))
            if service_discount != 0:
                real_pay -= f2(service_discount)
                seat.append(str(service_discount))
            seat[3] = str(real_pay)
            # seat = f'{seat_info["seat_id"]}-{handle_fee}-{market_price}-{str(real_pay)}-0{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}'
            seat_list.append('-'.join(seat))
            ticket_cash += real_pay
        ticket_cash = seat_price_from_yushouquan['balance']
        return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp
    else:
        pass


def general_seat_params_member(pay_type, data, card):
    """
        seat_id-handle_fee-price-ticket_type-is_discount-settlement_price-service_fee 组成的字符串,多个值(多个seat)组用半角逗号分隔。
        seat_id: 要购买的座位号
        handle_fee:手续费,如果下单传入了退票订单号,会将handle_fee字段视为改签手续费
        price:(不包含手续费)会员卡支付金额,该字段值是否包含影厅座位服务费取决于字段is_split_service_fee
        ticket_type: 影票类型(《会员卡详细信息》接口的业务响应参数desc的值)
        is_discount: 0:普通票,1:会员票,2:全局会员票
        settlement_price:座位结算价,用于计算座位补贴(补贴=结算价-支付价),该值不能低于场次最低票价。(只有当参数is_cinema_price=2时,该值才有效,平台请求影院购票接口时会将计算出的补贴金额传给影院,补贴金额会计入影城报表。
        注:该字段值是否包含影厅座位服务费取决于字段is_split_service_fee)
        service_fee:影厅座位服务费(只有当参数is_cinema_price=2时,该值才有效)

        返回 结果, seat, play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, cash_pay, timestamp
    """
    # 获取卡类型
    card_type = get_card_type(data["env"], data["pid"], data["cid"], card)
    if card_type is False:
        return_str = '此会员卡在该影院无法使用,请使用3.1.3 查询会员卡的详细信息接口查看卡信息'
        return False, return_str, return_str, return_str, return_str, return_str, '2', 'Y', None, int(
            time.time() * 1000)

    # 获取其他参数
    redis_key_prefix = f'dspt_api_{data["ip"]}_{data["env"]}_{data["member_type"]}_{data["pid"]}_{data["cid"]}'

    # seat_id
    request_api_seat = {'name': '3.2.6 获取某场次座位状态', 'path': 'play/seat-status'}
    redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}'
    result_seat, _format_seat, seat_data, _timestamp_seat = get_data_from_redis(redis_key_api_seat)
    if not result_seat:
        return False, None, None, None, None, None, None, None, None, None

    # 获取play_id 和 play_update_time
    request_api_play = {'name': '3.2.3 获取放映计划列表', 'path': 'cinema/plays'}
    redis_key_api_play = f'{redis_key_prefix}_{request_api_play["path"]}'
    result_play, _format_play, seat_price_from_play, _timestamp_play = get_data_from_redis(redis_key_api_play)
    if not result_play:
        return False, None, None, None, None, None, None, None, None, None
    play_id = seat_price_from_play['id']
    play_update_time = seat_price_from_play['cineUpdateTime']
    lowest_price = f2(seat_price_from_play['lowestPrice'])

    # 获取 lock_flag
    request_api_lock = {'name': '3.4.3 座位锁定', 'path': 'seat/lock'}
    redis_key_api_lock = f'{redis_key_prefix}_{request_api_lock["path"]}'
    result_lock, _format_lock, seat_price_from_lock, _timestamp_lock = get_data_from_redis(redis_key_api_lock)
    if not result_lock:
        return False, None, None, None, None, None, None, None, None, None
    lock_flag = seat_price_from_lock['lockFlag']

    # cinema_price
    request_api_seat = {'name': '3.4.4 锁定座位后获取票价', 'path': 'seat/price'}
    redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}'
    result_seat_price, _format_seat_price, seat_data_price, _timestamp_seat_price = get_data_from_redis(
        redis_key_api_seat)
    if not result_seat_price:
        return False, None, None, None, None, None, None, None, None, None

    # handle_fee
    request_api_config = {'name': '3.2.2 获取单个影院配置信息', 'path': 'cinema/config'}
    redis_key_api_config = f'{redis_key_prefix}_{request_api_config["path"]}'
    result_config, _format_config, seat_price_from_config, _timestamp_config = get_data_from_redis(redis_key_api_config)
    if not result_config:
        return False, None, None, None, None, None, None, None, None, None
    handle_fee = f2(seat_price_from_config['handleFee'])

    # 计算最大时间戳
    last_timestamp = max([_timestamp_seat, _timestamp_play, _timestamp_config, _timestamp_lock, _timestamp_seat_price])

    # 判断获取到了全部接口数据,就继续,否则报错
    if not (result_seat and result_play and result_lock and result_seat_price and result_config):
        return_str = '请手动输入参数,检查相关接口返回值:3.2.6 获取某场次座位状态、3.2.3 获取放映计划列表、3.4.3 座位锁定、3.4.4 锁定座位后获取票价、3.2.2 获取单个影院配置信息'
        return False, return_str, return_str, return_str, return_str, return_str, '1', None, None, last_timestamp

    seat_list = []

    # 处理影院定价逻辑
    if pay_type['select_price_type'] == 'cinema_price':
        # 11682-1-27.7-会员票-1
        is_cinema_price = '1'
        is_split_service_fee = None
        seat_coupons = None

        # 计算影票价
        ticket_price = f2(f2(seat_data_price['totalPrice']) / int(seat_data_price['ticketNum']))
        ticket_service = f2(f2(seat_data_price['totalServiceCharge']) / int(seat_data_price['ticketNum']))

        cash_pay = 0  # 计算需要非卡余额支付的金额

        # 生成座位字段
        for seat in seat_data:
            seat_list.append(f"{seat['cineSeatId']}-{str(handle_fee)}-{str(ticket_price)}-会员票-1")
            if card_type == '权益卡(积分卡)':
                cash_pay += f2(ticket_price + handle_fee)
            else:
                cash_pay += 0

        return True, ','.join(
            seat_list), play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, str(
            cash_pay), last_timestamp

    # 处理三方定价的逻辑
    if pay_type['select_price_type'] == 'third_price':
        quan_type = pay_type['ticket_quan']['ticket_quan_type']

        # 11664-1-16.5-会员票-1-26.5-1.5
        is_cinema_price = '2'

        # 处理is_split_service_fee字段
        if pay_type['ticket_info']['have_service_fee'] is True:
            is_split_service_fee = 'Y'
        else:
            is_split_service_fee = 'N'

        # 生成券字段
        # 11663-Rog自营兑换券10元@@6777bbcfhirW6VAqkHItn3PZ@@10.00@@0
        quan_list = []
        quan_price_list = []

        if pay_type['ticket_quan_check']:

            quan_per_ticket = int(int(pay_type['ticket_quan']['ticket_quan_num']) / len(seat_data))  # 每张票平均分配的券数量
            quan_price_num = [quan_per_ticket] * len(seat_data)  # 每张票平均分配的券数量列表
            # 多余的券添加到每张票上
            for i in range(int(pay_type['ticket_quan']['ticket_quan_num']) % len(seat_data)):
                quan_price_num[i] += 1
            print('quan_price_num', quan_price_num)  # quan_price_num [2, 2, 1] 3个座位 5张券

            # 生成券字段列表
            quan_price = f2(pay_type['ticket_quan']['ticket_quan_value'])

            for i, num in enumerate(quan_price_num):
                seat_id = seat_data[i]['cineSeatId']
                quan_code_list = [f"rog{str(time.time_ns())}{seat_id}{str(n)}" for n in range(num)]
                quan_code = '|'.join(quan_code_list)
                quan_code_price = f2(quan_price * num)
                # 券名称@@券码@@券面额@@券抵值金额
                if quan_type == '抵值兑换券':
                    quan_list.append(
                        f"{seat_id}-Rog{quan_type}{str(quan_price)}@@{quan_code}@@{str(quan_code_price)}@@{str(quan_code_price)}")
                else:
                    quan_list.append(
                        f"{seat_id}-Rog{quan_type}{str(quan_price)}@@{quan_code}@@{str(quan_code_price)}@@0")
                quan_price_list.append(quan_code_price)

        seat_coupons = ','.join(quan_list) if len(quan_list) > 0 else None  # 生成券字段
        print('quan_price_list',
              quan_price_list)  # quan_price_list [Decimal('22.22'), Decimal('22.22'), Decimal('11.11')]

        # 计算影票价格部分
        ticket_price = f2(pay_type['ticket_info']['ticket_price'])
        service_fee = f2(f2(seat_data_price['totalServiceCharge']) / int(seat_data_price['ticketNum']))

        cash_pay = 0

        for i, seat in enumerate(seat_data):
            # 计算实付金额
            ticket_real_pay = ticket_price
            if pay_type['ticket_quan_check']:
                if quan_type == '代金券':
                    ticket_real_pay = f2(ticket_price - quan_price_list[i])
                elif quan_type in ['抵值兑换券', '兑换券']:
                    ticket_real_pay = quan_price_list[i]

            ticket_real_pay = ticket_real_pay if ticket_real_pay > 0 else 0  # 处理用券后小于0的情况

            # 计算影票结算金额
            ticket_pay = ticket_real_pay
            if ticket_real_pay < lowest_price:
                ticket_pay = lowest_price

            if is_split_service_fee == 'Y':
                ticket_real_pay += service_fee
                ticket_pay += service_fee

            if card_type == '权益卡(积分卡)' or quan_type == '抵值兑换券':
                cash_pay += f2(ticket_real_pay + handle_fee)  # 当使用权益卡支付时,需要将实付票价累加到现金支付字段中
            else:
                cash_pay += 0

            seat_list.append(
                f"{seat['cineSeatId']}-{str(handle_fee)}-{str(ticket_real_pay)}-会员票-1-{str(ticket_pay)}-{str(service_fee)}")

        return True, ','.join(
            seat_list), play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, str(
            cash_pay), last_timestamp