#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Düsseldorfer Schülerinventar (DÜSK) - Python Client
Komplette Desktop-Anwendung für Windows/Mac/Linux
"""

import sys
import subprocess
import requests
import math
import json
from datetime import datetime

# PDF Export
try:
    from reportlab.lib import colors
    from reportlab.lib.pagesizes import A4
    from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "reportlab"])

# GUI
try:
    from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                                  QHBoxLayout, QLabel, QLineEdit, QPushButton, 
                                  QTableWidget, QTableWidgetItem, QMessageBox,
                                  QHeaderView, QDialog, QDialogButtonBox, 
                                  QFormLayout, QProgressDialog, QGroupBox,
                                  QTabWidget, QComboBox, QScrollArea, QTextEdit,
                                  QSplitter, QRadioButton, QButtonGroup,
                                  QFileDialog, QToolBar, QMenu)
    from PyQt6.QtCore import Qt, QThread, pyqtSignal
    from PyQt6.QtGui import QFont, QPainter, QPen, QBrush, QColor, QAction
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "PyQt6", "requests"])
    from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                                  QHBoxLayout, QLabel, QLineEdit, QPushButton, 
                                  QTableWidget, QTableWidgetItem, QMessageBox,
                                  QHeaderView, QDialog, QDialogButtonBox, 
                                  QFormLayout, QProgressDialog, QGroupBox,
                                  QTabWidget, QComboBox, QScrollArea, QTextEdit,
                                  QSplitter, QRadioButton, QButtonGroup,
                                  QFileDialog, QToolBar, QMenu)
    from PyQt6.QtCore import Qt, QThread, pyqtSignal
    from PyQt6.QtGui import QFont, QPainter, QPen, QBrush, QColor, QAction

# ============ API KONFIGURATION ============
API_BASE_URL = "https://paul-koop.org/api/"

# ============ NORMWERTE AUS IHRER DATENBANK ============
NORM_SE_HS = {1: [21.33, 25.33, 29.33, 33.32, 37.32], 2: [20.87, 24.95, 29.03, 33.13, 37.18],
              3: [17.93, 21.37, 24.80, 28.23, 31.67], 4: [13.98, 17.71, 21.44, 25.17, 28.90],
              5: [24.60, 28.55, 33.04, 37.53, 42.01], 6: [15.53, 18.97, 22.40, 25.83, 29.27]}

NORM_FE_HS = {1: [12.66, 18.16, 23.66, 29.16, 34.66], 2: [13.33, 18.42, 23.51, 28.60, 33.69],
              3: [10.75, 15.41, 20.07, 24.73, 29.39], 4: [14.22, 15.30, 16.38, 17.46, 18.54],
              5: [14.12, 20.21, 26.30, 32.39, 38.48], 6: [10.53, 14.51, 18.49, 22.47, 26.45]}

NORM_SE_FS = {1: [17.54, 24.03, 30.53, 37.02, 43.51], 2: [17.80, 24.26, 30.73, 37.19, 43.65],
              3: [18.03, 22.41, 26.79, 31.17, 35.55], 4: [14.28, 15.55, 16.83, 18.10, 19.37],
              5: [20.69, 27.49, 34.29, 41.09, 47.89], 6: [12.44, 18.06, 23.68, 29.29, 34.91]}

NORM_FE_FS = {1: [15.30, 19.79, 24.28, 28.77, 33.26], 2: [14.63, 18.94, 23.25, 27.56, 31.87],
              3: [14.62, 17.81, 21.00, 24.19, 27.38], 4: [15.00, 15.55, 16.10, 16.65, 17.20],
              5: [18.44, 22.61, 26.78, 30.95, 35.12], 6: [9.79, 13.97, 18.15, 22.33, 26.51]}


class APIWorker(QThread):
    finished = pyqtSignal(object)
    error = pyqtSignal(str)
    
    def __init__(self, endpoint, method="GET", data=None, params=None, user_id=None, session=None):
        super().__init__()
        self.endpoint = endpoint
        self.method = method
        self.data = data
        self.params = params
        self.user_id = user_id
        self.session = session
        
    def run(self):
        try:
            url = API_BASE_URL + self.endpoint
            headers = {'Content-Type': 'application/json'}
            if self.user_id and self.session:
                headers['X-User-ID'] = str(self.user_id)
                headers['X-Session'] = self.session
                
            if self.method == "GET":
                response = requests.get(url, headers=headers, params=self.params, timeout=30)
            elif self.method == "POST":
                response = requests.post(url, json=self.data, headers=headers, timeout=30)
            elif self.method == "PUT":
                response = requests.put(url, json=self.data, headers=headers, timeout=30)
            elif self.method == "DELETE":
                response = requests.delete(url, headers=headers, params=self.params, timeout=30)
            else:
                self.error.emit(f"Unbekannte Methode: {self.method}")
                return
                
            if response.status_code == 200:
                self.finished.emit(response.json())
            else:
                self.error.emit(f"HTTP {response.status_code}")
        except Exception as e:
            self.error.emit(str(e))


class ProfileChart(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMinimumSize(500, 250)
        self.se_values = [3, 3, 3, 3, 3, 3]
        self.fe_values = [3, 3, 3, 3, 3, 3]
        self.labels = ["Arbeitsverhalten", "Lernverhalten", "Sozialverhalten", 
                       "Fachkompetenz", "Personale Kompetenz", "Methodenkompetenz"]
        
    def set_values(self, se, fe):
        self.se_values = se[:6]
        self.fe_values = fe[:6]
        self.update()
        
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        w, h = self.width(), self.height()
        top, left = 40, 110
        row_h = (h - 80) / 6
        chart_w = w - 130
        
        # Gitter
        painter.setPen(QPen(QColor(200, 200, 200), 1))
        for i in range(7):
            y = top + i * row_h
            painter.drawLine(left - 5, y, left + chart_w, y)
        for i in range(6):
            x = left + i * (chart_w / 5)
            painter.drawLine(x, top, x, top + row_h * 6)
        
        # Beschriftungen
        painter.setFont(QFont("Arial", 9))
        painter.setPen(QColor(0, 0, 0))
        for i, label in enumerate(self.labels):
            y = top + i * row_h + row_h / 2 + 5
            painter.drawText(5, int(y), label)
        for i in range(5):
            x = left + i * (chart_w / 5) + (chart_w / 5) / 2
            painter.drawText(int(x) - 4, top - 10, str(i + 1))
        
        # SE Linie (blau)
        se_points = []
        for i, v in enumerate(self.se_values):
            x = left + (v - 1) * (chart_w / 4)
            y = top + i * row_h + row_h / 2
            se_points.append((int(x), int(y)))
        painter.setPen(QPen(QColor(0, 100, 200), 3))
        for i in range(5):
            painter.drawLine(se_points[i][0], se_points[i][1], se_points[i+1][0], se_points[i+1][1])
        painter.setBrush(QBrush(QColor(0, 100, 200, 100)))
        for x, y in se_points:
            painter.drawEllipse(x - 6, y - 6, 12, 12)
        
        # FE Linie (rot)
        fe_points = []
        for i, v in enumerate(self.fe_values):
            x = left + (v - 1) * (chart_w / 4)
            y = top + i * row_h + row_h / 2
            fe_points.append((int(x), int(y)))
        painter.setPen(QPen(QColor(200, 0, 0), 3))
        for i in range(5):
            painter.drawLine(fe_points[i][0], fe_points[i][1], fe_points[i+1][0], fe_points[i+1][1])
        painter.setBrush(QBrush(QColor(200, 0, 0, 100)))
        for x, y in fe_points:
            painter.drawEllipse(x - 6, y - 6, 12, 12)
        
        # Legende
        painter.setPen(QColor(0, 0, 0))
        painter.setBrush(QBrush(QColor(0, 100, 200)))
        painter.drawEllipse(left + chart_w - 50, top - 20, 8, 8)
        painter.drawText(left + chart_w - 38, top - 14, "SE")
        painter.setBrush(QBrush(QColor(200, 0, 0)))
        painter.drawEllipse(left + chart_w - 20, top - 20, 8, 8)
        painter.drawText(left + chart_w - 8, top - 14, "FE")


class ProfileViewDialog(QDialog):
    def __init__(self, profile_data, parent=None):
        super().__init__(parent)
        self.profile = profile_data
        self.current_norm = "HS"
        self.init_ui()
        self.calculate()
        
    def init_ui(self):
        self.setWindowTitle(f"Profil: {self.profile.get('name', 'Unbekannt')}")
        self.setMinimumSize(1100, 800)
        
        layout = QVBoxLayout()
        
        # Kopfzeile
        header = QHBoxLayout()
        header.addWidget(QLabel(f"<h2>{self.profile.get('name', 'Unbekannt')}</h2>"))
        header.addStretch()
        pdf_btn = QPushButton("PDF Export")
        pdf_btn.setStyleSheet("background-color: #f44336; color: white; padding: 5px 15px;")
        pdf_btn.clicked.connect(self.export_pdf)
        header.addWidget(pdf_btn)
        layout.addLayout(header)
        
        # Normauswahl
        norm_row = QHBoxLayout()
        norm_row.addWidget(QLabel("Normtabelle:"))
        self.norm_combo = QComboBox()
        self.norm_combo.addItem("Hauptschule (HS)", "HS")
        self.norm_combo.addItem("Förderschule (FS)", "FS")
        self.norm_combo.currentIndexChanged.connect(self.on_norm_change)
        norm_row.addWidget(self.norm_combo)
        norm_row.addStretch()
        layout.addLayout(norm_row)
        
        # Diagramm
        chart_group = QGroupBox("Profil-Diagramm")
        self.chart = ProfileChart()
        chart_group.setLayout(QVBoxLayout())
        chart_group.layout().addWidget(self.chart)
        layout.addWidget(chart_group)
        
        # Tabellen nebeneinander
        tables = QHBoxLayout()
        self.se_table = self.create_table("Selbsteinschätzung (SE)")
        self.fe_table = self.create_table("Fremdeinschätzung (FE)")
        tables.addWidget(self.se_table)
        tables.addWidget(self.fe_table)
        layout.addLayout(tables)
        
        # Statistik
        stats = QGroupBox("Statistische Auswertung")
        stats_layout = QVBoxLayout()
        self.corr_label = QLabel()
        self.agree_label = QLabel()
        self.analysis = QTextEdit()
        self.analysis.setReadOnly(True)
        self.analysis.setMaximumHeight(120)
        stats_layout.addWidget(self.corr_label)
        stats_layout.addWidget(self.agree_label)
        stats_layout.addWidget(self.analysis)
        stats.setLayout(stats_layout)
        layout.addWidget(stats)
        
        # Items (erste 10)
        items_group = QGroupBox("Item-Werte (erste 10)")
        self.items_table = QTableWidget(10, 3)
        self.items_table.setHorizontalHeaderLabels(["Item", "SE", "FE"])
        self.items_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        items_group.setLayout(QVBoxLayout())
        items_group.layout().addWidget(self.items_table)
        layout.addWidget(items_group)
        
        # Schließen
        close_btn = QPushButton("Schließen")
        close_btn.setStyleSheet("background-color: #6699CC; color: white; padding: 8px;")
        close_btn.clicked.connect(self.accept)
        layout.addWidget(close_btn)
        
        self.setLayout(layout)
        
    def create_table(self, title):
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.addWidget(QLabel(f"<b>{title}</b>", alignment=Qt.AlignmentFlag.AlignCenter))
        table = QTableWidget(6, 5)
        table.setHorizontalHeaderLabels(["1", "2", "3", "4", "5"])
        table.setVerticalHeaderLabels(["Arbeitsverhalten", "Lernverhalten", "Sozialverhalten", 
                                       "Fachkompetenz", "Personale Kompetenz", "Methodenkompetenz"])
        table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
        layout.addWidget(table)
        return widget
        
    def on_norm_change(self):
        self.current_norm = self.norm_combo.currentData()
        self.calculate()
        
    def calculate_sums(self, items):
        sums = [0] * 7
        sums[1] = sum(items[0:10])
        sums[2] = sum(items[10:20])
        sums[3] = sum(items[20:28]) + items[8] + items[9]
        sums[4] = sum(items[28:36])
        sums[5] = items[0] + items[1] + items[5] + items[6] + items[7] + items[8] + items[9] + items[11] + items[12] + items[13] + items[14]
        sums[6] = items[2] + items[3] + items[4] + items[8] + items[9] + items[10] + items[16] + items[17]
        return sums
        
    def get_profile_values(self, sums, norm):
        values = [0] * 6
        for k in range(1, 7):
            placed = False
            for p in range(5):
                if sums[k] < norm[k][p]:
                    values[k-1] = p
                    placed = True
                    break
            if not placed:
                values[k-1] = 4
        return values
        
    def fill_table(self, table, values):
        t = table.findChild(QTableWidget)
        for i, v in enumerate(values):
            for j in range(5):
                t.setItem(i, j, QTableWidgetItem("X" if j == v else ""))
                t.item(i, j).setTextAlignment(Qt.AlignmentFlag.AlignCenter)
        t.resizeColumnsToContents()
        
    def calculate(self):
        # Items auslesen
        se_items = [int(self.profile.get(f'item{i}', 2)) for i in range(1, 37)]
        fe_items = [int(self.profile.get(f'feitem{i}', 2)) for i in range(1, 37)]
        
        # Summen
        se_sums = self.calculate_sums(se_items)
        fe_sums = self.calculate_sums(fe_items)
        
        # Normen
        if self.current_norm == "HS":
            norm_se, norm_fe = NORM_SE_HS, NORM_FE_HS
        else:
            norm_se, norm_fe = NORM_SE_FS, NORM_FE_FS
        
        # Profile (0-4)
        se_prof = self.get_profile_values(se_sums, norm_se)
        fe_prof = self.get_profile_values(fe_sums, norm_fe)
        
        # Für Diagramm (1-5)
        se_chart = [v + 1 for v in se_prof]
        fe_chart = [v + 1 for v in fe_prof]
        
        # Tabellen füllen
        self.fill_table(self.se_table, se_prof)
        self.fill_table(self.fe_table, fe_prof)
        self.chart.set_values(se_chart, fe_chart)
        
        # Korrelation
        corr = self.calc_correlation(se_chart, fe_chart)
        agree = sum(1 for s, f in zip(se_items, fe_items) if s == f) * 100 / 36
        
        self.corr_label.setText(f"<b>Korrelation:</b> {corr:.2f}")
        self.agree_label.setText(f"<b>Übereinstimmung:</b> {agree:.1f}%")
        
        # Auswertung
        ratings = ["weit unterdurchschnittlich", "unterdurchschnittlich", "durchschnittlich", 
                   "überdurchschnittlich", "weit überdurchschnittlich"]
        komp = ["Arbeitsverhalten", "Lernverhalten", "Sozialverhalten", 
                "Fachkompetenz", "Personale Kompetenz", "Methodenkompetenz"]
        
        text = "Selbsteinschätzung:\n"
        for i, v in enumerate(se_chart):
            text += f"• {komp[i]}: {ratings[v-1]}\n"
        text += "\nFremdeinschätzung:\n"
        for i, v in enumerate(fe_chart):
            text += f"• {komp[i]}: {ratings[v-1]}\n"
        text += f"\nKorrelation {corr:.2f}: "
        if corr >= 0.8:
            text += "sehr gute Übereinstimmung"
        elif corr >= 0.5:
            text += "mäßige Übereinstimmung"
        elif corr >= 0.3:
            text += "schwache Übereinstimmung"
        else:
            text += "keine signifikante Übereinstimmung"
        self.analysis.setText(text)
        
        # Item-Tabelle
        names = ["Zuverlässigkeit", "Arbeitstempo", "Arbeitsplanung", "Organisationsfähigkeit",
                 "Geschicklichkeit", "Ordnung", "Sorgfalt", "Kreativität", "Problemlösungsfähigkeit",
                 "Abstraktionsvermögen"]
        for i, name in enumerate(names):
            self.items_table.setItem(i, 0, QTableWidgetItem(name))
            self.items_table.setItem(i, 1, QTableWidgetItem(str(se_items[i])))
            self.items_table.setItem(i, 2, QTableWidgetItem(str(fe_items[i])))
            
    def calc_correlation(self, a, b):
        ma, mb = sum(a)/6, sum(b)/6
        num = sum((a[i]-ma)*(b[i]-mb) for i in range(6))
        den = math.sqrt(sum((a[i]-ma)**2 for i in range(6)) * sum((b[i]-mb)**2 for i in range(6)))
        return num/den if den != 0 else 0
        
    def export_pdf(self):
        filename, _ = QFileDialog.getSaveFileName(self, "PDF speichern", 
                                                   f"{self.profile.get('name', 'profil')}.pdf",
                                                   "PDF (*.pdf)")
        if not filename:
            return
        try:
            doc = SimpleDocTemplate(filename, pagesize=A4)
            styles = getSampleStyleSheet()
            story = []
            story.append(Paragraph(f"DÜSK - Profil: {self.profile.get('name', 'Unbekannt')}", 
                                  ParagraphStyle('Title', parent=styles['Heading1'], fontSize=16, alignment=1)))
            story.append(Spacer(1, 20))
            story.append(Paragraph(f"Erstellt: {datetime.now().strftime('%d.%m.%Y %H:%M')}", styles['Normal']))
            story.append(Spacer(1, 20))
            
            # Tabellen für PDF
            story.append(Paragraph("Selbsteinschätzung", styles['Heading2']))
            data = [["Kompetenz", "1", "2", "3", "4", "5"]]
            komp = ["Arbeitsverhalten", "Lernverhalten", "Sozialverhalten", "Fachkompetenz", 
                    "Personale Kompetenz", "Methodenkompetenz"]
            t = self.se_table.findChild(QTableWidget)
            for i, k in enumerate(komp):
                row = [k]
                for j in range(5):
                    row.append("X" if t.item(i, j) and t.item(i, j).text() == "X" else "")
                data.append(row)
            tbl = Table(data)
            tbl.setStyle(TableStyle([('GRID', (0,0), (-1,-1), 1, colors.black), ('ALIGN', (0,0), (-1,-1), 'CENTER')]))
            story.append(tbl)
            story.append(Spacer(1, 20))
            
            story.append(Paragraph("Fremdeinschätzung", styles['Heading2']))
            data = [["Kompetenz", "1", "2", "3", "4", "5"]]
            t = self.fe_table.findChild(QTableWidget)
            for i, k in enumerate(komp):
                row = [k]
                for j in range(5):
                    row.append("X" if t.item(i, j) and t.item(i, j).text() == "X" else "")
                data.append(row)
            tbl = Table(data)
            tbl.setStyle(TableStyle([('GRID', (0,0), (-1,-1), 1, colors.black), ('ALIGN', (0,0), (-1,-1), 'CENTER')]))
            story.append(tbl)
            story.append(Spacer(1, 20))
            
            story.append(Paragraph(self.corr_label.text(), styles['Normal']))
            story.append(Paragraph(self.agree_label.text(), styles['Normal']))
            story.append(Spacer(1, 10))
            story.append(Paragraph(self.analysis.toPlainText(), styles['Normal']))
            
            doc.build(story)
            QMessageBox.information(self, "PDF Export", f"Gespeichert: {filename}")
        except Exception as e:
            QMessageBox.critical(self, "Fehler", str(e))


class ProfileEditDialog(QDialog):
    ITEMS = ["Zuverlässigkeit", "Arbeitstempo", "Arbeitsplanung", "Organisationsfähigkeit",
             "Geschicklichkeit", "Ordnung", "Sorgfalt", "Kreativität", "Problemlösungsfähigkeit",
             "Abstraktionsvermögen", "Selbstständigkeit", "Belastbarkeit", "Konzentrationsfähigkeit",
             "Verantwortungsbewusstsein", "Eigeninitiative", "Leistungsbereitschaft", "Auffassungsgabe",
             "Merkfähigkeit", "Motivationsfähigkeit", "Reflektionsfähigkeit", "Teamfähigkeit",
             "Hilfsbereitschaft", "Kontaktfähigkeit", "Respektvoller Umgang", "Kommunikationsfähigkeit",
             "Einfühlungsvermögen", "Konfliktfähigkeit", "Kritikfähigkeit", "Schreiben", "Lesen",
             "Mathematik", "Naturwissenschaft", "Fremdsprachen", "Präsentationsfähigkeit",
             "PC Kenntnisse", "Fächerübergreifendes Denken"]
    
    def __init__(self, user_id, session, profile=None, groups=None, parent=None):
        super().__init__(parent)
        self.user_id, self.session = user_id, session
        self.profile = profile or {}
        self.is_edit = profile is not None
        self.groups = groups or []
        self.se_btns, self.fe_btns = {}, {}
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle("Profil bearbeiten" if self.is_edit else "Neues Profil")
        self.setMinimumSize(900, 700)
        
        layout = QVBoxLayout()
        
        # Name
        form = QFormLayout()
        self.name_edit = QLineEdit()
        self.name_edit.setText(self.profile.get('name', ''))
        form.addRow("Name:", self.name_edit)
        
        self.group_combo = QComboBox()
        for g in self.groups:
            self.group_combo.addItem(g.get('name', ''), g.get('gruppeID'))
        if self.profile.get('gruppeID'):
            idx = self.group_combo.findData(self.profile.get('gruppeID'))
            if idx >= 0:
                self.group_combo.setCurrentIndex(idx)
        form.addRow("Gruppe:", self.group_combo)
        
        self.new_group = QLineEdit()
        self.new_group.setPlaceholderText("Neue Gruppe (optional)")
        form.addRow("Neue Gruppe:", self.new_group)
        layout.addLayout(form)
        
        # Tabs
        tabs = QTabWidget()
        tabs.addTab(self.create_item_tab("Selbsteinschätzung", "se"), "Selbsteinschätzung")
        tabs.addTab(self.create_item_tab("Fremdeinschätzung", "fe"), "Fremdeinschätzung")
        layout.addWidget(tabs)
        
        # Buttons
        btns = QHBoxLayout()
        save = QPushButton("Speichern")
        save.setStyleSheet("background-color: #4CAF50; color: white; padding: 8px;")
        save.clicked.connect(self.save)
        cancel = QPushButton("Abbrechen")
        cancel.clicked.connect(self.reject)
        btns.addStretch()
        btns.addWidget(save)
        btns.addWidget(cancel)
        layout.addLayout(btns)
        
        self.setLayout(layout)
        self.load_values()
        
    def create_item_tab(self, title, prefix):
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        container = QWidget()
        layout = QVBoxLayout(container)
        
        btns = self.se_btns if prefix == "se" else self.fe_btns
        for i, name in enumerate(self.ITEMS, 1):
            group = QGroupBox(f"{i}. {name}")
            hbox = QHBoxLayout()
            bg = QButtonGroup()
            for val, label in [(4, "trifft voll zu"), (3, "trifft zu"), (2, "trifft teilweise zu"), (1, "trifft nicht zu")]:
                rb = QRadioButton(label)
                hbox.addWidget(rb)
                bg.addButton(rb, val)
            group.setLayout(hbox)
            layout.addWidget(group)
            btns[i] = bg
        
        scroll.setWidget(container)
        return scroll
        
    def load_values(self):
        for i in range(1, 37):
            if i in self.se_btns:
                val = self.profile.get(f'item{i}', 2)
                if btn := self.se_btns[i].button(val):
                    btn.setChecked(True)
            if i in self.fe_btns:
                val = self.profile.get(f'feitem{i}', 2)
                if btn := self.fe_btns[i].button(val):
                    btn.setChecked(True)
                    
    def save(self):
        name = self.name_edit.text().strip()
        if not name:
            QMessageBox.warning(self, "Fehler", "Bitte Name eingeben")
            return
            
        data = {'name': name}
        if gid := self.group_combo.currentData():
            data['gruppeID'] = gid
        if ng := self.new_group.text().strip():
            data['namegruppe'] = ng
            
        for i in range(1, 37):
            data[f'item{i}'] = self.se_btns[i].checkedId() if i in self.se_btns and self.se_btns[i].checkedId() != -1 else 2
            data[f'feitem{i}'] = self.fe_btns[i].checkedId() if i in self.fe_btns and self.fe_btns[i].checkedId() != -1 else 2
            
        if self.is_edit:
            data['profilID'] = self.profile.get('profilID')
            worker = APIWorker("api_profiles.php", "PUT", data, user_id=self.user_id, session=self.session)
        else:
            worker = APIWorker("api_profiles.php", "POST", data, user_id=self.user_id, session=self.session)
            
        worker.finished.connect(lambda r: self.save_done(r))
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
        self.progress = QProgressDialog("Speichern...", None, 0, 0, self)
        self.progress.show()
        
    def save_done(self, resp):
        self.progress.close()
        if resp.get('success'):
            QMessageBox.information(self, "Erfolg", "Profil gespeichert")
            self.accept()
        else:
            QMessageBox.critical(self, "Fehler", resp.get('error', 'Unbekannter Fehler'))


class LoginDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.user_id = self.session = None
        self.setWindowTitle("DÜSK - Anmeldung")
        self.setModal(True)
        self.setMinimumSize(350, 250)
        
        layout = QVBoxLayout()
        layout.addWidget(QLabel("DÜSK - Düsseldorfer Schülerinventar", 
                                alignment=Qt.AlignmentFlag.AlignCenter,
                                font=QFont("Arial", 16, QFont.Weight.Bold)))
        
        form = QFormLayout()
        self.user_edit = QLineEdit()
        self.user_edit.setText("gast")
        self.pw_edit = QLineEdit()
        self.pw_edit.setText("gast")
        self.pw_edit.setEchoMode(QLineEdit.EchoMode.Password)
        form.addRow("Benutzername:", self.user_edit)
        form.addRow("Passwort:", self.pw_edit)
        layout.addLayout(form)
        
        btns = QDialogButtonBox()
        login = btns.addButton("Anmelden", QDialogButtonBox.ButtonRole.AcceptRole)
        cancel = btns.addButton("Abbrechen", QDialogButtonBox.ButtonRole.RejectRole)
        login.clicked.connect(self.do_login)
        cancel.clicked.connect(self.reject)
        layout.addWidget(btns)
        
        layout.addWidget(QLabel("Server: paul-koop.org\nBenutzung mit gast/gast möglich",
                                alignment=Qt.AlignmentFlag.AlignCenter,
                                styleSheet="color: gray; font-size: 10px;"))
        self.setLayout(layout)
        
    def do_login(self):
        worker = APIWorker("api_login.php", "POST", 
                          {"username": self.user_edit.text().strip(), 
                           "password": self.pw_edit.text().strip()})
        worker.finished.connect(self.on_success)
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
        self.progress = QProgressDialog("Anmeldung...", None, 0, 0, self)
        self.progress.show()
        
    def on_success(self, resp):
        self.progress.close()
        if resp.get('success') or resp.get('userID'):
            self.user_id = resp['userID']
            self.session = resp['session']
            self.accept()
        else:
            QMessageBox.warning(self, "Fehler", "Anmeldung fehlgeschlagen")


class MainWindow(QMainWindow):
    def __init__(self, user_id, session):
        super().__init__()
        self.user_id, self.session = user_id, session
        self.profiles = []
        self.setWindowTitle("DÜSK - Düsseldorfer Schülerinventar")
        self.setMinimumSize(1000, 600)
        
        central = QWidget()
        self.setCentralWidget(central)
        layout = QVBoxLayout(central)
        
        # Header
        header = QLabel("DÜSK - Düsseldorfer Schülerinventar")
        header.setAlignment(Qt.AlignmentFlag.AlignCenter)
        header.setStyleSheet("font-size: 24px; font-weight: bold; background-color: #6699CC; color: white; padding: 15px;")
        layout.addWidget(header)
        
        # Toolbar
        toolbar = QToolBar()
        new_btn = QPushButton("Neues Profil")
        new_btn.clicked.connect(self.new_profile)
        toolbar.addWidget(new_btn)
        refresh_btn = QPushButton("Aktualisieren")
        refresh_btn.clicked.connect(self.load_profiles)
        toolbar.addWidget(refresh_btn)
        toolbar.addSeparator()
        logout_btn = QPushButton("Abmelden")
        logout_btn.setStyleSheet("background-color: #f44336; color: white;")
        logout_btn.clicked.connect(self.logout)
        toolbar.addWidget(logout_btn)
        self.addToolBar(toolbar)
        
        # Tabelle
        self.table = QTableWidget()
        self.table.setColumnCount(4)
        self.table.setHorizontalHeaderLabels(["Name", "Gruppe", "ProfilID", "Aktion"])
        self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        layout.addWidget(self.table)
        
        # Footer
        footer = QLabel("Paul Koop M.A. - Thomashofstrasse 19, 52070 Aachen")
        footer.setAlignment(Qt.AlignmentFlag.AlignCenter)
        footer.setStyleSheet("background-color: #6699CC; color: white; padding: 10px; margin-top: 10px;")
        layout.addWidget(footer)
        
        self.load_profiles()
        self.load_groups()
        
    def load_groups(self):
        worker = APIWorker("api_groups.php", "GET", user_id=self.user_id, session=self.session)
        worker.finished.connect(lambda r: setattr(self, 'groups', r if isinstance(r, list) else []))
        worker.start()
        
    def load_profiles(self):
        worker = APIWorker("api_profiles.php", "GET", user_id=self.user_id, session=self.session)
        worker.finished.connect(self.on_profiles)
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
    def on_profiles(self, resp):
        if isinstance(resp, list):
            self.profiles = resp
            self.table.setRowCount(len(resp))
            for i, p in enumerate(resp):
                self.table.setItem(i, 0, QTableWidgetItem(p.get('name', '')))
                self.table.setItem(i, 1, QTableWidgetItem(p.get('gruppename', '')))
                self.table.setItem(i, 2, QTableWidgetItem(str(p.get('profilID', ''))))
                
                actions = QWidget()
                hbox = QHBoxLayout(actions)
                hbox.setContentsMargins(0, 0, 0, 0)
                
                view = QPushButton("Anzeigen")
                view.setStyleSheet("background-color: #4CAF50; color: white;")
                view.clicked.connect(lambda _, pid=p.get('profilID'): self.view_profile(pid))
                hbox.addWidget(view)
                
                edit = QPushButton("Bearbeiten")
                edit.clicked.connect(lambda _, pid=p.get('profilID'): self.edit_profile(pid))
                hbox.addWidget(edit)
                
                delete = QPushButton("Löschen")
                delete.setStyleSheet("background-color: #f44336; color: white;")
                delete.clicked.connect(lambda _, pid=p.get('profilID'): self.delete_profile(pid))
                hbox.addWidget(delete)
                
                self.table.setCellWidget(i, 3, actions)
            self.table.resizeRowsToContents()
            
    def view_profile(self, pid):
        worker = APIWorker("api_profiles.php", "GET", params={"id": pid},
                          user_id=self.user_id, session=self.session)
        worker.finished.connect(lambda r: ProfileViewDialog(r).exec() if isinstance(r, dict) else None)
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
    def edit_profile(self, pid):
        worker = APIWorker("api_profiles.php", "GET", params={"id": pid},
                          user_id=self.user_id, session=self.session)
        worker.finished.connect(lambda r: self.open_editor(r))
        worker.start()
        
    def open_editor(self, profile):
        if isinstance(profile, dict):
            dlg = ProfileEditDialog(self.user_id, self.session, profile, getattr(self, 'groups', []))
            if dlg.exec():
                self.load_profiles()
                
    def new_profile(self):
        dlg = ProfileEditDialog(self.user_id, self.session, groups=getattr(self, 'groups', []))
        if dlg.exec():
            self.load_profiles()
            
    def delete_profile(self, pid):
        if QMessageBox.question(self, "Löschen", "Profil wirklich löschen?") == QMessageBox.StandardButton.Yes:
            worker = APIWorker("api_profiles.php", "DELETE", params={"id": pid},
                              user_id=self.user_id, session=self.session)
            worker.finished.connect(lambda r: self.load_profiles())
            worker.start()
            
    def logout(self):
        APIWorker("api_logout.php", "POST", user_id=self.user_id, session=self.session).start()
        self.close()


def main():
    app = QApplication(sys.argv)
    login = LoginDialog()
    if login.exec() == QDialog.DialogCode.Accepted:
        win = MainWindow(login.user_id, login.session)
        win.show()
        sys.exit(app.exec())
    else:
        sys.exit(0)

if __name__ == "__main__":
    main()
