import pandas as pd
import numpy as np
import copy
import time
import json


class Queue:
    def __init__(self, length):
        self.queue = []
        self.length = length

    def in_queue(self, item):
        self.queue.append(item)
        if len(self.queue) > self.length:
            self.queue.pop(0)

    def content(self):
        return self.queue


def cal_price(engine, factor_dict):
    result = 0
    for key, value in factor_dict.items():
        x = value * engine[key]
        result += x if str(x) != 'nan' else 0
    return result


def generate_full_config(single_config, full_config_list):
    new_dimension = list(np.arange(single_config[0], single_config[1], single_config[2]).round(4))
    if not full_config_list:
        return [[item] for item in new_dimension]
    new_full_config_list = []
    for og_list in full_config_list:
        for item in new_dimension:
            new_full_config_list.append(copy.deepcopy(og_list + [item]))
    return new_full_config_list


def generate_full_config_dict_list(single_config, full_config_list, key):
    new_dimension = list(np.arange(single_config[0], single_config[1], single_config[2]).round(4))
    if not full_config_list:
        return [{key: float(val)} for val in new_dimension]
    new_full_config_list = []
    for og_dict in full_config_list:
        for item in new_dimension:
            new_dict = copy.deepcopy(og_dict)
            new_dict[key] = float(item)
            new_full_config_list.append(new_dict)
    return new_full_config_list


def calculate_config_factor(local_config_dict, target_list):
    gen_config_start_time = time.time()
    full_config = []
    for key, content in local_config_dict.items():
        # full_config = generate_full_config(content, full_config)
        full_config = generate_full_config_dict_list(content, full_config, key)
    with open('data/full_config.txt', 'w', encoding='utf-8') as file:
        file.write(json.dumps(full_config))
    # file = open('data/full_config.txt', 'r', encoding='utf-8')
    # full_config = json.loads(file.read())
    print('Config Time:', time.time() - gen_config_start_time)

    calculation_start = time.time()
    min_div = 999999999999999999999
    best_config = None
    best_config_queue = Queue(10)
    for config in full_config:
        div = 0
        for engine in target_list:
            if engine['SL-ISP'] >= 200:
                # auto_price = (engine['SL-ISP'] / 260) * (engine["Vac-ISP"] / 290) * engine['TWR'] * engine['Max Thrust'] * (1 - engine['Throttle Range']) * (1 + 0.01*engine['TVC']) / 4
                auto_price = cal_price(engine, config)
                price = engine['Price KD']
                div += abs(auto_price - price)
                # print(auto_price, price, auto_price - price, auto_price / price)
                # if auto_price / price >= 2:
                #     raise ValueError
        if min_div > div:
            min_div = div
            best_config = config
            best_config_queue.in_queue([min_div, config])
    print('Calculation Time:', time.time() - calculation_start)
    return best_config_queue


def cal_single_div(target_list, config):
    div = 0
    for engine in target_list:
        if engine['SL-ISP'] >= 200:
            auto_price = cal_price(engine, config)
            price = engine['Price KD']
            div += abs(auto_price - price)
    return div


if __name__ == '__main__':
    path = 'D://OneDrive//文档//KSP Engine Tweak Chart.xlsx'
    excel_content = pd.read_excel(path, sheet_name='Engine Database')
    full_list = []
    for key, content in excel_content.iterrows():
        if content['Fuel Type'] == 'Kerolox' and content['Cycle'] == 'Gas Generator':
            full_list.append(dict(content))

    tmp_config = {'Max Thrust': 1.7, 'SL-ISP': 0.2, 'TR Adjusted': 0.2, 'TVC Adjusted': 0.5, 'TWR': 0.5, 'Vac-ISP': 0.2}
    div = cal_single_div(full_list, tmp_config)

    config_dict = {
        'SL-ISP': (0.01, 0.51, 0.05),
        'Vac-ISP': (0.01, 0.51, 0.05),
        'TWR': (0.01, 1.01, 0.1),
        'Max Thrust': (1.5, 2.0, 0.05),
        'TR Adjusted': (0.01, 1.01, 0.1),
        'TVC Adjusted': (0.01, 1.01, 0.1),
    }

    factor_result = calculate_config_factor(config_dict, full_list)

    auto_dict = {'Max Thrust': 0.3, 'SL-ISP': 0.0012, 'TR Adjusted': 0.9, 'TVC Adjusted': 0.52, 'TWR': 0.5, 'Vac-ISP': 0.0013}
    div = 0
    for engine in full_list:
        if engine['SL-ISP'] >= 200:
            auto_price = cal_price(engine, auto_dict)
            price = engine['Price KD']
            print(auto_price, price, auto_price - price, auto_price / price)

            # if auto_price / price >= 2:
            #     raise ValueError
    print('done')



