from flask import Blueprint, request, render_template, redirect, session, flash
from definitions.models import Asset, db
from functions.process_csv import get_csv_data
from functions.validate_values import validate_values
from config import item_attributes
from functions.auth import login_required
from config import BrandingConfig

upload_bp = Blueprint('uploadcsv', __name__)

def _process_csv_file(file, mode):
    """
    Helper function to process CSV file and separate entries based on mode.
    mode: 'import' or 'edit'
    """
    # Extract CSV data
    csvdata = get_csv_data(file)

    # Validate each row of data
    errors = []
    for i, row in enumerate(csvdata, start=1):
        error = validate_values(row)
        if error:
            errors.append(f"Row {i}: {error}")

    if errors:
        return None, errors

    # Separate entries based on mode
    primary_attrib = next((attrib for attrib in item_attributes if attrib.primary), None)
    if not primary_attrib:
        return None, ["Primary attribute not defined in configuration."]

    new_entries = []
    existing_entries = []
    invalid_entries = []

    for row in csvdata:
        primary_value = row[primary_attrib.attrib_name]
        asset_exists = Asset.query.filter_by(**{primary_attrib.attrib_name: primary_value}).first()

        if mode == 'import':
            if asset_exists:
                invalid_entries.append(row)  # Existing entries are invalid for import
            else:
                new_entries.append(row)
        elif mode == 'edit':
            if asset_exists:
                existing_entries.append(row)  # Existing entries are valid for edit
            else:
                invalid_entries.append(row)  # Non-existing entries are invalid for edit

    return {
        'new_entries': new_entries,
        'existing_entries': existing_entries,
        'invalid_entries': invalid_entries
    }, None

@upload_bp.route('/import_from_csv/', methods=['GET', 'POST'])
@login_required
def import_from_csv():
    session['csv_mode'] = 'import'  # Store mode in session
    if request.method == 'POST':
        # Check if a file was uploaded
        if 'file' not in request.files:
            flash("No file uploaded.", "error")
            return redirect(request.url)

        file = request.files['file']

        # Check if the file is a CSV
        if file.filename == '' or not file.filename.endswith('.csv'):
            flash("Please upload a valid CSV file.", "error")
            return redirect(request.url)

        # Process the CSV file
        result, errors = _process_csv_file(file, mode='import')
        if errors:
            for error in errors:
                flash(error, "error")
            return redirect(request.url)

        # Store entries in session for further processing
        session['new_entries'] = result['new_entries']
        session['invalid_entries'] = result['invalid_entries']

        # Redirect to preview page
        return render_template(
            'csv_preview.html',
            mode='import',
            new_entries=result['new_entries'],
            invalid_entries=result['invalid_entries'],
            item_attributes=item_attributes,
            brandingconfig=BrandingConfig
        )

    # Render the upload page for GET requests
    return render_template('upload.html', mode="import", brandingconfig=BrandingConfig)

@upload_bp.route('/edit_using_csv/', methods=['GET', 'POST'])
@login_required
def edit_using_csv():
    session['csv_mode'] = 'edit'  # Store mode in session
    if request.method == 'POST':
        # Check if a file was uploaded
        if 'file' not in request.files:
            flash("No file uploaded.", "error")
            return redirect(request.url)

        file = request.files['file']

        # Check if the file is a CSV
        if file.filename == '' or not file.filename.endswith('.csv'):
            flash("Please upload a valid CSV file.", "error")
            return redirect(request.url)

        # Process the CSV file
        result, errors = _process_csv_file(file, mode='edit')
        if errors:
            for error in errors:
                flash(error, "error")
            return redirect(request.url)

        # Store entries in session for further processing
        session['existing_entries'] = result['existing_entries']
        session['invalid_entries'] = result['invalid_entries']

        # Redirect to preview page
        return render_template(
            'csv_preview.html',
            mode='edit',
            existing_entries=result['existing_entries'],
            invalid_entries=result['invalid_entries'],
            item_attributes=item_attributes,
            brandingconfig=BrandingConfig
        )

    # Render the upload page for GET requests
    return render_template('upload.html', mode="edit", brandingconfig=BrandingConfig)