from flask import Blueprint, render_template, request, jsonify, flash, redirect, url_for
from flask_login import login_required, current_user
from app.extensions import db
from app.models.lv import LVPosition
from app.models.contract import Contract
from app.models.view_profile import ViewProfile
import json

lv_bp = Blueprint('lv', __name__)

def _lv_berechtigt():
    if current_user.is_superadmin():
        return True
    if current_user.is_firmadmin() or current_user.darf_lv_verwalten:
        return True
    return False

@lv_bp.route('/')
@login_required
def index():
    if not _lv_berechtigt():
        flash('Keine Berechtigung für LV-Verwaltung.', 'danger')
        return redirect(url_for('admin.dashboard'))
    lv_names = db.session.query(LVPosition.lv_name).filter_by(
        company_id=current_user.company_id
    ).distinct().order_by(LVPosition.lv_name).all()
    lv_names = [r[0] for r in lv_names]
    selected_lv = request.args.get('lv', lv_names[0] if lv_names else '')
    search = request.args.get('q', '').strip()
    sort_col = request.args.get('sort', '')
    sort_dir = request.args.get('dir', 'asc')

    base = LVPosition.query.filter_by(
        company_id=current_user.company_id, lv_name=selected_lv
    )
    if search:
        like = f'%{search}%'
        base = base.filter(
            db.or_(LVPosition.pos_nr.like(like), LVPosition.kurztext.like(like))
        )

    sort_map = {
        'pos_nr': LVPosition.pos_nr,
        'text': LVPosition.kurztext,
        'einheit': LVPosition.einheit,
        'ep': LVPosition.einzelpreis,
    }
    if sort_col in sort_map:
        col = sort_map[sort_col]
        order = col.asc() if sort_dir == 'asc' else col.desc()
        positionen = base.order_by(LVPosition.favorite.desc(), order).all()
    else:
        positionen = base.order_by(LVPosition.favorite.desc(), LVPosition.order_index).all()

    contracts = Contract.query.filter_by(company_id=current_user.company_id).order_by(Contract.name).all()

    view_id = request.args.get('view_id', type=int)
    view_config = ViewProfile.get_default_config()
    if view_id:
        vp = ViewProfile.query.get(view_id)
        if vp and vp.user_id == current_user.id:
            view_config = vp.get_config()
    else:
        default_vp = ViewProfile.query.filter_by(
            user_id=current_user.id, view_type='lv', is_default=True
        ).first()
        if default_vp:
            view_config = default_vp.get_config()

    preise_sichtbar = current_user.is_firmadmin() or current_user.darf_preise_sehen
    return render_template('lv/index.html',
                         lv_names=lv_names, selected_lv=selected_lv,
                         positionen=positionen, search=search,
                         contracts=contracts,
                         view_config=view_config,
                         view_config_json=json.dumps(view_config),
                         preise_sichtbar=preise_sichtbar,
                         titel='Leistungsverzeichnis')

@lv_bp.route('/neu', methods=['POST'])
@login_required
def neu_lv():
    if not _lv_berechtigt():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('lv.index'))
    lv_name = request.form.get('lv_name', '').strip()
    if not lv_name:
        flash('LV-Name erforderlich.', 'danger')
        return redirect(url_for('lv.index'))
    return redirect(url_for('lv.index', lv=lv_name))

@lv_bp.route('/position/neu', methods=['POST'])
@login_required
def position_neu():
    if not _lv_berechtigt():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('lv.index'))
    lv_name = request.form.get('lv_name', '')
    if not lv_name:
        flash('Bitte zuerst ein LV auswählen.', 'danger')
        return redirect(url_for('lv.index'))
    max_order = db.session.query(db.func.max(LVPosition.order_index)).filter_by(
        company_id=current_user.company_id, lv_name=lv_name
    ).scalar() or 0
    einzelpreis = float(request.form.get('einzelpreis', 0))
    pos = LVPosition(
        company_id=current_user.company_id, lv_name=lv_name,
        pos_nr=request.form.get('pos_nr', ''), order_index=max_order + 1,
        kurztext=request.form.get('kurztext', ''),
        langtext=request.form.get('langtext', ''),
        einheit=request.form.get('einheit', 'ST'),
        einzelpreis=einzelpreis if current_user.is_firmadmin() or current_user.darf_preise_sehen else 0,
        gruppe=request.form.get('gruppe', ''),
    )
    db.session.add(pos)
    db.session.commit()
    return redirect(url_for('lv.index', lv=lv_name))

@lv_bp.route('/position/<int:pos_id>/bearbeiten', methods=['POST'])
@login_required
def position_bearbeiten(pos_id):
    if not _lv_berechtigt():
        return 'Keine Berechtigung', 403
    pos = LVPosition.query.get_or_404(pos_id)
    if pos.company_id != current_user.company_id:
        return 'Zugriff verweigert', 403
    pos.pos_nr = request.form.get('pos_nr', pos.pos_nr)
    pos.kurztext = request.form.get('kurztext', pos.kurztext)
    pos.langtext = request.form.get('langtext', pos.langtext)
    pos.einheit = request.form.get('einheit', pos.einheit)
    if current_user.is_firmadmin() or current_user.darf_preise_sehen:
        pos.einzelpreis = float(request.form.get('einzelpreis', pos.einzelpreis))
    pos.gruppe = request.form.get('gruppe', pos.gruppe)
    db.session.commit()
    return redirect(url_for('lv.index', lv=pos.lv_name))

@lv_bp.route('/position/<int:pos_id>/loeschen', methods=['POST'])
@login_required
def position_loeschen(pos_id):
    if not _lv_berechtigt():
        return 'Keine Berechtigung', 403
    pos = LVPosition.query.get_or_404(pos_id)
    if pos.company_id != current_user.company_id:
        return 'Zugriff verweigert', 403
    lv_name = pos.lv_name
    db.session.delete(pos)
    db.session.commit()
    return redirect(url_for('lv.index', lv=lv_name))

@lv_bp.route('/positionen/reihenfolge', methods=['POST'])
@login_required
def positionen_reihenfolge():
    if not _lv_berechtigt():
        return jsonify({'error': 'Keine Berechtigung'}), 403
    data = request.get_json()
    if not data or 'reihenfolge' not in data:
        return jsonify({'error': 'Keine Daten'}), 400
    for item in data['reihenfolge']:
        pos = LVPosition.query.get(item['id'])
        if pos and pos.company_id == current_user.company_id:
            pos.order_index = item['order_index']
    db.session.commit()
    return jsonify({'status': 'ok'})

@lv_bp.route('/position/<int:pos_id>/favorite', methods=['POST'])
@login_required
def position_favorite(pos_id):
    pos = LVPosition.query.get_or_404(pos_id)
    if pos.company_id != current_user.company_id:
        return 'Zugriff verweigert', 403
    data = request.get_json() or {}
    pos.favorite = data.get('favorite', not pos.favorite)
    db.session.commit()
    return jsonify({'favorite': pos.favorite})

@lv_bp.route('/position/<int:pos_id>/langtext')
@login_required
def position_langtext(pos_id):
    pos = LVPosition.query.get_or_404(pos_id)
    if pos.company_id != current_user.company_id:
        return 'Zugriff verweigert', 403
    preise_sichtbar = current_user.is_firmadmin() or current_user.darf_preise_sehen
    preis_text = f'{pos.einzelpreis:.2f} €' if preise_sichtbar else 'versteckt'
    return f'''<div class="box">
        <p class="has-text-weight-bold mb-2">{pos.pos_nr} – {pos.kurztext or ''}</p>
        <p class="is-size-6"><strong>Einheit:</strong> {pos.einheit} | <strong>EP:</strong> {preis_text} | <strong>Favorit:</strong> {'★' if pos.favorite else '☆'}</p>
        <hr>
        <div style="white-space:pre-wrap;font-size:0.9rem">{pos.langtext or 'Kein Langtext vorhanden.'}</div>
    </div>'''

@lv_bp.route('/import/txt', methods=['POST'])
@login_required
def import_txt():
    if not _lv_berechtigt():
        flash('Keine Berechtigung.', 'danger')
        return redirect(url_for('lv.index'))
    lv_name = request.form.get('lv_name', '').strip()
    if not lv_name:
        flash('LV-Name erforderlich.', 'danger')
        return redirect(url_for('lv.index'))
    file = request.files.get('datei')
    if not file:
        flash('Keine Datei ausgewählt.', 'danger')
        return redirect(url_for('lv.index'))
    content = file.read().decode('utf-8', errors='ignore')
    max_order = db.session.query(db.func.max(LVPosition.order_index)).filter_by(
        company_id=current_user.company_id, lv_name=lv_name
    ).scalar() or 0
    zeilen = content.split('\n')
    count = 0
    preise_sichtbar = current_user.is_firmadmin() or current_user.darf_preise_sehen
    for zeile in zeilen:
        zeile = zeile.strip()
        if not zeile or zeile.startswith('#'):
            continue
        parts = [p.strip() for p in zeile.split('|')]
        if len(parts) >= 2:
            pos_nr = parts[0]
            if not LVPosition.query.filter_by(
                company_id=current_user.company_id, lv_name=lv_name, pos_nr=pos_nr
            ).first():
                max_order += 1
                einzelpreis = float(parts[4]) if len(parts) > 4 and parts[4] else 0
                pos = LVPosition(
                    company_id=current_user.company_id, lv_name=lv_name,
                    pos_nr=pos_nr, order_index=max_order,
                    kurztext=parts[1] if len(parts) > 1 else '',
                    langtext=parts[2] if len(parts) > 2 else '',
                    einheit=parts[3] if len(parts) > 3 else 'ST',
                    einzelpreis=einzelpreis if preise_sichtbar else 0,
                )
                db.session.add(pos)
                count += 1
    db.session.commit()
    flash(f'{count} Positionen importiert.', 'success')
    return redirect(url_for('lv.index', lv=lv_name))
