from datetime import datetime, timedelta
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, session
from flask_login import login_user, logout_user, login_required, current_user
from werkzeug.security import check_password_hash
from sqlalchemy import func, desc
import uuid
import json

from app import db
from app.models import User, Incident

bp = Blueprint('main', __name__)

@bp.route('/health')
def health_check():
    """Health check endpoint voor Kubernetes"""
    try:
        # Check database connectivity
        db.session.execute('SELECT 1')
        return jsonify({
            'status': 'healthy',
            'timestamp': datetime.utcnow().isoformat(),
            'database': 'connected'
        }), 200
    except Exception as e:
        return jsonify({
            'status': 'unhealthy',
            'timestamp': datetime.utcnow().isoformat(),
            'database': 'disconnected',
            'error': str(e)
        }), 503

@bp.route('/')
def index():
    """Homepage met incident invoer"""
    return render_template('index.html')

@bp.route('/add-incident', methods=['GET', 'POST'])
def add_incident():
    """Incident toevoegen (voor geregistreerde gebruikers)"""
    if request.method == 'POST':
        try:
            severity_str = request.form.get('severity')
            notes = request.form.get('notes', '').strip()
            incident_time = request.form.get('incident_time')

            print(f"DEBUG add_incident - Severity: {severity_str}, Time: {incident_time}")

            # Validatie
            if not severity_str:
                flash('Selecteer een Snauw-index', 'error')
                return redirect(url_for('main.add_incident'))

            severity = int(severity_str)
            if not (1 <= severity <= 5):
                flash('Snauw-index moet tussen 1 en 5 zijn', 'error')
                return redirect(url_for('main.add_incident'))

            # Parse timestamp
            if incident_time:
                try:
                    # Handle different datetime formats
                    if 'T' in incident_time:
                        timestamp = datetime.fromisoformat(incident_time.replace('Z', '+00:00'))
                    else:
                        timestamp = datetime.strptime(incident_time, '%Y-%m-%d %H:%M:%S')
                except ValueError as dt_error:
                    print(f"DEBUG DateTime parse error: {dt_error}")
                    timestamp = datetime.utcnow()
            else:
                timestamp = datetime.utcnow()

            # Maak incident
            incident = Incident(
                user_id=current_user.id if current_user.is_authenticated else None,
                timestamp=timestamp,
                severity=severity,
                notes=notes if notes else None,
                session_id=get_or_create_session_id() if not current_user.is_authenticated else None
            )

            db.session.add(incident)
            db.session.commit()

            flash('✅ Incident succesvol opgeslagen!', 'success')
            return redirect(url_for('main.statistics'))

        except ValueError as e:
            print(f"DEBUG ValueError in add_incident: {e}")
            flash('Ongeldige invoer. Controleer je gegevens.', 'error')
        except Exception as e:
            print(f"DEBUG Exception in add_incident: {e}")
            flash('Er is een fout opgetreden bij het opslaan.', 'error')
            db.session.rollback()

    return render_template('add_incident.html')

@bp.route('/api/incidents', methods=['POST'])
def api_add_incident():
    """API endpoint voor het toevoegen van incidenten (voor AJAX)"""
    try:
        data = request.get_json()

        severity = int(data.get('severity'))
        notes = data.get('notes', '').strip()
        timestamp_str = data.get('timestamp')

        if not (1 <= severity <= 5):
            return jsonify({'error': 'Snauw-index moet tussen 1 en 5 zijn'}), 400

        # Parse timestamp
        if timestamp_str:
            timestamp = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
        else:
            timestamp = datetime.utcnow()

        # Maak incident
        incident = Incident(
            user_id=current_user.id if current_user.is_authenticated else None,
            timestamp=timestamp,
            severity=severity,
            notes=notes if notes else None,
            session_id=get_or_create_session_id() if not current_user.is_authenticated else None
        )

        db.session.add(incident)
        db.session.commit()

        return jsonify({
            'success': True,
            'message': 'Incident succesvol opgeslagen!',
            'incident': incident.to_dict()
        })

    except ValueError:
        return jsonify({'error': 'Ongeldige invoer'}), 400
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': 'Er is een fout opgetreden'}), 500

@bp.route('/statistics')
def statistics():
    """Statistieken pagina"""
    # Voor ingelogde gebruikers
    if current_user.is_authenticated:
        incidents = Incident.query.filter_by(user_id=current_user.id).order_by(desc(Incident.timestamp)).all()
    else:
        # Voor anonieme gebruikers - via session_id
        session_id = get_or_create_session_id()
        incidents = Incident.query.filter_by(session_id=session_id).order_by(desc(Incident.timestamp)).all()

    # Bereken statistieken
    stats = calculate_statistics(incidents)

    return render_template('statistics.html', incidents=incidents, stats=stats)

@bp.route('/api/statistics')
def api_statistics():
    """API endpoint voor statistieken (voor AJAX updates)"""
    if current_user.is_authenticated:
        incidents = Incident.query.filter_by(user_id=current_user.id).all()
    else:
        session_id = get_or_create_session_id()
        incidents = Incident.query.filter_by(session_id=session_id).all()

    stats = calculate_statistics(incidents)

    return jsonify({
        'stats': stats,
        'incidents': [incident.to_dict() for incident in incidents]
    })

@bp.route('/register', methods=['GET', 'POST'])
def register():
    """Gebruiker registratie"""
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    if request.method == 'POST':
        email = request.form.get('email', '').strip().lower()
        password = request.form.get('password')
        password_confirm = request.form.get('password_confirm')

        # Debug informatie
        print(f"DEBUG Register - Email: {email}, Password len: {len(password) if password else 0}")

        # Validatie
        if not email or '@' not in email or '.' not in email:
            flash('Voer een geldig e-mailadres in', 'error')
            return render_template('register.html')

        if not password or len(password) < 6:
            flash('Wachtwoord moet minstens 6 karakters lang zijn', 'error')
            return render_template('register.html')

        if password != password_confirm:
            flash('Wachtwoorden komen niet overeen', 'error')
            return render_template('register.html')

        # Check of gebruiker al bestaat
        if User.query.filter_by(email=email).first():
            flash('Er bestaat al een account met dit e-mailadres', 'error')
            return render_template('register.html')

        try:
            # Maak nieuwe gebruiker
            user = User(email=email)
            user.set_password(password)

            db.session.add(user)
            db.session.commit()

            # Probeer data migratie van anonieme gebruiker
            migrate_anonymous_data(user)

            # Log in de gebruiker
            login_user(user)

            flash('✅ Account succesvol aangemaakt en ingelogd!', 'success')
            return redirect(url_for('main.index'))

        except Exception as e:
            print(f"DEBUG Register error: {e}")
            db.session.rollback()
            flash('Er is een fout opgetreden bij het maken van je account', 'error')
            return render_template('register.html')

    return render_template('register.html')

@bp.route('/login', methods=['GET', 'POST'])
def login():
    """Gebruiker login"""
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    if request.method == 'POST':
        email = request.form.get('email', '').strip().lower()
        password = request.form.get('password')

        if not email or not password:
            flash('Voer e-mail en wachtwoord in', 'error')
            return render_template('login.html')

        user = User.query.filter_by(email=email).first()

        if user and user.check_password(password):
            login_user(user)

            # Probeer data migratie van anonieme gebruiker
            migrate_anonymous_data(user)

            flash('✅ Succesvol ingelogd!', 'success')
            next_page = request.args.get('next')
            return redirect(next_page) if next_page else redirect(url_for('main.index'))
        else:
            flash('Ongeldig e-mailadres of wachtwoord', 'error')

    return render_template('login.html')

@bp.route('/logout')
@login_required
def logout():
    """Gebruiker logout"""
    logout_user()
    flash('Je bent uitgelogd', 'info')
    return redirect(url_for('main.index'))

@bp.route('/migrate-data', methods=['POST'])
def migrate_data():
    """Data migratie van anonieme naar geregistreerde gebruiker"""
    if not current_user.is_authenticated:
        return jsonify({'error': 'Inloggen vereist'}), 401

    try:
        data = request.get_json()
        anonymous_incidents = data.get('incidents', [])

        migrated_count = 0
        for incident_data in anonymous_incidents:
            # Controleer of incident al bestaat (op basis van timestamp en severity)
            timestamp = datetime.fromisoformat(incident_data['timestamp'].replace('Z', '+00:00'))

            existing = Incident.query.filter_by(
                user_id=current_user.id,
                timestamp=timestamp,
                severity=incident_data['severity']
            ).first()

            if not existing:
                incident = Incident(
                    user_id=current_user.id,
                    timestamp=timestamp,
                    severity=incident_data['severity'],
                    notes=incident_data.get('notes')
                )
                db.session.add(incident)
                migrated_count += 1

        db.session.commit()

        return jsonify({
            'success': True,
            'migrated_count': migrated_count,
            'message': f'{migrated_count} incidenten succesvol gemigreerd!'
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({'error': 'Fout bij data migratie'}), 500

@bp.route('/export-data')
def export_data():
    """GDPR data export"""
    if current_user.is_authenticated:
        incidents = Incident.query.filter_by(user_id=current_user.id).all()

        data = {
            'user': {
                'email': current_user.email,
                'created_at': current_user.created_at.isoformat()
            },
            'incidents': [incident.to_dict() for incident in incidents],
            'export_date': datetime.utcnow().isoformat(),
            'total_incidents': len(incidents)
        }
    else:
        session_id = get_or_create_session_id()
        incidents = Incident.query.filter_by(session_id=session_id).all()

        data = {
            'session_id': session_id,
            'incidents': [incident.to_dict() for incident in incidents],
            'export_date': datetime.utcnow().isoformat(),
            'total_incidents': len(incidents),
            'note': 'Anonieme gebruiker data'
        }

    return jsonify(data)

@bp.route('/delete-account', methods=['POST'])
@login_required
def delete_account():
    """GDPR account verwijdering"""
    if request.form.get('confirm') != 'DELETE':
        flash('Type "DELETE" om je account te bevestigen', 'error')
        return redirect(url_for('main.statistics'))

    try:
        # Verwijder alle incidenten van de gebruiker
        Incident.query.filter_by(user_id=current_user.id).delete()

        # Verwijder de gebruiker
        user_email = current_user.email
        db.session.delete(current_user)
        db.session.commit()

        logout_user()

        flash(f'Account {user_email} en alle gegevens zijn permanent verwijderd', 'info')
        return redirect(url_for('main.index'))

    except Exception as e:
        db.session.rollback()
        flash('Fout bij het verwijderen van account', 'error')
        return redirect(url_for('main.statistics'))

@bp.route('/privacy')
def privacy():
    """Privacy beleid pagina"""
    return render_template('privacy.html')

# Helper functions

def get_or_create_session_id():
    """Haal session ID op of maak een nieuwe voor anonieme gebruikers"""
    if 'session_id' not in session:
        session['session_id'] = str(uuid.uuid4())
    return session['session_id']

def migrate_anonymous_data(user):
    """Probeer data van anonieme gebruiker naar geregistreerde gebruiker te migreren"""
    if 'session_id' in session:
        session_id = session['session_id']

        # Vind incidenten van anonieme sessie
        anonymous_incidents = Incident.query.filter_by(session_id=session_id).all()

        if anonymous_incidents:
            # Migreer naar gebruiker
            for incident in anonymous_incidents:
                incident.user_id = user.id
                incident.session_id = None

            db.session.commit()
            flash(f'✨ {len(anonymous_incidents)} incidenten zijn gemigreerd naar je account!', 'success')

def calculate_statistics(incidents):
    """Bereken statistieken voor incidents"""
    if not incidents:
        return {
            'total_incidents': 0,
            'avg_severity': 0,
            'incidents_today': 0,
            'incidents_this_week': 0,
            'incidents_this_month': 0,
            'most_severe': 0,
            'trend_data': []
        }

    now = datetime.utcnow()
    today = now.date()
    week_ago = now - timedelta(days=7)
    month_ago = now - timedelta(days=30)

    # Basis statistieken
    total_incidents = len(incidents)
    severities = [inc.severity for inc in incidents]
    avg_severity = sum(severities) / len(severities) if severities else 0
    most_severe = max(severities) if severities else 0

    # Tijd-gebaseerde counts
    incidents_today = len([inc for inc in incidents if inc.timestamp.date() == today])
    incidents_this_week = len([inc for inc in incidents if inc.timestamp >= week_ago])
    incidents_this_month = len([inc for inc in incidents if inc.timestamp >= month_ago])

    # Trend data (laatste 7 dagen)
    trend_data = []
    for i in range(7):
        date = now - timedelta(days=i)
        day_incidents = [inc for inc in incidents if inc.timestamp.date() == date.date()]
        trend_data.append({
            'date': date.strftime('%m/%d'),
            'count': len(day_incidents),
            'avg_severity': sum(inc.severity for inc in day_incidents) / len(day_incidents) if day_incidents else 0
        })

    trend_data.reverse()  # Chronologische volgorde

    return {
        'total_incidents': total_incidents,
        'avg_severity': round(avg_severity, 1),
        'incidents_today': incidents_today,
        'incidents_this_week': incidents_this_week,
        'incidents_this_month': incidents_this_month,
        'most_severe': most_severe,
        'trend_data': trend_data
    }
