from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length

from services.project_service import (
    create_project, update_project, get_project, delete_project,
    get_all_projects, get_project_children, get_project_document_count,
    filter_projects
)
from services.schema_service import get_all_schemas
from utils.security import permission_required

# Definir Blueprint
projects_bp = Blueprint('projects', __name__, url_prefix='/projects')

# Formularios
class ProjectForm(FlaskForm):
    """Formulario de proyecto."""
    descripcion = StringField('Descripción', validators=[DataRequired(), Length(1, 100)])
    cliente = StringField('Cliente', validators=[DataRequired(), Length(1, 100)])
    destinacion = StringField('Destinación', validators=[Length(0, 100)])
    esquema = SelectField('Esquema', validators=[DataRequired()])
    proyecto_padre = SelectField('Proyecto Padre', validators=[])
    submit = SubmitField('Guardar')

class ProjectFilterForm(FlaskForm):
    """Formulario de filtrado de proyectos."""
    cliente = StringField('Cliente')
    estado = SelectField('Estado', choices=[('', 'Todos'), ('activo', 'Activo'), ('inactivo', 'Inactivo')])
    ano_inicio = StringField('Año Inicio')
    ano_fin = StringField('Año Fin')
    descripcion = StringField('Descripción')
    submit = SubmitField('Filtrar')

# Rutas
@projects_bp.route('/')
@login_required
def list():
    """Listar proyectos."""
    filter_form = ProjectFilterForm(request.args)
    
    # Obtener proyectos según filtros
    if request.args:
        projects = filter_projects(request.args)
    else:
        projects = get_all_projects()
    
    return render_template('projects/list.html', 
                          projects=projects, 
                          filter_form=filter_form)

@projects_bp.route('/create', methods=['GET', 'POST'])
@login_required
@permission_required(1000)  # Nivel mínimo para crear proyectos
def create():
    """Crear nuevo proyecto."""
    form = ProjectForm()
    
    # Cargar opciones para esquemas
    schemas = get_all_schemas()
    form.esquema.choices = [(code, schema['descripcion']) for code, schema in schemas.items()]
    
    # Cargar opciones para proyectos padre
    projects = [(p['codigo'], p['descripcion']) for p in get_all_projects()]
    form.proyecto_padre.choices = [('', 'Ninguno')] + projects
    
    if form.validate_on_submit():
        # Preparar datos del proyecto
        project_data = {
            'descripcion': form.descripcion.data,
            'cliente': form.cliente.data,
            'destinacion': form.destinacion.data,
            'esquema': form.esquema.data,
            'proyecto_padre': form.proyecto_padre.data if form.proyecto_padre.data else None
        }
        
        # Crear proyecto
        success, message, project_id = create_project(project_data, current_user.username)
        
        if success:
            flash(message, 'success')
            return redirect(url_for('projects.view', project_id=project_id))
        else:
            flash(message, 'danger')
    
    return render_template('projects/create.html', form=form)

@projects_bp.route('/<int:project_id>')
@login_required
def view(project_id):
    """Ver detalles de un proyecto."""
    project = get_project(project_id)
    
    if not project:
        flash('Proyecto no encontrado.', 'danger')
        return redirect(url_for('projects.list'))
    
    # Obtener información adicional
    children = get_project_children(project_id)
    document_count = get_project_document_count(project_id)
    
    return render_template('projects/view.html',
                          project=project,
                          children=children,
                          document_count=document_count)

@projects_bp.route('/<int:project_id>/edit', methods=['GET', 'POST'])
@login_required
@permission_required(5000)  # Nivel mínimo para editar proyectos
def edit(project_id):
    """Editar un proyecto."""
    project = get_project(project_id)
    
    if not project:
        flash('Proyecto no encontrado.', 'danger')
        return redirect(url_for('projects.list'))
    
    form = ProjectForm()
    
    # Cargar opciones para esquemas
    schemas = get_all_schemas()
    form.esquema.choices = [(code, schema['descripcion']) for code, schema in schemas.items()]
    
    # Cargar opciones para proyectos padre (excluyendo este proyecto y sus hijos)
    all_projects = get_all_projects()
    children_codes = [child['codigo'] for child in get_project_children(project_id)]
    available_projects = [(p['codigo'], p['descripcion']) for p in all_projects 
                         if p['codigo'] != project['codigo'] and p['codigo'] not in children_codes]
    
    form.proyecto_padre.choices = [('', 'Ninguno')] + available_projects
    
    if request.method == 'GET':
        # Cargar datos actuales
        form.descripcion.data = project['descripcion']
        form.cliente.data = project['cliente']
        form.destinacion.data = project.get('destinacion', '')
        form.esquema.data = project['esquema']
        form.proyecto_padre.data = project.get('proyecto_padre', '')
    
    if form.validate_on_submit():
        # Preparar datos actualizados
        project_data = {
            'descripcion': form.descripcion.data,
            'cliente': form.cliente.data,
            'destinacion': form.destinacion.data,
            'esquema': form.esquema.data,
            'proyecto_padre': form.proyecto_padre.data if form.proyecto_padre.data else None
        }
        
        # Actualizar proyecto
        success, message = update_project(project_id, project_data, current_user.username)
        
        if success:
            flash(message, 'success')
            return redirect(url_for('projects.view', project_id=project_id))
        else:
            flash(message, 'danger')
    
    return render_template('projects/edit.html', form=form, project=project)

@projects_bp.route('/<int:project_id>/delete', methods=['POST'])
@login_required
@permission_required(9000)  # Nivel alto para eliminar proyectos
def delete(project_id):
    """Eliminar un proyecto (marcar como inactivo)."""
    success, message = delete_project(project_id)
    
    if success:
        flash(message, 'success')
    else:
        flash(message, 'danger')
    
    return redirect(url_for('projects.list'))

@projects_bp.route('/api/list')
@login_required
def api_list():
    """API para listar proyectos (para selects dinámicos)."""
    projects = get_all_projects()
    return jsonify([{
        'id': p['codigo'],
        'text': p['descripcion']
    } for p in projects])