from flask import Flask, render_template, request, redirect, url_for, jsonify
import json
import requests
import logging
import os
import traceback

app = Flask(__name__)

# Setup logging to file
logging.basicConfig(filename='log.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(message)s')

# Load the assort data
ASSORT_FILE_PATH = 'assort.json'
QUEST_ASSORT_FILE_PATH = 'questassort.json'
CACHE_FILE_PATH = 'item_cache.json'
RUBLE_TPL_ID = '5449016a4bdc2d6f028b456f'

try:
    with open(ASSORT_FILE_PATH) as f:
        assort_data = json.load(f)
        logging.debug("Assort data loaded successfully")
except Exception as e:
    logging.error(f"Error loading assort data: {e}")
    logging.error(traceback.format_exc())

try:
    with open(QUEST_ASSORT_FILE_PATH) as f:
        quest_assort_data = json.load(f)
        logging.debug("Quest assort data loaded successfully")
except Exception as e:
    logging.error(f"Error loading quest assort data: {e}")
    logging.error(traceback.format_exc())

# Load cache or initialize an empty dictionary
if os.path.exists(CACHE_FILE_PATH):
    try:
        with open(CACHE_FILE_PATH) as f:
            item_cache = json.load(f)
            logging.debug("Item cache loaded successfully")
    except Exception as e:
        logging.error(f"Error loading item cache: {e}")
        logging.error(traceback.format_exc())
        item_cache = {}
else:
    item_cache = {}
    logging.debug("Initialized empty item cache")

# Tarkov.dev API URL
TARKOV_API_URL = "https://api.tarkov.dev/graphql"

def get_ruble_image():
    return get_item_details_cached(RUBLE_TPL_ID)

@app.route('/')
def index():
    try:
        items = get_main_items_with_details(assort_data)
        ruble_image = get_ruble_image()
        return render_template('index.html', items=items, ruble_image=ruble_image)
    except Exception as e:
        logging.error(f"Error in index route: {e}")
        logging.error(traceback.format_exc())
        return "Error loading items", 500

def get_main_items_with_details(assort_data):
    items = []
    for item in assort_data['items']:
        if item['parentId'] == 'hideout':
            item_copy = item.copy()  # Create a copy of the item to avoid modifying the original
            item_copy['details'] = get_item_details_cached(item_copy['_tpl'])
            item_copy['parts'] = get_item_parts_with_details(item_copy['_id'], assort_data)
            item_copy['barter_scheme'] = get_barter_scheme_with_details(item_copy['_id'], assort_data)
            item_copy['quest_requirement'] = get_quest_requirement(item_copy['_id'])
            item_copy['offer_name'] = item_copy['_id']  # Add offer name
            items.append(item_copy)
    logging.debug(f"Main items with details: {items}")
    return items

def get_item_details_cached(tpl):
    if tpl in item_cache:
        logging.debug(f"Cache hit for tpl {tpl}")
        return item_cache[tpl]
    else:
        logging.debug(f"Cache miss for tpl {tpl}, fetching from API")
        item_details = get_items_details([tpl])
        if tpl in item_details:
            item_cache[tpl] = item_details[tpl]
            save_item_cache()
        return item_details.get(tpl, {})

def get_items_details(tpls):
    queries = "\n".join([
        f'item{index}: item(id: "{tpl}") {{ id name shortName description basePrice image512pxLink wikiLink }}'
        for index, tpl in enumerate(tpls)
    ])
    query = f"{{ {queries} }}"
    try:
        response = requests.post(TARKOV_API_URL, json={'query': query})
        data = response.json()
        logging.debug(f"Item details for tpls {tpls}: {data}")
        return {tpl: data['data'][f'item{index}'] for index, tpl in enumerate(tpls)}
    except Exception as e:
        logging.error(f"Error fetching item details for tpls {tpls}: {e}")
        logging.error(traceback.format_exc())
        return {}

def get_item_parts_with_details(parent_id, assort_data):
    parts = []
    def fetch_parts(parent_id):
        sub_parts = []
        for item in assort_data['items']:
            if item['parentId'] == parent_id:
                part_copy = item.copy()  # Create a copy of the part to avoid modifying the original
                part_copy['details'] = get_item_details_cached(part_copy['_tpl'])
                part_copy['parts'] = fetch_parts(part_copy['_id'])  # Fetch sub-parts recursively
                sub_parts.append(part_copy)
        return sub_parts
    parts = fetch_parts(parent_id)
    logging.debug(f"Parts for parent_id {parent_id}: {parts}")
    return parts

def get_barter_scheme_with_details(item_id, assort_data):
    barter_scheme = []
    if 'barter_scheme' in assort_data:
        for scheme in assort_data['barter_scheme'].get(item_id, []):
            scheme_details = []
            for req in scheme:
                req_copy = req.copy()  # Create a copy of the req to avoid modifying the original
                req_details = get_item_details_cached(req_copy['_tpl'])
                req_copy['details'] = req_details
                scheme_details.append(req_copy)
            barter_scheme.append(scheme_details)
    logging.debug(f"Barter scheme for item_id {item_id}: {barter_scheme}")
    return barter_scheme

def get_quest_requirement(item_id):
    for quest_type, quests in quest_assort_data.items():
        if item_id in quests:
            return {
                "type": quest_type,
                "quest": quests[item_id]
            }
    return None

@app.route('/edit/<item_id>', methods=['GET', 'POST'])
def edit_item(item_id):
    try:
        if request.method == 'POST':
            # Handle form submission
            new_barter_scheme = []
            tpl_list = request.form.getlist('barter_tpl')
            count_list = request.form.getlist('barter_count')
            scheme = []
            for i in range(len(tpl_list)):
                scheme.append({
                    '_tpl': tpl_list[i],
                    'count': int(count_list[i])
                })
            new_barter_scheme.append(scheme)
            update_barter_scheme(item_id, new_barter_scheme)
            return redirect(url_for('index'))

        item = next((item for item in assort_data['items'] if item['_id'] == item_id), None)
        if item:
            item_copy = item.copy()  # Create a copy of the item to avoid modifying the original
            item_copy['details'] = get_item_details_cached(item_copy['_tpl'])
            item_copy['parts'] = get_item_parts_with_details(item_id, assort_data)
            item_copy['barter_scheme'] = get_barter_scheme_with_details(item_id, assort_data)
            item_copy['quest_requirement'] = get_quest_requirement(item_id)
            ruble_image = get_ruble_image()
            return render_template('edit.html', item=item_copy, ruble_image=ruble_image)
        else:
            return "Item not found", 404
    except Exception as e:
        logging.error(f"Error in edit_item route: {e}")
        logging.error(traceback.format_exc())
        return "Error editing item", 500

def update_barter_scheme(item_id, new_barter_scheme):
    try:
        assort_data['barter_scheme'][item_id] = new_barter_scheme
        save_assort_data()
    except Exception as e:
        logging.error(f"Error updating barter scheme for item {item_id}: {e}")
        logging.error(traceback.format_exc())

def save_assort_data():
    try:
        # Deep copy the assort data and remove 'details' key before saving
        cleaned_assort_data = json.loads(json.dumps(assort_data))  # Deep copy

        # Clean items
        for item in cleaned_assort_data['items']:
            if 'details' in item:
                del item['details']

        # Clean barter_scheme
        for item_id, schemes in cleaned_assort_data.get('barter_scheme', {}).items():
            for scheme in schemes:
                for part in scheme:
                    if 'details' in part:
                        del part['details']
        
        with open(ASSORT_FILE_PATH, 'w') as f:
            json.dump(cleaned_assort_data, f, indent=2)  # Use 2 spaces for indentation
            logging.debug("Assort data saved successfully")
    except Exception as e:
        logging.error(f"Error saving assort data: {e}")
        logging.error(traceback.format_exc())

def save_item_cache():
    try:
        with open(CACHE_FILE_PATH, 'w') as f:
            json.dump(item_cache, f, indent=2)  # Use 2 spaces for indentation
            logging.debug("Item cache saved successfully")
    except Exception as e:
        logging.error(f"Error saving item cache: {e}")
        logging.error(traceback.format_exc())

@app.route('/item_image/<tpl>')
def item_image(tpl):
    details = get_item_details_cached(tpl)
    return jsonify({'image512pxLink': details.get('image512pxLink', ''), 'name': details.get('name', '')})

if __name__ == '__main__':
    app.run(debug=True)