from flask import Blueprint, render_template, request, flash, redirect, url_for, jsonify, current_app
from flask_login import login_required, current_user
from app.extensions import db
from app.models.company import Company
from app.models.user import User
from app.models.project import Project
from app.models.contract import Contract
from app.models.module import Module
from app.models.company_module import CompanyModule
from app.models.user_module import UserModulePermission
from app.models.project_access import ProjectAccess
from app.models.license import License, LicenseModule
from app.models.aufmass import Aufmass
from app.models.position import Position
from app.models.settings import Settings

superadmin_bp = Blueprint('superadmin', __name__)

def _require_superadmin():
    if not current_user.is_superadmin():
        flash('Nur für Superadmins.', 'danger')
        return False
    return True

@superadmin_bp.route('/')
@login_required
def dashboard():
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    firmsen = Company.query.order_by(Company.name).all()
    gesamt_user = User.query.count()
    gesamt_projekte = Project.query.count()

    all_licenses = License.query.all()
    gesamt_lizenzen = len(all_licenses)
    gesamt_max_mitarbeiter = sum((l.max_mitarbeiter or 0) for l in all_licenses if not l.unlimited_users)
    # Unlimited companies count as "max" being their actual user count
    for l in all_licenses:
        if l.unlimited_users:
            gesamt_max_mitarbeiter += l.used_users
    gesamt_max_module_slots = sum((l.max_module_slots or 0) for l in all_licenses if not l.unlimited_modules)
    for l in all_licenses:
        if l.unlimited_modules:
            gesamt_max_module_slots += l.used_module_slots
    gesamt_module_anzahl = Module.query.count()
    belegte_module_slots = db.session.query(UserModulePermission.id)\
        .filter(UserModulePermission.aktiv==True).count()

    for f in firmsen:
        f._user_count = User.query.filter_by(company_id=f.id).count()
        lic = License.query.filter_by(company_id=f.id, aktiv=True).first()
        if lic:
            f._license_slots = '\u221e' if lic.unlimited_users else f'{f._user_count} / {lic.max_mitarbeiter}'
            f._module_slots = '\u221e' if lic.unlimited_modules else f'{lic.used_module_slots} / {lic.max_module_slots}'
            f._licensed_modules = LicenseModule.query.filter_by(license_id=lic.id, aktiv=True).count()
        else:
            f._license_slots = '–'
            f._module_slots = '–'
            f._licensed_modules = 0

    reg_enabled = Settings.get('registration_enabled', 'false') == 'true'
    return render_template('superadmin/dashboard.html', titel='Superadmin',
                         firmsen=firmsen, gesamt_user=gesamt_user,
                         gesamt_projekte=gesamt_projekte,
                         gesamt_lizenzen=gesamt_lizenzen,
                         gesamt_max_mitarbeiter=gesamt_max_mitarbeiter,
                         gesamt_max_module_slots=gesamt_max_module_slots,
                         gesamt_module_anzahl=gesamt_module_anzahl,
                         belegte_module_slots=belegte_module_slots,
                         registration_enabled=reg_enabled)

@superadmin_bp.route('/firma/neu', methods=['GET', 'POST'])
@login_required
def firma_create():
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    if request.method == 'POST':
        name = request.form.get('name', '').strip()
        if not name:
            flash('Firmenname ist erforderlich.', 'danger')
            return render_template('superadmin/firma_form.html', titel='Neue Firma', company=None)
        slug = name.lower().replace(' ', '-').replace('ä','ae').replace('ö','oe').replace('ü','ue')[:100]
        base_slug = slug
        counter = 1
        while Company.query.filter_by(slug=slug).first():
            slug = f"{base_slug}-{counter}"
            counter += 1
        company = Company(
            name=name, slug=slug,
            strasse=request.form.get('strasse', '').strip(),
            house_number=request.form.get('house_number', '').strip(),
            plz=request.form.get('plz', '').strip(),
            ort=request.form.get('ort', '').strip(),
            telefon=request.form.get('telefon', '').strip(),
            email=request.form.get('email', '').strip(),
            aktiv=True
        )
        db.session.add(company)
        db.session.flush()

        # Optional: Firmadmin-User direkt anlegen
        admin_email = request.form.get('admin_email', '').strip()
        admin_password = request.form.get('admin_password', '').strip()
        if admin_email and admin_password:
            if User.query.filter_by(email=admin_email).first():
                flash('E-Mail existiert bereits. Firma wurde trotzdem angelegt.', 'warning')
            else:
                user = User(
                    company_id=company.id, email=admin_email,
                    vorname=request.form.get('admin_vorname', '').strip(),
                    nachname=request.form.get('admin_nachname', '').strip(),
                    rolle='firmadmin',
                    darf_projekte_anlegen=True, darf_lv_verwalten=True,
                    darf_preise_sehen=True, darf_aufmass_verwalten=True,
                )
                user.set_password(admin_password)
                db.session.add(user)

        db.session.commit()
        flash(f'Firma "{name}" angelegt.', 'success')
        return redirect(url_for('superadmin.firma_detail', company_id=company.id))
    return render_template('superadmin/firma_form.html', titel='Neue Firma', company=None)

@superadmin_bp.route('/firma/<int:company_id>/edit', methods=['GET', 'POST'])
@login_required
def firma_edit(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    if request.method == 'POST':
        company.name = request.form.get('name', company.name).strip()
        company.strasse = request.form.get('strasse', '').strip()
        company.house_number = request.form.get('house_number', '').strip()
        company.plz = request.form.get('plz', '').strip()
        company.ort = request.form.get('ort', '').strip()
        company.telefon = request.form.get('telefon', '').strip()
        company.email = request.form.get('email', '').strip()
        db.session.commit()
        flash('Firmendaten aktualisiert.', 'success')
        return redirect(url_for('superadmin.firma_detail', company_id=company.id))
    return render_template('superadmin/firma_form.html', titel=f'Firma bearbeiten: {company.name}', company=company)

@superadmin_bp.route('/firma/<int:company_id>/user/neu', methods=['POST'])
@login_required
def firma_user_create(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    email = request.form.get('email', '').strip()
    if not email:
        flash('E-Mail ist erforderlich.', 'danger')
        return redirect(url_for('superadmin.firma_detail', company_id=company.id))
    if User.query.filter_by(email=email).first():
        flash('E-Mail existiert bereits.', 'danger')
        return redirect(url_for('superadmin.firma_detail', company_id=company.id))
    password = request.form.get('password', '').strip()
    if not password:
        flash('Passwort ist erforderlich.', 'danger')
        return redirect(url_for('superadmin.firma_detail', company_id=company.id))
    rolle = request.form.get('rolle', 'mitarbeiter')
    if rolle not in ('mitarbeiter', 'firmadmin'):
        rolle = 'mitarbeiter'
    user = User(
        company_id=company.id, email=email,
        vorname=request.form.get('vorname', '').strip(),
        nachname=request.form.get('nachname', '').strip(),
        rolle=rolle,
        darf_projekte_anlegen=bool(request.form.get('darf_projekte_anlegen')),
        darf_lv_verwalten=bool(request.form.get('darf_lv_verwalten')),
        darf_preise_sehen=bool(request.form.get('darf_preise_sehen')),
        darf_aufmass_verwalten=bool(request.form.get('darf_aufmass_verwalten')),
        darf_evergabe_nutzen=bool(request.form.get('darf_evergabe_nutzen')),
        darf_kopfdaten_holen=bool(request.form.get('darf_kopfdaten_holen')),
        darf_aufmass_uebertragen=bool(request.form.get('darf_aufmass_uebertragen')),
    )
    user.set_password(password)
    db.session.add(user)
    db.session.commit()
    flash(f'Benutzer {user.full_name} angelegt.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=company.id))

@superadmin_bp.route('/firma/<int:company_id>')
@login_required
def firma_detail(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    users = User.query.filter_by(company_id=company.id).order_by(User.email).all()
    projekte = Project.query.filter_by(company_id=company.id).order_by(Project.erstellt_am.desc()).all()
    licenses = License.query.filter_by(company_id=company.id).order_by(License.erstellt_am.desc()).all()
    contracts = Contract.query.filter_by(company_id=company.id).order_by(Contract.name).all()
    modules = Module.query.order_by(Module.sortierung).all()
    company_modules = {cm.module_id for cm in CompanyModule.query.filter_by(company_id=company.id, aktiv=True).all()}
    all_modules = Module.query.order_by(Module.sortierung).all()
    return render_template('superadmin/firma_detail.html', company=company,
                         users=users, projekte=projekte, licenses=licenses,
                         contracts=contracts, modules=modules,
                         company_modules=company_modules, all_modules=all_modules,
                         titel=f'Firma: {company.name}')

@superadmin_bp.route('/firma/<int:company_id>/toggle')
@login_required
def firma_toggle(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    company.aktiv = not company.aktiv
    db.session.commit()
    flash(f'Firma {"aktiviert" if company.aktiv else "deaktiviert"}.', 'success')
    return redirect(url_for('superadmin.dashboard'))

@superadmin_bp.route('/user/<int:user_id>/toggle')
@login_required
def user_toggle(user_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    user = User.query.get_or_404(user_id)
    user.aktiv = not user.aktiv
    db.session.commit()
    flash(f'User {"aktiviert" if user.aktiv else "deaktiviert"}.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=user.company_id))

@superadmin_bp.route('/user/<int:user_id>/make-superadmin')
@login_required
def user_make_superadmin(user_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    user = User.query.get_or_404(user_id)
    if user.is_superadmin():
        user.rolle = 'firmadmin'
    else:
        user.rolle = 'superadmin'
    db.session.commit()
    flash(f'User {user.email} ist jetzt {user.rolle}.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=user.company_id))

@superadmin_bp.route('/user/<int:user_id>/loeschen', methods=['POST'])
@login_required
def user_loeschen(user_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    user = User.query.get_or_404(user_id)
    if user.id == current_user.id:
        flash('Sie können sich nicht selbst löschen.', 'danger')
        return redirect(url_for('superadmin.firma_detail', company_id=user.company_id))
    email = user.email
    ProjectAccess.query.filter_by(user_id=user.id).delete()
    UserModulePermission.query.filter_by(user_id=user.id).delete()
    db.session.delete(user)
    db.session.commit()
    flash(f'Benutzer {email} gelöscht.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=user.company_id))

@superadmin_bp.route('/company/<int:company_id>/module/<int:module_id>/toggle')
@login_required
def company_module_toggle(company_id, module_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    cm = CompanyModule.query.filter_by(company_id=company_id, module_id=module_id).first()
    if cm:
        cm.aktiv = not cm.aktiv
    else:
        cm = CompanyModule(company_id=company_id, module_id=module_id, aktiv=True)
        db.session.add(cm)
    db.session.commit()
    return redirect(url_for('superadmin.firma_detail', company_id=company_id))

@superadmin_bp.route('/firma/<int:company_id>/license/create', methods=['POST'])
@login_required
def license_create(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    max_mitarbeiter = request.form.get('max_mitarbeiter', type=int) or 5
    max_module_slots = request.form.get('max_module_slots', type=int) or 5
    unlimited_users = bool(request.form.get('unlimited_users'))
    unlimited_modules = bool(request.form.get('unlimited_modules'))
    uid = License.generate_uid(company.name)
    lic = License(company_id=company_id, uid=uid,
                  max_mitarbeiter=max_mitarbeiter,
                  max_module_slots=max_module_slots,
                  unlimited_users=unlimited_users,
                  unlimited_modules=unlimited_modules)
    db.session.add(lic)
    db.session.flush()
    # Assign selected modules
    mod_ids = request.form.getlist('modules')
    for mid in mod_ids:
        db.session.add(LicenseModule(license_id=lic.id, module_id=int(mid), aktiv=True))
    db.session.commit()
    flash('Lizenz angelegt.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=company_id))

@superadmin_bp.route('/license/<int:license_id>/edit', methods=['POST'])
@login_required
def license_edit(license_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    lic = License.query.get_or_404(license_id)
    lic.max_mitarbeiter = request.form.get('max_mitarbeiter', type=int) or lic.max_mitarbeiter
    lic.max_module_slots = request.form.get('max_module_slots', type=int) or lic.max_module_slots
    lic.unlimited_users = bool(request.form.get('unlimited_users'))
    lic.unlimited_modules = bool(request.form.get('unlimited_modules'))
    # Update module assignments
    new_mod_ids = set(int(x) for x in request.form.getlist('modules'))
    for lm in lic.modules.filter_by(aktiv=True).all():
        if lm.module_id not in new_mod_ids:
            lm.aktiv = False
    existing_ids = {lm.module_id for lm in lic.modules.filter_by(aktiv=True).all()}
    for mid in new_mod_ids:
        if mid not in existing_ids:
            db.session.add(LicenseModule(license_id=lic.id, module_id=mid, aktiv=True))
    db.session.commit()
    flash('Lizenz aktualisiert.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=lic.company_id))

@superadmin_bp.route('/license/<int:license_id>/delete', methods=['POST'])
@login_required
def license_delete(license_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    lic = License.query.get_or_404(license_id)
    company_id = lic.company_id
    db.session.delete(lic)
    db.session.commit()
    flash('Lizenz gelöscht.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=company_id))

@superadmin_bp.route('/license/<int:license_id>/module/<int:module_id>/toggle')
@login_required
def license_module_toggle(license_id, module_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    lm = LicenseModule.query.filter_by(license_id=license_id, module_id=module_id).first()
    if lm:
        lm.aktiv = not lm.aktiv
    else:
        lm = LicenseModule(license_id=license_id, module_id=module_id, aktiv=True)
        db.session.add(lm)
    db.session.commit()
    lic = License.query.get(license_id)
    return redirect(url_for('superadmin.firma_detail', company_id=lic.company_id))

@superadmin_bp.route('/firma/<int:company_id>/evergabe/toggle')
@login_required
def firma_evergabe_toggle(company_id):
    if not _require_superadmin():
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get_or_404(company_id)
    company.evergabe_aktiviert = not company.evergabe_aktiviert
    db.session.commit()
    flash(f'E-Vergabe Addon {"freigeschaltet" if company.evergabe_aktiviert else "deaktiviert"}.', 'success')
    return redirect(url_for('superadmin.firma_detail', company_id=company_id))

@superadmin_bp.route('/registration/toggle')
@login_required
def registration_toggle():
    if not _require_superadmin():
        if request.headers.get('HX-Request'):
            return jsonify({'error': 'Zugriff verweigert'}), 403
        return redirect(url_for('admin.dashboard'))
    current = Settings.get('registration_enabled', 'false') == 'true'
    Settings.set('registration_enabled', 'false' if current else 'true')
    current_app.config['REGISTRATION_ENABLED'] = not current
    if request.headers.get('HX-Request'):
        return jsonify({'ok': True, 'registration_enabled': not current})
    flash(f'Registrierung {"aktiviert" if not current else "deaktiviert"}.', 'success')
    return redirect(url_for('superadmin.dashboard'))

@superadmin_bp.route('/registration/status')
@login_required
def registration_status():
    if not _require_superadmin():
        return jsonify({'error': 'Zugriff verweigert'}), 403
    enabled = Settings.get('registration_enabled', 'false') == 'true'
    return jsonify({'registration_enabled': enabled})
