from flask import Blueprint, render_template, redirect, url_for, flash, request, g, jsonify
from datetime import datetime
from app.models import db, User, Event, Guest, ScheduleItem, GuestSchedule
from app.auth import role_required

emc_bp = Blueprint('emc', __name__, url_prefix='/emc')

@emc_bp.route('/dashboard', methods=['GET', 'POST'])
@role_required('emc')
def dashboard():
    if request.method == 'POST':
        # Add upcoming event
        title = request.form.get('title', '').strip()
        description = request.form.get('description', '').strip()
        date_str = request.form.get('date', '')
        location = request.form.get('location', '').strip()
        
        if not title or not date_str:
            flash("Event title and date are required.", "error")
        else:
            try:
                event_date = datetime.strptime(date_str, '%Y-%m-%dT%H:%M')
                new_event = Event(
                    title=title,
                    description=description,
                    date=event_date,
                    location=location,
                    emc_id=g.user.id
                )
                db.session.add(new_event)
                db.session.commit()
                flash(f"Event '{title}' created successfully!", "success")
                return redirect(url_for('emc.dashboard'))
            except ValueError:
                flash("Invalid date/time format.", "error")
                
    # List of events created by this EMC
    my_events = Event.query.filter_by(emc_id=g.user.id).order_by(Event.date.asc()).all()
    
    return render_template('emc/dashboard.html', events=my_events)

@emc_bp.route('/callers', methods=['GET', 'POST'])
@role_required('emc')
def callers():
    if request.method == 'POST':
        # Create caller account
        username = request.form.get('username', '').strip()
        password = request.form.get('password', '')
        
        if not username or not password:
            flash("Username and password are required.", "error")
        else:
            existing = User.query.filter_by(username=username).first()
            if existing:
                flash(f"Username '{username}' is already taken.", "error")
            else:
                caller = User(
                    username=username,
                    role='caller',
                    status='approved'
                )
                caller.set_password(password)
                db.session.add(caller)
                db.session.commit()
                flash(f"Caller account for '{username}' created successfully!", "success")
                return redirect(url_for('emc.callers'))
                
    # Show callers list (in a simple implementation, all callers in the database)
    all_callers = User.query.filter_by(role='caller').all()
    return render_template('emc/callers.html', callers=all_callers)

@emc_bp.route('/event/<int:event_id>')
@role_required('emc')
def event_detail(event_id):
    # Verify ownership
    event = Event.query.get_or_404(event_id)
    if event.emc_id != g.user.id:
        flash("You do not have access to this event.", "error")
        return redirect(url_for('emc.dashboard'))
        
    callers_list = User.query.filter_by(role='caller', status='approved').all()
    
    # Calculate RSVP stats for this event
    total = len(event.guests)
    attending = sum(1 for g in event.guests if g.rsvp_status == 'attending')
    declined = sum(1 for g in event.guests if g.rsvp_status == 'not_attending')
    tentative = sum(1 for g in event.guests if g.rsvp_status == 'tentative')
    pending = sum(1 for g in event.guests if g.rsvp_status == 'pending')
    
    return render_template(
        'emc/event_detail.html',
        event=event,
        callers=callers_list,
        stat_total=total,
        stat_attending=attending,
        stat_declined=declined,
        stat_tentative=tentative,
        stat_pending=pending
    )

@emc_bp.route('/event/<int:event_id>/import-guests', methods=['POST'])
@role_required('emc')
def import_guests(event_id):
    import csv
    import io

    event = Event.query.get_or_404(event_id)
    if event.emc_id != g.user.id:
        return jsonify({'error': 'Unauthorized'}), 403

    added_count = 0
    uploaded_file = request.files.get('file')

    if uploaded_file and uploaded_file.filename:
        filename = uploaded_file.filename.lower()

        if filename.endswith('.xlsx') or filename.endswith('.xls'):
            # --- Excel file parsing via openpyxl ---
            try:
                from openpyxl import load_workbook
                wb = load_workbook(uploaded_file, read_only=True, data_only=True)
                ws = wb.active

                rows = list(ws.iter_rows(values_only=True))
                if not rows:
                    flash("The uploaded Excel file is empty.", "error")
                    return redirect(url_for('emc.event_detail', event_id=event_id))

                # Try to detect header row
                header = [str(c).strip().lower() if c else '' for c in rows[0]]
                name_col = email_col = phone_col = None

                for i, h in enumerate(header):
                    if 'name' in h:
                        name_col = i
                    elif 'email' in h or 'mail' in h:
                        email_col = i
                    elif 'phone' in h or 'mobile' in h or 'cell' in h or 'contact' in h:
                        phone_col = i

                # If no headers detected, assume positional: Name, Email, Phone
                if name_col is None:
                    name_col, email_col, phone_col = 0, 1, 2
                    data_rows = rows  # No header row to skip
                else:
                    data_rows = rows[1:]

                for row in data_rows:
                    if not row or all(c is None for c in row):
                        continue
                    name = str(row[name_col]).strip() if name_col is not None and name_col < len(row) and row[name_col] else None
                    if not name or name == 'None':
                        continue
                    email = str(row[email_col]).strip() if email_col is not None and email_col < len(row) and row[email_col] else None
                    phone = str(row[phone_col]).strip() if phone_col is not None and phone_col < len(row) and row[phone_col] else None
                    if email == 'None': email = None
                    if phone == 'None': phone = None

                    guest = Guest(event_id=event.id, name=name, email=email, phone=phone, rsvp_status='pending')
                    db.session.add(guest)
                    added_count += 1

                wb.close()
            except Exception as e:
                flash(f"Error reading Excel file: {str(e)}", "error")
                return redirect(url_for('emc.event_detail', event_id=event_id))

        elif filename.endswith('.csv'):
            # --- CSV file parsing ---
            try:
                stream = io.StringIO(uploaded_file.stream.read().decode('utf-8-sig'))
                reader = csv.reader(stream)
                for row in reader:
                    if not row:
                        continue
                    parts = [p.strip().strip('"').strip("'") for p in row]
                    if parts[0]:
                        name = parts[0]
                        email = parts[1] if len(parts) > 1 and parts[1] else None
                        phone = parts[2] if len(parts) > 2 and parts[2] else None
                        guest = Guest(event_id=event.id, name=name, email=email, phone=phone, rsvp_status='pending')
                        db.session.add(guest)
                        added_count += 1
            except Exception as e:
                flash(f"Error reading CSV file: {str(e)}", "error")
                return redirect(url_for('emc.event_detail', event_id=event_id))
        else:
            flash("Unsupported file format. Please upload .xlsx, .xls, or .csv files.", "error")
            return redirect(url_for('emc.event_detail', event_id=event_id))
    else:
        # --- Fallback: pasted CSV text ---
        csv_data = request.form.get('csv_data', '').strip()
        if not csv_data:
            flash("No guest data entered and no file uploaded.", "error")
            return redirect(url_for('emc.event_detail', event_id=event_id))

        lines = csv_data.split('\n')
        for line in lines:
            line = line.strip()
            if not line:
                continue
            parts = [p.replace('"', '').replace("'", "").strip() for p in line.split(',')]
            if len(parts) > 0 and parts[0]:
                name = parts[0]
                email = parts[1] if len(parts) > 1 else None
                phone = parts[2] if len(parts) > 2 else None
                guest = Guest(event_id=event.id, name=name, email=email, phone=phone, rsvp_status='pending')
                db.session.add(guest)
                added_count += 1

    db.session.commit()
    flash(f"Successfully imported {added_count} guests.", "success")
    return redirect(url_for('emc.event_detail', event_id=event_id))

@emc_bp.route('/event/<int:event_id>/add-schedule', methods=['POST'])
@role_required('emc')
def add_schedule(event_id):
    event = Event.query.get_or_404(event_id)
    if event.emc_id != g.user.id:
        return jsonify({'error': 'Unauthorized'}), 403
        
    title = request.form.get('title', '').strip()
    description = request.form.get('description', '').strip()
    start_str = request.form.get('start_time', '')
    end_str = request.form.get('end_time', '')
    location = request.form.get('location', '').strip()
    
    if not title or not start_str or not end_str:
        flash("Title, start time, and end time are required.", "error")
    else:
        try:
            start_time = datetime.strptime(start_str, '%Y-%m-%dT%H:%M')
            end_time = datetime.strptime(end_str, '%Y-%m-%dT%H:%M')
            
            item = ScheduleItem(
                event_id=event.id,
                title=title,
                description=description,
                start_time=start_time,
                end_time=end_time,
                location=location
            )
            db.session.add(item)
            db.session.commit()
            flash(f"Schedule item '{title}' added.", "success")
        except ValueError:
            flash("Invalid date format in schedule timeline.", "error")
            
    return redirect(url_for('emc.event_detail', event_id=event_id))

@emc_bp.route('/event/<int:event_id>/assign-caller', methods=['POST'])
@role_required('emc')
def assign_caller(event_id):
    event = Event.query.get_or_404(event_id)
    if event.emc_id != g.user.id:
        return jsonify({'error': 'Unauthorized'}), 403
        
    caller_id_str = request.form.get('caller_id')
    caller_id = int(caller_id_str) if caller_id_str else None
    guest_ids = request.form.getlist('guest_ids')
    
    if not guest_ids:
        flash("No guests selected for assignment.", "error")
        return redirect(url_for('emc.event_detail', event_id=event_id))
        
    # Update selected guests
    guests = Guest.query.filter(Guest.id.in_(guest_ids), Guest.event_id == event.id).all()
    for guest in guests:
        guest.caller_id = caller_id
        
    db.session.commit()
    
    caller_name = "Unassigned"
    if caller_id:
        caller = db.session.get(User, caller_id)
        if caller:
            caller_name = caller.username
            
    flash(f"Assigned {len(guests)} guests to caller '{caller_name}'.", "success")
    return redirect(url_for('emc.event_detail', event_id=event_id))

@emc_bp.route('/event/<int:event_id>/link-schedule', methods=['POST'])
@role_required('emc')
def link_schedule(event_id):
    event = Event.query.get_or_404(event_id)
    if event.emc_id != g.user.id:
        return jsonify({'error': 'Unauthorized'}), 403
        
    schedule_item_id = request.form.get('schedule_item_id')
    guest_ids = request.form.getlist('guest_ids')
    
    if not schedule_item_id:
        flash("Please select a schedule session.", "error")
        return redirect(url_for('emc.event_detail', event_id=event_id))
        
    if not guest_ids:
        flash("No guests selected to link.", "error")
        return redirect(url_for('emc.event_detail', event_id=event_id))
        
    # Link selected guests to this sub-event
    schedule_item = ScheduleItem.query.filter_by(id=schedule_item_id, event_id=event.id).first()
    if not schedule_item:
        flash("Invalid schedule session selected.", "error")
        return redirect(url_for('emc.event_detail', event_id=event_id))
        
    link_count = 0
    for g_id in guest_ids:
        # Check if already linked
        existing = GuestSchedule.query.filter_by(guest_id=g_id, schedule_item_id=schedule_item.id).first()
        if not existing:
            link = GuestSchedule(guest_id=g_id, schedule_item_id=schedule_item.id)
            db.session.add(link)
            link_count += 1
            
    db.session.commit()
    flash(f"Invited {link_count} guests to '{schedule_item.title}'.", "success")
    return redirect(url_for('emc.event_detail', event_id=event_id))
