import pandas as pd
import json
import os
import uuid
from datetime import datetime

# --- KONFIGURATION ---
EXCEL_FILE = 'hardware_import.xlsx'
JSON_FILE = 'db/hardware/test_equipment_data.json'
BACKUP_FILE = f'db/hardware/test_equipment_data_backup_{int(datetime.now().timestamp())}.json'


def load_existing_data():
    """Lädt die bestehende JSON-Datenbank."""
    if os.path.exists(JSON_FILE):
        print(f"Lade existierende Datenbank: {JSON_FILE}")
        # Backup erstellen
        import shutil
        try:
            shutil.copy(JSON_FILE, BACKUP_FILE)
            print(f"Backup erstellt: {BACKUP_FILE}")
        except Exception as e:
            print(f"WARNUNG: Backup konnte nicht erstellt werden: {e}")

        with open(JSON_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    else:
        print("Keine existierende Datenbank gefunden. Erstelle neu.")
        return {
            "inventory": {}, "boms": {}, "mappings": {},
            "trolleys": {}, "storage_units": {}
        }


def recalculate_kit_status_local(data):
    """
    Kopie der Server-Logik, damit der Import konsistente Daten erzeugt.
    Berechnet Kit-Status und weist Teile zu.
    """
    print("--- Starte lokale Kit-Neuberechnung ---")
    inventory = data.get('inventory', {})
    boms = data.get('boms', {})

    # 1. Pool verfügbarer Teile aufbauen
    pool = {}
    for pn, part in inventory.items():
        pool[pn] = []
        for serial in part.get('serials', []):
            # Reset Zuweisung
            serial['kitId'] = 'N/A'
            if serial.get('status') == 'Available':
                pool[pn].append(serial)

    # 2. Kits prüfen
    for kit_id, kit in boms.items():
        items_needed = kit.get('items', [])
        if not items_needed:
            kit['status'] = 'missing'
            continue

        is_fully_ready = True
        is_partial = False

        for item in items_needed:
            needed_pn = item.get('partNumber')
            needed_qty = int(item.get('quantity', 1))
            available_sns = pool.get(needed_pn, [])

            if len(available_sns) >= needed_qty:
                # Genug da -> Zuweisen
                for _ in range(needed_qty):
                    sn_obj = available_sns.pop(0)
                    sn_obj['kitId'] = kit_id  # UUID zuweisen
                is_partial = True
            elif len(available_sns) > 0:
                # Teilweise
                for _ in range(len(available_sns)):
                    sn_obj = available_sns.pop(0)
                    sn_obj['kitId'] = kit_id
                is_partial = True
                is_fully_ready = False
            else:
                is_fully_ready = False

        if is_fully_ready:
            kit['status'] = 'ready'
        elif is_partial:
            kit['status'] = 'partial'
        else:
            kit['status'] = 'missing'


def process_excel():
    if not os.path.exists(EXCEL_FILE):
        print(f"FEHLER: Excel-Datei '{EXCEL_FILE}' nicht gefunden.")
        return

    try:
        df = pd.read_excel(EXCEL_FILE, dtype=str)
        df = df.fillna('')
    except Exception as e:
        print(f"FEHLER beim Lesen der Excel: {e}")
        return

    data = load_existing_data()
    inventory = data.get('inventory', {})

    new_count = 0
    update_count = 0

    # Set für IDs, die in DIESEM Durchlauf schon bearbeitet wurden
    processed_ids = set()

    for index, row in df.iterrows():
        pn = row.get('P/N', '').strip()
        sn = row.get('S/N', '').strip()

        # KORREKTUR 1: Nur P/N ist Pflicht. Wenn S/N fehlt, setzen wir "N/A"
        if not pn:
            continue
        if not sn:
            sn = "N/A"

        # Haupt-Eintrag für P/N
        if pn not in inventory:
            inventory[pn] = {
                "name": row.get('Name', '').strip(),
                "type": row.get('Hardware Type', '').strip(),
                "productType": [pt.strip() for pt in row.get('Product Type', '').split(',') if pt.strip()],
                "description": row.get('Description', '').strip(),
                "serials": []
            }

        serials_list = inventory[pn]['serials']

        # KORREKTUR 2: Wir suchen einen Eintrag mit gleicher S/N,
        # der aber HEUTE noch nicht angefasst wurde.
        existing_serial = None
        for s in serials_list:
            # Vergleich der S/N und Prüfung, ob ID schon verbraucht ist
            if s['sn'] == sn and s['id'] not in processed_ids:
                existing_serial = s
                break

        if existing_serial:
            # Update existierendes Teil (wird nur 1x pro ID gemacht)
            if row.get('Location'): existing_serial['location'] = row.get('Location', '').strip()
            if row.get('Status'): existing_serial['status'] = row.get('Status', '').strip()
            if row.get('Last Check'): existing_serial['lastCheck'] = row.get('Last Check', '').strip()

            # ID als "verbraucht" markieren
            processed_ids.add(existing_serial['id'])
            update_count += 1
        else:
            # Neu erstellen (weil S/N neu ist ODER alle existierenden "N/A"-Einträge schon verbraucht sind)
            new_id = f"hw_{uuid.uuid4().hex[:12]}"
            new_serial_entry = {
                "id": new_id,
                "sn": sn,
                "location": row.get('Location', '').strip(),
                "status": row.get('Status', 'Available').strip(),
                "lastCheck": row.get('Last Check', '').strip(),
                "maintenanceId": "N/A",
                "kitId": "N/A",
                "documents": [],
                "maintenanceLinks": [],
                "statusSummary": {"light": "GREEN", "nextDue": "N/A", "openIssues": 0, "issueList": []}
            }
            serials_list.append(new_serial_entry)

            # Neue ID auch als verbraucht markieren
            processed_ids.add(new_id)
            new_count += 1

    # Konsistenz prüfen
    recalculate_kit_status_local(data)

    try:
        data['inventory'] = inventory
        os.makedirs(os.path.dirname(JSON_FILE), exist_ok=True)
        with open(JSON_FILE, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
        print(f"\nERFOLG: Datenbank aktualisiert.")
        print(f"Statistik: {new_count} Teile neu, {update_count} Teile aktualisiert.")
    except Exception as e:
        print(f"FEHLER beim Speichern der JSON: {e}")


if __name__ == '__main__':
    process_excel()