import os
import json
from functools import wraps
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.contrib import messages
from django.http import JsonResponse
from .models import Project, PipelineStep, CgiAsset, StudioConfig, Scene
from ai.local_ai_api import LocalAIApi
from .pexels import fetch_first, fetch_video

def studio_admin_required(view_func):
    """Decorator to restrict access to studio admin only."""
    @wraps(view_func)
    def _wrapped_view(request, *args, **kwargs):
        if not request.session.get('is_studio_admin', False):
            messages.warning(request, "Acesso restrito. Por favor, insira sua chave de administrador.")
            return redirect('admin_login')
        return view_func(request, *args, **kwargs)
    return _wrapped_view

def home(request):
    """Render the CGI Studio Command Center."""
    config, created = StudioConfig.objects.get_or_create(id=1)
    if created or not config.admin_access_key:
        config.save()
    
    projects = Project.objects.prefetch_related('steps').all().order_by('-created_at')
    
    total_projects = projects.count()
    active_productions = projects.filter(status='PROD').count()
    completed_projects = projects.filter(status='DONE').count()

    context = {
        "projects": projects,
        "total_projects": total_projects,
        "active_productions": active_productions,
        "completed_projects": completed_projects,
        "current_time": timezone.now(),
        "is_admin": request.session.get('is_studio_admin', False),
    }
    return render(request, "core/index.html", context)

@studio_admin_required
def studio_ai(request):
    """Page to configure and launch AI-automated productions."""
    context = {
        "project_types": Project.TYPES,
        "voice_presets": Project.VOICE_CHOICES,
    }
    return render(request, "core/studio_ai.html", context)

@studio_admin_required
def generate_production(request):
    """AI logic to create a full SUPER PRODUCTION with Video, Audio, and CRUD."""
    if request.method == "POST":
        category = request.POST.get("category", "Sci-Fi")
        proj_type = request.POST.get("project_type", "MOVIE")
        theme = request.POST.get("theme", "Future of humanity")
        voice_preset = request.POST.get("voice_preset", "male_1")
        
        prompt = f"""
        Create a detailed SUPER PRODUCTION plan for a {proj_type} in the {category} category.
        Theme: {theme}
        
        Requirements:
        1. Unique Title and a compelling description.
        2. A full cinematic screenplay (script).
        3. A visual query for a Banner/Capa (2-4 words).
        4. 3 Characters with names, physical descriptions, and a 'voice_preset' (choice of: v_male_1, v_male_2, v_female_1, v_female_2).
        5. 6 Key Scenes with titles, descriptions, and a unique 'video_query' (2-4 words) for each scene.
        6. Metadata: Budget, Rating, Duration.
        
        Return JSON:
        {{
            "title": "...",
            "description": "...",
            "full_script": "...",
            "banner_query": "...",
            "budget": "...",
            "rating": "...",
            "duration": "...",
            "characters": [
                {{"name": "...", "description": "...", "voice_preset": "..."}}
            ],
            "scenes": [
                {{"title": "...", "description": "...", "video_query": "..."}}
            ]
        }}
        """
        
        response = LocalAIApi.create_response({
            "input": [
                {"role": "system", "content": "You are a Hollywood AI Director creating cinematic video-based productions."},
                {"role": "user", "content": prompt},
            ],
            "text": {"format": {"type": "json_object"}},
        })
        
        if response.get("success"):
            try:
                data = LocalAIApi.decode_json_from_response(response)
                
                # Fetch Banner
                banner_data = fetch_first(data.get('banner_query', data['title']))
                banner_url = banner_data['local_path'] if banner_data else ""

                # Create the Project
                project = Project.objects.create(
                    title=data['title'],
                    project_type=proj_type,
                    category=category,
                    description=data['description'],
                    full_script=data.get('full_script', ''),
                    thumbnail_url=banner_url,
                    banner_url=banner_url,
                    is_ai_generated=True,
                    status='DONE',
                    voice_preset=voice_preset,
                    estimated_budget=data.get('budget', '$200M'),
                    rating=data.get('rating', 'PG-13'),
                    duration=data.get('duration', '130 min')
                )
                
                # Create default Pipeline Steps
                for stage in [s[0] for s in PipelineStep.STAGES]:
                    PipelineStep.objects.create(project=project, name=stage, progress=100, is_completed=True)
                
                # Characters
                for char in data['characters']:
                    CgiAsset.objects.create(
                        project=project,
                        name=char['name'],
                        asset_type='CHAR',
                        physical_description=char['description'],
                        voice_preset=char.get('voice_preset', 'v_male_1')
                    )
                
                # Scenes + Videos
                for i, scene_data in enumerate(data['scenes']):
                    v_query = scene_data.get('video_query', scene_data['title'])
                    
                    # Fetch Video for scene
                    video_res = fetch_video(f"{data['title']} {v_query}")
                    video_path = video_res['local_path'] if video_res else ""
                    
                    # Fetch Image as fallback/thumbnail for scene
                    image_res = fetch_first(f"{data['title']} {v_query}", orientation="landscape")
                    image_path = image_res['local_path'] if image_res else ""
                    
                    Scene.objects.create(
                        project=project,
                        number=i+1,
                        title=scene_data['title'],
                        description=scene_data['description'],
                        visual_prompt=v_query,
                        image_url=image_path,
                        video_url=video_path
                    )
                
                # Overall production video (using the first scene's video as main)
                if project.scenes.exists():
                    project.video_url = project.scenes.first().video_url
                    project.save()

                messages.success(request, f"Produção '{project.title}' gerada com Sucesso! Banner e Vídeos salvos.")
                return redirect('production_library')
                
            except Exception as e:
                messages.error(request, f"Erro ao processar: {str(e)}")
        else:
            messages.error(request, f"Erro AI: {response.get('error')}")
            
    return redirect('studio_ai')

@studio_admin_required
def edit_production(request, slug):
    """View to edit an existing production's metadata."""
    project = get_object_or_404(Project, slug=slug)
    if request.method == "POST":
        project.title = request.POST.get("title", project.title)
        project.description = request.POST.get("description", project.description)
        project.category = request.POST.get("category", project.category)
        project.estimated_budget = request.POST.get("budget", project.estimated_budget)
        project.duration = request.POST.get("duration", project.duration)
        project.rating = request.POST.get("rating", project.rating)
        project.save()
        messages.success(request, f"Produção '{project.title}' atualizada com sucesso.")
        return redirect('production_library')
    
    return render(request, "core/edit_production.html", {"project": project})

@studio_admin_required
def delete_production(request, slug):
    """View to delete a production."""
    project = get_object_or_404(Project, slug=slug)
    title = project.title
    project.delete()
    messages.success(request, f"Produção '{title}' excluída.")
    return redirect('production_library')

@studio_admin_required
def production_library(request):
    """View to see all completed AI productions."""
    productions = Project.objects.filter(is_ai_generated=True).order_by('-created_at')
    return render(request, "core/production_library.html", {"productions": productions})

@studio_admin_required
def watch_production(request, slug):
    """View to 'watch' (read and experience) a complete production."""
    project = get_object_or_404(Project.objects.prefetch_related('assets', 'scenes'), slug=slug)
    return render(request, "core/watch_production.html", {"project": project})

def admin_login(request):
    """View to enter the unique admin access key."""
    if request.method == "POST":
        key = request.POST.get("access_key")
        try:
            config = StudioConfig.objects.get(id=1)
            if key == config.admin_access_key:
                request.session['is_studio_admin'] = True
                messages.success(request, "Bem-vindo, Comandante do Estúdio!")
                return redirect('home')
            else:
                messages.error(request, "Chave de acesso inválida.")
        except StudioConfig.DoesNotExist:
            messages.error(request, "Configuração do estúdio não encontrada.")
            
    return render(request, "core/admin_login.html")

def admin_logout(request):
    """Logout the studio admin."""
    request.session['is_studio_admin'] = False
    return redirect('home')

@studio_admin_required
def asset_library(request):
    """View all digital assets (Characters, Props, Environments)."""
    assets = CgiAsset.objects.select_related('project').all()
    asset_types = {
        'CHAR': assets.filter(asset_type='CHAR'),
        'PROP': assets.filter(asset_type='PROP'),
        'ENV': assets.filter(asset_type='ENV'),
    }
    return render(request, "core/asset_library.html", {"assets": assets, "asset_types": asset_types})

def project_detail(request, slug):
    """Render the detailed pipeline for a specific production."""
    project = get_object_or_404(Project.objects.prefetch_related('steps', 'assets', 'scenes'), slug=slug)
    return render(request, "core/project_detail.html", {"project": project})
