"""
Institute Template Management Routes
For institute owners/admins to manage their template customization
"""
from flask import Blueprint, request, jsonify
import json
from datetime import datetime
from utils.decorators import token_required
from config import db
from models.institute import Institute, InstituteConfig, InstituteTemplate, InstituteWidget

template_admin_bp = Blueprint('template_admin', __name__, url_prefix='/api/admin')


def format_response(data=None, message="Success", success=True):
    """Standard API response format"""
    return {
        "success": success,
        "message": message,
        "data": data
    }


def error_response(message, status_code=400):
    """Standard error response"""
    return jsonify(format_response(None, message, False)), status_code


# ==========================================
# INSTITUTE CONFIG MANAGEMENT
# ==========================================

# Header-based route (uses x-institute-id from FetchInterceptor)
@template_admin_bp.route('/institute/config', methods=['GET'])
@token_required
def get_institute_config_by_header(current_user, user_role, institute_id, instructor_id):
    """Get config using institute_id from header"""
    if not institute_id:
        return error_response("Institute ID required", 400)
    return _get_institute_config(current_user, user_role, institute_id)

@template_admin_bp.route('/institute/config', methods=['PUT', 'PATCH'])
@token_required
def update_institute_config_by_header(current_user, user_role, institute_id, instructor_id):
    """Update config using institute_id from header"""
    if not institute_id:
        return error_response("Institute ID required", 400)
    return _update_institute_config(current_user, user_role, institute_id)

# Shared helpers
def _get_institute_config(current_user, user_role, institute_id):
    """Shared logic for getting institute config"""
    try:
        # Verify user has access to this institute
        institute = Institute.query.filter_by(id=institute_id).first()
        if not institute:
            return error_response("Institute not found", 404)
        if institute.created_by != current_user.id and user_role not in ('superadmin', 'institute_admin', 'institute_owner'):
            return error_response("Access denied to this institute", 403)
        
        config = InstituteConfig.query.filter_by(institute_id=institute_id).first()
        
        if not config:
            config_dict = {
                'institute_id': institute_id,
                'template_id': 'modern',
                'primary_color': '#10B981',
                'secondary_color': '#059669',
                'accent_color': '#34D399'
            }
        else:
            config_dict = config.to_dict()
            template = InstituteTemplate.query.filter_by(id=config.template_id).first()
            if template:
                config_dict['template_name'] = template.name
                config_dict['template_preview'] = template.preview_url
                
            json_fields = ['sections_config', 'nav_items', 'footer_links', 
                         'floating_contact_config', 'mobile_bottom_nav_items']
            for field in json_fields:
                if config_dict.get(field) and isinstance(config_dict[field], str):
                    try:
                        config_dict[field] = json.loads(config_dict[field])
                    except:
                        pass
        
        return jsonify(format_response({'config': config_dict}, "Config retrieved")), 200
            
    except Exception as e:
        return error_response(str(e), 500)


def _update_institute_config(current_user, user_role, institute_id):
    """Shared logic for updating institute config"""
    try:
        data = request.get_json()
        if not data:
            return error_response("Request data required", 400)
        
        institute = Institute.query.filter_by(id=institute_id).first()
        if not institute:
            return error_response("Institute not found", 404)
        if institute.created_by != current_user.id and user_role not in ('superadmin', 'institute_admin', 'institute_owner'):
            return error_response("Access denied to this institute", 403)
        
        json_fields = ['sections_config', 'nav_items', 'footer_links', 
                     'floating_contact_config', 'mobile_bottom_nav_items',
                     'custom_stats', 'display_rules']
        for field in json_fields:
            if field in data and isinstance(data[field], (dict, list)):
                data[field] = json.dumps(data[field])
        
        config = InstituteConfig.query.filter_by(institute_id=institute_id).first()
        
        allowed_fields = [
            'template_id', 'template_variant',
            'primary_color', 'secondary_color', 'accent_color',
            'text_color', 'text_muted_color', 'background_color',
            'surface_color', 'border_color',
            'gradient_start', 'gradient_end', 'gradient_direction',
            'heading_font', 'body_font', 'font_size_base',
            'border_radius', 'shadow_style',
            'header_style', 'header_bg_color', 'header_text_color',
            'header_height', 'show_top_bar', 'top_bar_bg_color',
            'top_bar_text', 'header_cta_text', 'header_cta_link',
            'logo_position', 'logo_size', 'show_institute_name',
            'hero_style', 'hero_height', 'hero_title', 'hero_subtitle',
            'hero_cta_primary_text', 'hero_cta_primary_link',
            'hero_cta_secondary_text', 'hero_cta_secondary_link',
            'hero_image_url', 'hero_video_url',
            'hero_overlay_enabled', 'hero_overlay_color', 'hero_text_align',
            'sections_config',
            'courses_layout', 'courses_per_row',
            'show_course_price', 'show_course_rating', 'show_course_instructor',
            'footer_style', 'footer_bg_color', 'footer_text_color',
            'footer_columns', 'show_powered_by', 'copyright_text', 'footer_links',
            'nav_style', 'nav_items', 'show_search_in_nav', 'show_auth_buttons',
            'meta_title', 'meta_description', 'og_image_url', 'favicon_url',
            'enable_dark_mode', 'enable_search', 'enable_wishlist',
            'enable_reviews', 'enable_certificates', 'enable_discussions',
            'enable_live_classes', 'enable_cart',
            'animations_enabled', 'animation_speed', 'loading_style',
            'custom_css', 'custom_head_scripts',
            'floating_contact_enabled', 'floating_contact_config',
            'mobile_menu_style', 'mobile_bottom_nav', 'mobile_bottom_nav_items'
        ]
        
        if config:
            for field in allowed_fields:
                if field in data:
                    setattr(config, field, data[field])
        else:
            new_config_data = {'institute_id': institute_id}
            for field in allowed_fields:
                if field in data:
                    new_config_data[field] = data[field]
            config = InstituteConfig(**new_config_data)
            db.session.add(config)
        
        db.session.commit()
        return jsonify(format_response(None, "Configuration updated")), 200
            
    except Exception as e:
        db.session.rollback()
        return error_response(str(e), 500)


# URL-based route (legacy)
@template_admin_bp.route('/institute/<int:route_institute_id>/config', methods=['GET'])
@token_required
def get_institute_config(current_user, user_role, institute_id, instructor_id, route_institute_id):
    """Get institute configuration for editing (URL-based)"""
    return _get_institute_config(current_user, user_role, route_institute_id)


@template_admin_bp.route('/institute/<int:route_institute_id>/config', methods=['PUT', 'PATCH'])
@token_required
def update_institute_config(current_user, user_role, institute_id, instructor_id, route_institute_id):
    """Update institute configuration (URL-based)"""
    return _update_institute_config(current_user, user_role, route_institute_id)


# ==========================================
# TEMPLATE SELECTION
# ==========================================

@template_admin_bp.route('/templates', methods=['GET'])
@token_required
def get_available_templates(current_user, user_role, institute_id, instructor_id):
    """Get all available templates"""
    try:
        templates = InstituteTemplate.query.order_by(InstituteTemplate.is_premium.asc(), InstituteTemplate.name.asc()).all()
        # Ensure we send list of dicts
        templates_list = [t.to_dict() for t in templates]
        return jsonify(format_response(templates_list, f"Found {len(templates_list)} templates")), 200
            
    except Exception as e:
        return error_response(str(e), 500)


# ==========================================
# WIDGET MANAGEMENT
# ==========================================

@template_admin_bp.route('/institute/<int:institute_id>/widgets', methods=['GET'])
@token_required
def get_widgets(current_user, user_role, institute_id, instructor_id):
    """Get all widgets for an institute"""
    try:
        widgets = InstituteWidget.query.filter_by(institute_id=institute_id).order_by(InstituteWidget.display_order.asc()).all()
        
        widgets_list = []
        # Parse JSON fields
        for widget in widgets:
            w_dict = widget.to_dict()
            for field in ['config', 'content', 'display_rules']:
                if w_dict.get(field) and isinstance(w_dict[field], str):
                    try:
                        w_dict[field] = json.loads(w_dict[field])
                    except:
                        pass
            widgets_list.append(w_dict)
        
        return jsonify(format_response(widgets_list, f"Found {len(widgets_list)} widgets")), 200
            
    except Exception as e:
        return error_response(str(e), 500)


@template_admin_bp.route('/institute/<int:institute_id>/widgets', methods=['POST'])
@token_required
def create_widget(current_user, user_role, institute_id, instructor_id):
    """Create a new widget"""
    try:
        data = request.get_json()
        if not data or 'widget_type' not in data:
            return error_response("widget_type is required", 400)
        
        # Serialize JSON fields
        for field in ['config', 'content', 'display_rules']:
            if field in data and isinstance(data[field], (dict, list)):
                data[field] = json.dumps(data[field])
        
        new_widget = InstituteWidget(
            institute_id=institute_id,
            widget_type=data['widget_type'],
            title=data.get('title'),
            subtitle=data.get('subtitle'),
            config=data.get('config', '{}'),
            content=data.get('content'),
            position=data.get('position', 'content'),
            page_target=data.get('page_target', 'all'),
            display_order=data.get('display_order', 0),
            is_active=data.get('is_active', True)
        )
        db.session.add(new_widget)
        db.session.commit()
        
        return jsonify(format_response(
            {'id': new_widget.id, 'institute_id': institute_id},
            "Widget created"
        )), 201
            
    except Exception as e:
        db.session.rollback()
        return error_response(str(e), 500)


@template_admin_bp.route('/institute/<int:institute_id>/widgets/<int:widget_id>', methods=['PUT', 'PATCH'])
@token_required
def update_widget(current_user, user_role, institute_id, instructor_id, widget_id):
    """Update a widget"""
    try:
        data = request.get_json()
        if not data:
            return error_response("Request data required", 400)
        
        # Verify widget belongs to institute
        widget = InstituteWidget.query.filter_by(id=widget_id, institute_id=institute_id).first()
        if not widget:
            return error_response("Widget not found", 404)
        
        # Serialize JSON fields
        for field in ['config', 'content', 'display_rules']:
            if field in data and isinstance(data[field], (dict, list)):
                data[field] = json.dumps(data[field])
        
        allowed_fields = ['widget_type', 'title', 'subtitle', 'config', 'content',
                        'position', 'page_target', 'display_order', 'is_active',
                        'start_date', 'end_date', 'display_rules']
        
        for field in allowed_fields:
            if field in data:
                setattr(widget, field, data[field])
        
        db.session.commit()
        
        return jsonify(format_response(None, "Widget updated")), 200
            
    except Exception as e:
        db.session.rollback()
        return error_response(str(e), 500)


@template_admin_bp.route('/institute/<int:institute_id>/widgets/<int:widget_id>', methods=['DELETE'])
@token_required
def delete_widget(current_user, user_role, institute_id, instructor_id, widget_id):
    """Delete a widget"""
    try:
        widget = InstituteWidget.query.filter_by(id=widget_id, institute_id=institute_id).first()
        if not widget:
            return error_response("Widget not found", 404)
            
        db.session.delete(widget)
        db.session.commit()
        
        return jsonify(format_response(None, "Widget deleted")), 200
            
    except Exception as e:
        db.session.rollback()
        return error_response(str(e), 500)


@template_admin_bp.route('/institute/<int:institute_id>/widgets/reorder', methods=['PATCH'])
@token_required
def reorder_widgets(current_user, user_role, institute_id, instructor_id):
    """Reorder widgets"""
    try:
        data = request.get_json()
        if not data or 'order' not in data:
            return error_response("order array required", 400)
        
        # order should be array of {id: widget_id, order: new_order}
        for item in data['order']:
            widget = InstituteWidget.query.filter_by(id=item['id'], institute_id=institute_id).first()
            if widget:
                widget.display_order = item['order']
        
        db.session.commit()
        return jsonify(format_response(None, "Widgets reordered")), 200
            
    except Exception as e:
        db.session.rollback()
        return error_response(str(e), 500)
