import os
from flask import Blueprint, render_template, redirect, url_for, request, flash
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.license import License, LicenseModule
from app.models.module import Module
from app.models.company_module import CompanyModule
from app.models.user_module import UserModulePermission
from app.services.license_service import get_aktive_module
from app.models.project import Project
from app.models.contract import Contract
from app.models.lv import LVPosition
from app.models.project_access import ProjectAccess

admin_bp = Blueprint('admin', __name__)

def _get_sichtbare_projekte():
    if current_user.is_firmadmin():
        return Project.query.filter_by(company_id=current_user.company_id)
    zugriff_ids = db.session.query(ProjectAccess.project_id).filter_by(
        user_id=current_user.id
    ).subquery()
    return Project.query.filter(Project.id.in_(zugriff_ids))

@admin_bp.route('/')
@login_required
def dashboard():
    if current_user.is_superadmin():
        return redirect(url_for('superadmin.dashboard'))
    modules = get_aktive_module(current_user.company_id, user=current_user)
    projekte_query = _get_sichtbare_projekte()
    projekte_anzahl = projekte_query.filter(Project.status == 'aktiv').count()
    letztes_projekt = projekte_query.order_by(Project.erstellt_am.desc()).first()
    contracts = Contract.query.filter_by(
        company_id=current_user.company_id
    ).order_by(Contract.name).all()
    lv_names = [r[0] for r in db.session.query(LVPosition.lv_name).filter_by(
        company_id=current_user.company_id
    ).distinct().order_by(LVPosition.lv_name).all()]

    # Project sums
    projekte = projekte_query.order_by(Project.sm_nr).all()
    from app.models.position import Position
    from app.models.aufmass import Aufmass
    projekte_mit_summe = []
    gesamt_summe = 0.0
    for p in projekte:
        summe = db.session.query(db.func.coalesce(db.func.sum(Position.gesamtpreis), 0)).join(
            Aufmass, Position.aufmass_id == Aufmass.id
        ).filter(Aufmass.project_id == p.id).scalar() or 0.0
        projekte_mit_summe.append((p, summe))
        gesamt_summe += summe

    # Employee count
    mitarbeiter_anzahl = User.query.filter_by(company_id=current_user.company_id).count()

    # License info
    licenses = License.query.filter_by(company_id=current_user.company_id, aktiv=True).all()
    license_max_ma = sum(l.max_mitarbeiter for l in licenses)
    license_module_count = 0
    license_module_used = 0
    for lic in licenses:
        lms = LicenseModule.query.filter_by(license_id=lic.id, aktiv=True).all()
        license_module_count += len(lms)
    license_count = len(licenses)

    # Profiles
    from app.models.view_profile import ViewProfile
    profile_list = ViewProfile.query.filter_by(
        user_id=current_user.id, view_type='dashboard'
    ).order_by(ViewProfile.is_default.desc(), ViewProfile.name).all()
    active_profile = next((p for p in profile_list if p.is_default), profile_list[0] if profile_list else None)

    return render_template('admin/dashboard.html', modules=modules, titel='Dashboard',
                         projekte_anzahl=projekte_anzahl, letztes_projekt=letztes_projekt,
                         contracts=contracts, lv_names=lv_names,
                         projekte_mit_summe=projekte_mit_summe, gesamt_summe=gesamt_summe,
                         mitarbeiter_anzahl=mitarbeiter_anzahl,
                         license_count=license_count, license_max_ma=license_max_ma,
                         license_module_count=license_module_count,
                         license_module_used=license_module_used,
                         profile_list=profile_list, active_profile=active_profile)

@admin_bp.route('/profil', methods=['GET', 'POST'])
@login_required
def profil():
    if request.method == 'POST':
        current_user.vorname = request.form.get('vorname', '').strip()
        current_user.nachname = request.form.get('nachname', '').strip()
        if request.form.get('password'):
            current_user.set_password(request.form['password'])
        db.session.commit()
        flash('Profil aktualisiert.', 'success')
    return render_template('admin/profil.html', titel='Profil')

@admin_bp.route('/firma')
@login_required
def firma():
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.dashboard'))
    company = Company.query.get(current_user.company_id)
    users = User.query.filter_by(company_id=current_user.company_id).all()
    licenses = License.query.filter_by(company_id=current_user.company_id).all()
    modules = get_aktive_module(company.id, user=current_user)
    return render_template('admin/firma.html', company=company, users=users, licenses=licenses,
                         modules=modules, titel='Firma')

@admin_bp.route('/mitarbeiter/neu', methods=['POST'])
@login_required
def mitarbeiter_neu():
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    email = request.form.get('email', '').strip()
    if User.query.filter_by(email=email).first():
        flash('E-Mail existiert bereits.', 'danger')
        return redirect(url_for('admin.firma'))
    rolle = request.form.get('rolle', 'mitarbeiter')
    if rolle not in ('mitarbeiter', 'firmadmin'):
        rolle = 'mitarbeiter'
    user = User(
        company_id=current_user.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(request.form.get('password', '123456'))
    db.session.add(user)
    db.session.commit()
    flash(f'Mitarbeiter {user.full_name} angelegt.', 'success')
    return redirect(url_for('admin.firma'))

@admin_bp.route('/projekt/schnellanlage', methods=['POST'])
@login_required
def projekt_schnellanlage():
    if not current_user.is_firmadmin() and not current_user.is_superadmin() and not current_user.darf_projekte_anlegen:
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.dashboard'))
    contract_id = request.form.get('contract_id', type=int)
    contract = Contract.query.get(contract_id) if contract_id else None
    from datetime import datetime as dt
    project = Project(
        company_id=current_user.company_id,
        contract_id=contract_id,
        sm_nr=request.form.get('sm_nr', '').strip(),
        bezeichnung=request.form.get('bezeichnung', '').strip(),
        vertrag=contract.name if contract else '',
        lv_name=request.form.get('lv_name', '').strip(),
        status='aktiv', erstellt_von=current_user.id,
    )
    db.session.add(project)
    db.session.commit()
    flash(f'Projekt {project.sm_nr} angelegt.', 'success')
    return redirect(url_for('aufmass.aufmass_list', project_id=project.id))

@admin_bp.route('/mitarbeiter/<int:user_id>/toggle')
@login_required
def mitarbeiter_toggle(user_id):
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id:
        flash('Zugriff verweigert.', 'danger')
        return redirect(url_for('admin.firma'))
    user.aktiv = not user.aktiv
    db.session.commit()
    flash(f'Benutzer {"aktiviert" if user.aktiv else "deaktiviert"}.', 'success')
    return redirect(url_for('admin.firma'))

@admin_bp.route('/mitarbeiter/<int:user_id>/rechte', methods=['GET', 'POST'])
@login_required
def mitarbeiter_rechte(user_id):
    if not current_user.is_firmadmin() and not current_user.is_superadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.dashboard'))
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id and not current_user.is_superadmin():
        flash('Zugriff verweigert.', 'danger')
        return redirect(url_for('admin.firma'))
    if request.method == 'POST':
        user.darf_projekte_anlegen = bool(request.form.get('darf_projekte_anlegen'))
        user.darf_lv_verwalten = bool(request.form.get('darf_lv_verwalten'))
        user.darf_preise_sehen = bool(request.form.get('darf_preise_sehen'))
        user.darf_aufmass_verwalten = bool(request.form.get('darf_aufmass_verwalten'))
        user.darf_evergabe_nutzen = bool(request.form.get('darf_evergabe_nutzen'))
        user.darf_kopfdaten_holen = bool(request.form.get('darf_kopfdaten_holen'))
        user.darf_aufmass_uebertragen = bool(request.form.get('darf_aufmass_uebertragen'))
        db.session.commit()
        flash('Rechte aktualisiert.', 'success')
        return redirect(url_for('admin.firma'))
    projekte = Project.query.filter_by(company_id=current_user.company_id).order_by(Project.sm_nr).all()
    zugriffe = {pa.project_id: pa for pa in ProjectAccess.query.filter_by(user_id=user.id).all()}
    modules = get_aktive_module(current_user.company_id, user=current_user)
    user_modules = {um.module_id for um in UserModulePermission.query.filter_by(user_id=user.id, aktiv=True).all()}
    return render_template('admin/rechte.html', user=user, projekte=projekte, zugriffe=zugriffe,
                         modules=modules, user_modules=user_modules, titel='Rechte')

@admin_bp.route('/mitarbeiter/<int:user_id>/projekt-zugriff', methods=['POST'])
@login_required
def mitarbeiter_projekt_zugriff(user_id):
    if not current_user.is_firmadmin():
        return 'Keine Berechtigung', 403
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id:
        return 'Zugriff verweigert', 403
    project_id = request.form.get('project_id', type=int)
    zugriff = request.form.get('zugriff', '')
    if not project_id or zugriff not in ('lesen', 'schreiben', ''):
        return 'Ungültige Daten', 400
    existing = ProjectAccess.query.filter_by(user_id=user.id, project_id=project_id).first()
    if zugriff:
        if existing:
            existing.zugriff = zugriff
        else:
            pa = ProjectAccess(user_id=user.id, project_id=project_id, zugriff=zugriff)
            db.session.add(pa)
    elif existing:
        db.session.delete(existing)
    db.session.commit()
    return redirect(url_for('admin.mitarbeiter_rechte', user_id=user.id))

@admin_bp.route('/mitarbeiter/<int:user_id>/bearbeiten', methods=['GET', 'POST'])
@login_required
def mitarbeiter_bearbeiten(user_id):
    if not current_user.is_firmadmin() and not current_user.is_superadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id and not current_user.is_superadmin():
        flash('Zugriff verweigert.', 'danger')
        return redirect(url_for('admin.firma'))
    if request.method == 'POST':
        email = request.form.get('email', '').strip()
        if email and email != user.email:
            if User.query.filter_by(email=email).first():
                flash('E-Mail existiert bereits.', 'danger')
                return redirect(url_for('admin.mitarbeiter_bearbeiten', user_id=user.id))
            user.email = email
        user.vorname = request.form.get('vorname', '').strip()
        user.nachname = request.form.get('nachname', '').strip()
        rolle = request.form.get('rolle', '')
        if rolle in ('mitarbeiter', 'firmadmin'):
            user.rolle = rolle
        if request.form.get('password'):
            user.set_password(request.form['password'])
        user.darf_projekte_anlegen = bool(request.form.get('darf_projekte_anlegen'))
        user.darf_lv_verwalten = bool(request.form.get('darf_lv_verwalten'))
        user.darf_preise_sehen = bool(request.form.get('darf_preise_sehen'))
        user.darf_aufmass_verwalten = bool(request.form.get('darf_aufmass_verwalten'))
        user.darf_evergabe_nutzen = bool(request.form.get('darf_evergabe_nutzen'))
        user.darf_kopfdaten_holen = bool(request.form.get('darf_kopfdaten_holen'))
        user.darf_aufmass_uebertragen = bool(request.form.get('darf_aufmass_uebertragen'))
        db.session.commit()
        flash(f'Benutzer {user.full_name} aktualisiert.', 'success')
        if current_user.is_superadmin():
            return redirect(url_for('superadmin.firma_detail', company_id=user.company_id))
        return redirect(url_for('admin.firma'))
    company = Company.query.get(user.company_id)
    return render_template('admin/mitarbeiter_bearbeiten.html', user=user, company=company, titel='Benutzer bearbeiten')

@admin_bp.route('/mitarbeiter/<int:user_id>/loeschen', methods=['POST'])
@login_required
def mitarbeiter_loeschen(user_id):
    if not current_user.is_firmadmin() and not current_user.is_superadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id and not current_user.is_superadmin():
        flash('Zugriff verweigert.', 'danger')
        return redirect(url_for('admin.firma'))
    if user.id == current_user.id:
        flash('Sie können sich nicht selbst löschen.', 'danger')
        return redirect(url_for('admin.firma'))
    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('admin.firma'))

@admin_bp.route('/mitarbeiter/<int:user_id>/module/<int:module_id>/toggle')
@login_required
def mitarbeiter_module_toggle(user_id, module_id):
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    user = User.query.get_or_404(user_id)
    if user.company_id != current_user.company_id:
        flash('Zugriff verweigert.', 'danger')
        return redirect(url_for('admin.firma'))
    if user.is_firmadmin():
        flash('Firmadmin hat automatisch alle Module.', 'info')
        return redirect(url_for('admin.mitarbeiter_rechte', user_id=user.id))
    um = UserModulePermission.query.filter_by(user_id=user.id, module_id=module_id).first()
    if um:
        um.aktiv = not um.aktiv
    else:
        um = UserModulePermission(user_id=user.id, module_id=module_id, aktiv=True)
        db.session.add(um)
    db.session.commit()
    return redirect(url_for('admin.mitarbeiter_rechte', user_id=user.id))

@admin_bp.route('/avatar/upload', methods=['POST'])
@login_required
def avatar_upload():
    file = request.files.get('avatar')
    if not file:
        flash('Keine Datei ausgewählt.', 'danger')
        return redirect(url_for('admin.profil'))
    import os
    from flask import current_app
    ext = os.path.splitext(file.filename)[1].lower()
    if ext not in ('.png', '.jpg', '.jpeg', '.gif'):
        flash('Nur PNG, JPG, GIF erlaubt.', 'danger')
        return redirect(url_for('admin.profil'))
    upload_dir = os.path.join(current_app.root_path, 'static', 'avatars')
    os.makedirs(upload_dir, exist_ok=True)
    filename = f'avatar_{current_user.id}{ext}'
    file.save(os.path.join(upload_dir, filename))
    for old_ext in ('.png', '.jpg', '.jpeg', '.gif'):
        old_path = os.path.join(upload_dir, f'avatar_{current_user.id}{old_ext}')
        if old_ext != ext and os.path.exists(old_path):
            os.remove(old_path)
    current_user.profile_image = filename
    db.session.commit()
    flash('Profilbild aktualisiert.', 'success')
    return redirect(url_for('admin.profil'))

@admin_bp.route('/avatar/entfernen', methods=['POST'])
@login_required
def avatar_entfernen():
    import os
    from flask import current_app
    if current_user.profile_image:
        path = os.path.join(current_app.root_path, 'static', 'avatars', current_user.profile_image)
        if os.path.exists(path):
            os.remove(path)
        current_user.profile_image = None
        db.session.commit()
    flash('Profilbild entfernt.', 'success')
    return redirect(url_for('admin.profil'))

@admin_bp.route('/firma/logo')
@login_required
def firma_logo():
    if not current_user.is_firmadmin():
        return '', 403
    company = Company.query.get(current_user.company_id)
    if not company or not company.logo or not os.path.exists(company.logo):
        return '', 404
    from flask import send_file
    return send_file(company.logo)

@admin_bp.route('/firma/logo-upload', methods=['POST'])
@login_required
def firma_logo_upload():
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    company = Company.query.get(current_user.company_id)
    if request.form.get('delete'):
        if company.logo and os.path.exists(company.logo):
            os.remove(company.logo)
        company.logo = None
        db.session.commit()
        flash('Firmenlogo entfernt.', 'success')
        return redirect(url_for('admin.firma'))
    file = request.files.get('logo')
    if not file or file.filename == '':
        flash('Keine Datei ausgewählt.', 'danger')
        return redirect(url_for('admin.firma'))
    ext = os.path.splitext(file.filename)[1].lower()
    if ext not in ('.png', '.jpg', '.jpeg', '.gif', '.webp'):
        flash('Nur Bildformate: PNG, JPG, GIF, WebP.', 'danger')
        return redirect(url_for('admin.firma'))
    from flask import current_app
    upload_dir = os.path.join(current_app.root_path, '..', 'data', 'uploads', 'logos')
    os.makedirs(upload_dir, exist_ok=True)
    filename = f'logo_{company.id}{ext}'
    filepath = os.path.join(upload_dir, filename)
    file.save(filepath)
    company.logo = filepath
    db.session.commit()
    flash('Firmenlogo erfolgreich hochgeladen.', 'success')
    return redirect(url_for('admin.firma'))

@admin_bp.route('/firma/evergabe', methods=['POST'])
@login_required
def firma_evergabe_save():
    if not current_user.is_firmadmin():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('admin.firma'))
    company = Company.query.get(current_user.company_id)
    if not company.evergabe_aktiviert:
        flash('E-Vergabe ist für Ihre Firma nicht freigeschaltet.', 'danger')
        return redirect(url_for('admin.firma'))
    company.evergabe_benutzer = request.form.get('evergabe_benutzer', '').strip()
    company.evergabe_passwort = request.form.get('evergabe_passwort', '').strip()
    company.evergabe_name = request.form.get('evergabe_name', '').strip()
    db.session.commit()
    flash('E-Vergabe Logindaten gespeichert.', 'success')
    return redirect(url_for('admin.firma'))
