<?php

namespace App\Http\Controllers\Professor;

use App\Http\Controllers\Controller;
use App\Models\Trabalho;
use App\Models\PlanoTrimestral;
use App\Models\AnoLetivo;
use App\Models\Turma;
use App\Models\Disciplina;
use App\Models\Trimestre;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Schema;

class TPCPlanoController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('role:professor');
    }

    // ========== TPCs ==========
    public function indexTPCs()
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || !$anoLetivo) {
            return redirect()->route('professor.dashboard')
                ->withErrors(['error' => 'Ano letivo não encontrado.']);
        }

        $tpcs = Trabalho::where('professor_id', $professor->id)
            ->where('ano_letivo_id', $anoLetivo->id)
            ->where('tipo', 'TPC')
            ->with(['turma', 'disciplina'])
            ->orderBy('created_at', 'desc')
            ->get();

        return view('professor.tpcs.index', compact('tpcs', 'anoLetivo'));
    }

    public function createTPC()
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || !$anoLetivo) {
            return redirect()->route('professor.dashboard')
                ->withErrors(['error' => 'Ano letivo não encontrado.']);
        }

        // Buscar turmas e disciplinas do professor
        $alocacoes = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->join('turmas', 'turma_disciplina_professor.turma_id', '=', 'turmas.id')
            ->join('disciplinas', 'turma_disciplina_professor.disciplina_id', '=', 'disciplinas.id')
            ->select(
                'turmas.id as turma_id',
                'turmas.nome as turma_nome',
                'turmas.codigo as turma_codigo',
                'disciplinas.id as disciplina_id',
                'disciplinas.nome as disciplina_nome'
            )
            ->get();

        $trimestres = Trimestre::where('ano_letivo_id', $anoLetivo->id)
            ->orderBy('numero')
            ->get();

        return view('professor.tpcs.create', compact('alocacoes', 'trimestres', 'anoLetivo'));
    }

    public function storeTPC(Request $request)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        $request->validate([
            'titulo' => 'required|string|max:255',
            'descricao' => 'nullable|string',
            'disciplina_id' => 'required|exists:disciplinas,id',
            'turma_id' => 'required|exists:turmas,id',
            'data_entrega' => 'required|date',
            'valor' => 'nullable|numeric|min:0|max:20',
            'arquivo' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
        ]);

        // Verificar permissão
        $alocacao = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.turma_id', $request->turma_id)
            ->where('turma_disciplina_professor.disciplina_id', $request->disciplina_id)
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->first();

        if (!$alocacao) {
            return back()->withErrors(['error' => 'Você não leciona esta disciplina nesta turma.']);
        }

        $dados = $request->all();
        $dados['professor_id'] = $professor->id;
        $dados['ano_letivo_id'] = $anoLetivo->id;
        $dados['tipo'] = 'TPC';

        // Upload de arquivo
        if ($request->hasFile('arquivo')) {
            $arquivo = $request->file('arquivo');
            $nomeArquivo = time() . '_' . uniqid() . '.' . $arquivo->getClientOriginalExtension();
            $caminho = $arquivo->storeAs('tpcs', $nomeArquivo, 'public');
            $dados['arquivo'] = $caminho;
            $dados['nome_arquivo'] = $arquivo->getClientOriginalName();
        }

        $tpc = Trabalho::create($dados);

        // Associar alunos da turma
        $turma = Turma::find($request->turma_id);
        $alunos = $turma->alunos()
            ->wherePivot('ano_letivo_id', $anoLetivo->id)
            ->get();
        
        foreach ($alunos as $aluno) {
            $tpc->alunos()->attach($aluno->id);
        }

        return redirect()->route('professor.tpcs.index')->with('success', 'TPC criado com sucesso!');
    }

    public function showTPC(Trabalho $tpc)
    {
        $user = auth()->user();
        $professor = $user->professor;

        if (!$professor || $tpc->professor_id !== $professor->id || $tpc->tipo !== 'TPC') {
            abort(403, 'Você não tem permissão para acessar este TPC.');
        }

        $tpc->load(['turma', 'disciplina', 'alunos.user']);

        return view('professor.tpcs.show', compact('tpc'));
    }

    public function editTPC(Trabalho $tpc)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || $tpc->professor_id !== $professor->id || $tpc->tipo !== 'TPC') {
            abort(403, 'Você não tem permissão para editar este TPC.');
        }

        // Buscar turmas e disciplinas do professor
        $alocacoes = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->join('turmas', 'turma_disciplina_professor.turma_id', '=', 'turmas.id')
            ->join('disciplinas', 'turma_disciplina_professor.disciplina_id', '=', 'disciplinas.id')
            ->select(
                'turmas.id as turma_id',
                'turmas.nome as turma_nome',
                'turmas.codigo as turma_codigo',
                'disciplinas.id as disciplina_id',
                'disciplinas.nome as disciplina_nome'
            )
            ->get();

        return view('professor.tpcs.edit', compact('tpc', 'alocacoes', 'anoLetivo'));
    }

    public function updateTPC(Request $request, Trabalho $tpc)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || $tpc->professor_id !== $professor->id || $tpc->tipo !== 'TPC') {
            abort(403, 'Você não tem permissão para editar este TPC.');
        }

        $request->validate([
            'titulo' => 'required|string|max:255',
            'descricao' => 'nullable|string',
            'disciplina_id' => 'required|exists:disciplinas,id',
            'turma_id' => 'required|exists:turmas,id',
            'data_entrega' => 'required|date',
            'valor' => 'nullable|numeric|min:0|max:20',
            'arquivo' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
        ]);

        // Verificar permissão
        $alocacao = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.turma_id', $request->turma_id)
            ->where('turma_disciplina_professor.disciplina_id', $request->disciplina_id)
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->first();

        if (!$alocacao) {
            return back()->withErrors(['error' => 'Você não leciona esta disciplina nesta turma.']);
        }

        $dados = $request->only(['titulo', 'descricao', 'disciplina_id', 'turma_id', 'data_entrega', 'valor']);

        // Upload de arquivo se fornecido
        if ($request->hasFile('arquivo')) {
            // Deletar arquivo antigo se existir
            if ($tpc->arquivo && Storage::disk('public')->exists($tpc->arquivo)) {
                Storage::disk('public')->delete($tpc->arquivo);
            }

            $arquivo = $request->file('arquivo');
            $nomeArquivo = time() . '_' . uniqid() . '.' . $arquivo->getClientOriginalExtension();
            $caminho = $arquivo->storeAs('tpcs', $nomeArquivo, 'public');
            $dados['arquivo'] = $caminho;
            $dados['nome_arquivo'] = $arquivo->getClientOriginalName();
        }

        $tpc->update($dados);

        return redirect()->route('professor.tpcs.index')->with('success', 'TPC atualizado com sucesso!');
    }

    public function destroyTPC(Trabalho $tpc)
    {
        $user = auth()->user();
        $professor = $user->professor;

        if (!$professor || $tpc->professor_id !== $professor->id || $tpc->tipo !== 'TPC') {
            abort(403, 'Você não tem permissão para excluir este TPC.');
        }

        // Deletar arquivo se existir
        if ($tpc->arquivo && Storage::disk('public')->exists($tpc->arquivo)) {
            Storage::disk('public')->delete($tpc->arquivo);
        }

        // Eliminar registos relacionados
        DB::table('trabalho_aluno')->where('trabalho_id', $tpc->id)->delete();

        // Hard delete (remove do banco de dados)
        $tpc->forceDelete();

        return redirect()->route('professor.tpcs.index')->with('success', 'TPC excluído com sucesso!');
    }

    public function visualizarTPC(Trabalho $tpc)
    {
        $user = auth()->user();
        $professor = $user->professor;

        if (!$professor || $tpc->professor_id !== $professor->id || $tpc->tipo !== 'TPC') {
            abort(403, 'Você não tem permissão para visualizar este arquivo.');
        }

        if (!$tpc->arquivo || !Storage::disk('public')->exists($tpc->arquivo)) {
            abort(404, 'Arquivo não encontrado.');
        }

        $caminhoArquivo = Storage::disk('public')->path($tpc->arquivo);
        $mimeType = Storage::disk('public')->mimeType($tpc->arquivo);
        
        return response()->file($caminhoArquivo, [
            'Content-Type' => $mimeType,
            'Content-Disposition' => 'inline; filename="' . $tpc->nome_arquivo . '"',
        ]);
    }

    // ========== Planos Trimestrais ==========
    public function indexPlanos()
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || !$anoLetivo) {
            return redirect()->route('professor.dashboard')
                ->withErrors(['error' => 'Ano letivo não encontrado.']);
        }

        // Otimização: Paginação e select específico
        $planos = PlanoTrimestral::where('professor_id', $professor->id)
            ->where('ano_letivo_id', $anoLetivo->id)
            ->select('planos_trimestrais.id', 'planos_trimestrais.turma_id', 'planos_trimestrais.disciplina_id', 'planos_trimestrais.trimestre_id', 'planos_trimestrais.created_at')
            ->with([
                'turma:id,nome,codigo',
                'disciplina:id,nome,codigo',
                'trimestre:id,nome,numero'
            ])
            ->orderBy('created_at', 'desc')
            ->paginate(25)
            ->onEachSide(2)
            ->appends(request()->query());

        return view('professor.planos.index', compact('planos', 'anoLetivo'));
    }

    public function createPlano()
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if (!$professor || !$anoLetivo) {
            return redirect()->route('professor.dashboard')
                ->withErrors(['error' => 'Ano letivo não encontrado.']);
        }

        // Buscar turmas e disciplinas do professor
        $alocacoes = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->join('turmas', 'turma_disciplina_professor.turma_id', '=', 'turmas.id')
            ->join('disciplinas', 'turma_disciplina_professor.disciplina_id', '=', 'disciplinas.id')
            ->select(
                'turmas.id as turma_id',
                'turmas.nome as turma_nome',
                'turmas.codigo as turma_codigo',
                'disciplinas.id as disciplina_id',
                'disciplinas.nome as disciplina_nome'
            )
            ->get();

        $trimestres = Trimestre::where('ano_letivo_id', $anoLetivo->id)
            ->orderBy('numero')
            ->get();

        return view('professor.planos.create', compact('alocacoes', 'trimestres', 'anoLetivo'));
    }

    public function storePlano(Request $request)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        $request->validate([
            'disciplina_id' => 'required|exists:disciplinas,id',
            'turma_id' => 'required|exists:turmas,id',
            'trimestre_id' => 'required|exists:trimestres,id',
            'arquivo' => 'required|file|mimes:pdf,doc,docx|max:10240',
            'observacoes' => 'nullable|string',
        ]);

        // Verificar permissão
        $alocacao = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.turma_id', $request->turma_id)
            ->where('turma_disciplina_professor.disciplina_id', $request->disciplina_id)
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->first();

        if (!$alocacao) {
            return back()->withErrors(['error' => 'Você não leciona esta disciplina nesta turma.']);
        }

        // Verificar se já existe plano para este trimestre
        $planoExistente = PlanoTrimestral::where('professor_id', $professor->id)
            ->where('disciplina_id', $request->disciplina_id)
            ->where('turma_id', $request->turma_id)
            ->where('trimestre_id', $request->trimestre_id)
            ->where('ano_letivo_id', $anoLetivo->id)
            ->first();

        if ($planoExistente) {
            return back()->withErrors(['error' => 'Já existe um plano para esta turma, disciplina e trimestre. Use a opção de editar.'])->withInput();
        }

        // Criar novo plano
        $arquivo = $request->file('arquivo');
        $nomeArquivo = time() . '_' . uniqid() . '.' . $arquivo->getClientOriginalExtension();
        $caminho = $arquivo->storeAs('planos-trimestrais', $nomeArquivo, 'public');

        PlanoTrimestral::create([
            'professor_id' => $professor->id,
            'disciplina_id' => $request->disciplina_id,
            'turma_id' => $request->turma_id,
            'trimestre_id' => $request->trimestre_id,
            'ano_letivo_id' => $anoLetivo->id,
            'arquivo' => $caminho,
            'nome_arquivo' => $arquivo->getClientOriginalName(),
            'observacoes' => $request->observacoes,
        ]);

        return redirect()->route('professor.planos.index')->with('success', 'Plano trimestral criado com sucesso!');
    }

    public function showPlano(PlanoTrimestral $plano)
    {
        $user = auth()->user();
        
        if ($user->isProfessor() && $plano->professor_id !== $user->professor->id) {
            abort(403, 'Você não tem permissão para acessar este plano.');
        }

        return view('professor.planos.show', compact('plano'));
    }

    public function editPlano(PlanoTrimestral $plano)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if ($plano->professor_id !== $professor->id) {
            abort(403, 'Você não tem permissão para editar este plano.');
        }

        // Buscar turmas e disciplinas do professor
        $alocacoes = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->join('turmas', 'turma_disciplina_professor.turma_id', '=', 'turmas.id')
            ->join('disciplinas', 'turma_disciplina_professor.disciplina_id', '=', 'disciplinas.id')
            ->select(
                'turmas.id as turma_id',
                'turmas.nome as turma_nome',
                'turmas.codigo as turma_codigo',
                'disciplinas.id as disciplina_id',
                'disciplinas.nome as disciplina_nome'
            )
            ->get();

        $trimestres = Trimestre::where('ano_letivo_id', $anoLetivo->id)
            ->orderBy('numero')
            ->get();

        return view('professor.planos.edit', compact('plano', 'alocacoes', 'trimestres', 'anoLetivo'));
    }

    public function updatePlano(Request $request, PlanoTrimestral $plano)
    {
        $user = auth()->user();
        $professor = $user->professor;
        $anoLetivo = AnoLetivo::where('ativo', true)->first();

        if ($plano->professor_id !== $professor->id) {
            abort(403, 'Você não tem permissão para editar este plano.');
        }

        $request->validate([
            'disciplina_id' => 'required|exists:disciplinas,id',
            'turma_id' => 'required|exists:turmas,id',
            'trimestre_id' => 'required|exists:trimestres,id',
            'arquivo' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
            'observacoes' => 'nullable|string',
        ]);

        // Verificar permissão
        $alocacao = DB::table('turma_disciplina_professor')
            ->where('turma_disciplina_professor.turma_id', $request->turma_id)
            ->where('turma_disciplina_professor.disciplina_id', $request->disciplina_id)
            ->where('turma_disciplina_professor.professor_id', $professor->id)
            ->where('turma_disciplina_professor.ano_letivo_id', $anoLetivo->id)
            ->first();

        if (!$alocacao) {
            return back()->withErrors(['error' => 'Você não leciona esta disciplina nesta turma.']);
        }

        $dados = [
            'disciplina_id' => $request->disciplina_id,
            'turma_id' => $request->turma_id,
            'trimestre_id' => $request->trimestre_id,
            'observacoes' => $request->observacoes,
        ];

        // Atualizar arquivo se fornecido
        if ($request->hasFile('arquivo')) {
            // Deletar arquivo antigo
            if ($plano->arquivo && Storage::disk('public')->exists($plano->arquivo)) {
                Storage::disk('public')->delete($plano->arquivo);
            }

            $arquivo = $request->file('arquivo');
            $nomeArquivo = time() . '_' . uniqid() . '.' . $arquivo->getClientOriginalExtension();
            $caminho = $arquivo->storeAs('planos-trimestrais', $nomeArquivo, 'public');
            $dados['arquivo'] = $caminho;
            $dados['nome_arquivo'] = $arquivo->getClientOriginalName();
        }

        $plano->update($dados);

        return redirect()->route('professor.planos.index')->with('success', 'Plano trimestral atualizado com sucesso!');
    }

    public function destroyPlano(PlanoTrimestral $plano)
    {
        $user = auth()->user();
        $professor = $user->professor;

        if ($plano->professor_id !== $professor->id) {
            abort(403, 'Você não tem permissão para excluir este plano.');
        }

        // Deletar arquivo
        if ($plano->arquivo && Storage::disk('public')->exists($plano->arquivo)) {
            Storage::disk('public')->delete($plano->arquivo);
        }

        // Hard delete (remove do banco de dados)
        $plano->forceDelete();

        return redirect()->route('professor.planos.index')->with('success', 'Plano trimestral excluído com sucesso!');
    }

    public function visualizarPlano(PlanoTrimestral $plano)
    {
        $user = auth()->user();
        
        if ($user->isProfessor() && $plano->professor_id !== $user->professor->id) {
            abort(403, 'Você não tem permissão para visualizar este arquivo.');
        }

        if (!Storage::disk('public')->exists($plano->arquivo)) {
            abort(404, 'Arquivo não encontrado.');
        }

        $caminhoArquivo = Storage::disk('public')->path($plano->arquivo);
        $mimeType = Storage::disk('public')->mimeType($plano->arquivo);
        
        return response()->file($caminhoArquivo, [
            'Content-Type' => $mimeType,
            'Content-Disposition' => 'inline; filename="' . $plano->nome_arquivo . '"',
        ]);
    }

    public function downloadPlano(PlanoTrimestral $plano)
    {
        $user = auth()->user();
        
        if ($user->isProfessor() && $plano->professor_id !== $user->professor->id) {
            abort(403, 'Você não tem permissão para acessar este arquivo.');
        }

        if (!Storage::disk('public')->exists($plano->arquivo)) {
            abort(404, 'Arquivo não encontrado.');
        }

        return Storage::disk('public')->download($plano->arquivo, $plano->nome_arquivo);
    }
}
