<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Aluno;
use App\Models\Professor;
use App\Models\Turma;
use App\Models\AnoLetivo;
use App\Models\Disciplina;
use App\Models\Trimestre;
use App\Models\Avaliacao;
use App\Models\Evento;
use App\Models\Trabalho;
use App\Models\Financeiro;
use App\Services\CodigoEstudanteService;
use App\Services\AvaliacaoService;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\App;

class PopularTodasTabelasSeeder extends Seeder
{
    public function run(): void
    {
        $this->command->info('=== POVOANDO TODAS AS TABELAS ===');
        
        // Verificar se já existe ano letivo ativo
        $anoLetivo = AnoLetivo::where('ativo', true)->first();
        
        if (!$anoLetivo) {
            $this->command->info('Criando ano letivo...');
            $anoAtual = date('Y');
            $anoLetivo = AnoLetivo::create([
                'ano' => "{$anoAtual}/" . ($anoAtual + 1),
                'data_inicio' => "{$anoAtual}-01-01",
                'data_fim' => ($anoAtual + 1) . "-12-31",
                'ativo' => true,
            ]);
        }
        
        // Criar trimestres se não existirem
        $trimestres = Trimestre::where('ano_letivo_id', $anoLetivo->id)->get();
        if ($trimestres->isEmpty()) {
            $this->command->info('Criando trimestres...');
            Trimestre::create(['nome' => '1º Trimestre', 'numero' => 1, 'ano_letivo_id' => $anoLetivo->id]);
            Trimestre::create(['nome' => '2º Trimestre', 'numero' => 2, 'ano_letivo_id' => $anoLetivo->id]);
            Trimestre::create(['nome' => '3º Trimestre', 'numero' => 3, 'ano_letivo_id' => $anoLetivo->id]);
        }
        
        // Verificar se já existem disciplinas
        $disciplinas = Disciplina::where('ativa', true)->get();
        if ($disciplinas->isEmpty()) {
            $this->command->info('Criando disciplinas...');
            $disciplinasNomes = ['Matemática', 'Português', 'História', 'Geografia', 'Ciências', 'Inglês', 'Educação Física', 'Educação Visual'];
            foreach ($disciplinasNomes as $nome) {
                Disciplina::create(['nome' => $nome, 'ativa' => true]);
            }
            $disciplinas = Disciplina::where('ativa', true)->get();
        }
        
        // Criar turmas se não existirem
        $turmas = Turma::where('ano_letivo_id', $anoLetivo->id)->get();
        if ($turmas->isEmpty()) {
            $this->command->info('Criando turmas...');
            $classes = ['1ª Classe', '2ª Classe', '3ª Classe', '4ª Classe', '5ª Classe', '6ª Classe'];
            $nomesTurmas = ['A', 'B'];
            foreach ($classes as $classe) {
                foreach ($nomesTurmas as $nomeTurma) {
                    Turma::create([
                        'codigo' => $classe,
                        'nome' => $nomeTurma,
                        'ano_letivo_id' => $anoLetivo->id,
                        'capacidade_maxima' => 30,
                        'ativa' => true,
                    ]);
                }
            }
            $turmas = Turma::where('ano_letivo_id', $anoLetivo->id)->get();
        }
        
        // Atribuir disciplinas às turmas
        $this->command->info('Atribuindo disciplinas às turmas...');
        foreach ($turmas as $turma) {
            $disciplinasTurma = DB::table('turma_disciplina')
                ->where('turma_id', $turma->id)
                ->where('ano_letivo_id', $anoLetivo->id)
                ->count();
            
            if ($disciplinasTurma == 0) {
                foreach ($disciplinas->take(5) as $disciplina) {
                    DB::table('turma_disciplina')->insert([
                        'turma_id' => $turma->id,
                        'disciplina_id' => $disciplina->id,
                        'ano_letivo_id' => $anoLetivo->id,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                }
            }
        }
        
        // Criar alunos se não existirem
        $totalAlunos = Aluno::count();
        if ($totalAlunos < 50) {
            $this->command->info("Criando alunos (atualmente: {$totalAlunos})...");
            $this->criarAlunos($anoLetivo, $turmas);
        }
        
        // Criar professores se não existirem
        $totalProfessores = Professor::count();
        if ($totalProfessores < 10) {
            $this->command->info("Criando professores (atualmente: {$totalProfessores})...");
            $this->criarProfessores($anoLetivo, $turmas, $disciplinas);
        }
        
        // Criar avaliações
        $totalAvaliacoes = Avaliacao::count();
        if ($totalAvaliacoes < 100) {
            $this->command->info("Criando avaliações (atualmente: {$totalAvaliacoes})...");
            $this->criarAvaliacoes($anoLetivo, $turmas, $disciplinas);
        }
        
        // Criar trabalhos
        $totalTrabalhos = Trabalho::count();
        if ($totalTrabalhos < 20) {
            $this->command->info("Criando trabalhos (atualmente: {$totalTrabalhos})...");
            $this->criarTrabalhos($anoLetivo, $turmas, $disciplinas);
        }
        
        // Criar eventos
        $totalEventos = Evento::count();
        if ($totalEventos < 10) {
            $this->command->info("Criando eventos (atualmente: {$totalEventos})...");
            $this->criarEventos($anoLetivo, $turmas);
        }
        
        // Criar mensalidades
        $totalMensalidades = Financeiro::count();
        if ($totalMensalidades < 50) {
            $this->command->info("Criando mensalidades (atualmente: {$totalMensalidades})...");
            $this->criarMensalidades($anoLetivo);
        }
        
        $this->command->info('=== POVOAMENTO CONCLUÍDO COM SUCESSO! ===');
    }
    
    private function criarAlunos($anoLetivo, $turmas)
    {
        $nomesMulheres = [
            'Maria Santos', 'Ana Oliveira', 'Sofia Pereira', 'Beatriz Rodrigues', 'Inês Martins',
            'Mariana Ferreira', 'Carolina Lopes', 'Leonor Carvalho', 'Matilde Correia', 'Lara Moreira',
            'Joana Silva', 'Rita Costa', 'Catarina Mendes', 'Diana Fernandes', 'Eva Alves',
            'Patrícia Sousa', 'Teresa Gomes', 'Cristina Ribeiro', 'Sandra Pinto', 'Mónica Nunes',
            'Isabel Ferreira', 'Carla Oliveira', 'Diana Santos', 'Patrícia Costa', 'Teresa Mendes',
            'Sandra Pereira', 'Mónica Fernandes', 'Rita Alves', 'Cristina Sousa', 'Carla Gomes'
        ];
        
        $nomesHomens = [
            'João Silva', 'Pedro Costa', 'Carlos Mendes', 'Miguel Fernandes', 'Tiago Alves',
            'Rafael Sousa', 'Gonçalo Gomes', 'Diogo Ribeiro', 'Francisco Pinto', 'Tomás Nunes',
            'António Machado', 'Manuel Santos', 'José Silva', 'Ricardo Mendes', 'Paulo Fernandes',
            'Luís Alves', 'Nuno Sousa', 'Hugo Gomes', 'Bruno Ribeiro', 'Filipe Pinto'
        ];
        
        $anoAtual = date('Y');
        $index = 1;
        $timestamp = time();
        
        // Criar 30 mulheres
        foreach ($nomesMulheres as $nome) {
            if (Aluno::count() >= 50) break;
            
            $email = strtolower(str_replace(' ', '', $nome)) . $timestamp . $index . '@aluno.sge.pt';
            
            if (User::where('email', $email)->exists()) {
                $index++;
                continue;
            }
            
            $user = User::create([
                'name' => $nome,
                'email' => $email,
                'password' => Hash::make($anoAtual),
                'tipo' => 'aluno',
                'must_change_password' => true,
                'is_active' => true,
            ]);
            
            $codigoEstudante = CodigoEstudanteService::gerar($anoAtual);
            
            $aluno = Aluno::create([
                'user_id' => $user->id,
                'codigo_estudante' => $codigoEstudante,
                'telefone' => '+258 8' . rand(1000000, 9999999),
                'endereco' => 'Endereço ' . $index . ', Maputo',
                'data_nascimento' => now()->subYears(rand(10, 18))->subDays(rand(0, 365)),
                'genero' => 'F',
                'nome_encarregado' => 'Encarregado de ' . $nome,
                'telefone_encarregado' => '+258 8' . rand(1000000, 9999999),
            ]);
            
            // Alocar a uma turma aleatória
            if ($turmas->isNotEmpty()) {
                $turma = $turmas->random();
                $aluno->turmas()->attach($turma->id, ['ano_letivo_id' => $anoLetivo->id]);
            }
            
            $index++;
        }
        
        // Criar 20 homens
        foreach ($nomesHomens as $nome) {
            if (Aluno::count() >= 50) break;
            
            $email = strtolower(str_replace(' ', '', $nome)) . $timestamp . $index . '@aluno.sge.pt';
            
            if (User::where('email', $email)->exists()) {
                $index++;
                continue;
            }
            
            $user = User::create([
                'name' => $nome,
                'email' => $email,
                'password' => Hash::make($anoAtual),
                'tipo' => 'aluno',
                'must_change_password' => true,
                'is_active' => true,
            ]);
            
            $codigoEstudante = CodigoEstudanteService::gerar($anoAtual);
            
            $aluno = Aluno::create([
                'user_id' => $user->id,
                'codigo_estudante' => $codigoEstudante,
                'telefone' => '+258 8' . rand(1000000, 9999999),
                'endereco' => 'Endereço ' . $index . ', Maputo',
                'data_nascimento' => now()->subYears(rand(10, 18))->subDays(rand(0, 365)),
                'genero' => 'M',
                'nome_encarregado' => 'Encarregado de ' . $nome,
                'telefone_encarregado' => '+258 8' . rand(1000000, 9999999),
            ]);
            
            // Alocar a uma turma aleatória
            if ($turmas->isNotEmpty()) {
                $turma = $turmas->random();
                $aluno->turmas()->attach($turma->id, ['ano_letivo_id' => $anoLetivo->id]);
            }
            
            $index++;
        }
    }
    
    private function criarProfessores($anoLetivo, $turmas, $disciplinas)
    {
        $nomesHomens = [
            'António Machado', 'Manuel Santos', 'José Silva', 'Ricardo Mendes', 'Paulo Fernandes', 'Luís Alves'
        ];
        
        $nomesMulheres = [
            'Isabel Ferreira', 'Cristina Oliveira', 'Patrícia Costa', 'Teresa Rodrigues'
        ];
        
        $anoAtual = date('Y');
        $index = 1;
        $timestamp = time();
        
        // Criar 6 homens
        foreach ($nomesHomens as $nome) {
            if (Professor::count() >= 10) break;
            
            $email = strtolower(str_replace(' ', '', $nome)) . $timestamp . $index . '@professor.sge.pt';
            
            if (User::where('email', $email)->exists()) {
                $index++;
                continue;
            }
            
            $user = User::create([
                'name' => $nome,
                'email' => $email,
                'password' => Hash::make($anoAtual),
                'tipo' => 'professor',
                'must_change_password' => true,
                'is_active' => true,
            ]);
            
            $professor = Professor::create([
                'user_id' => $user->id,
                'numero_funcionario' => 'PROF' . str_pad($index, 4, '0', STR_PAD_LEFT),
                'telefone' => '+258 8' . rand(1000000, 9999999),
                'endereco' => 'Endereço ' . $index . ', Maputo',
                'data_nascimento' => now()->subYears(rand(25, 55))->subDays(rand(0, 365)),
                'genero' => 'M',
            ]);
            
            // Alocar professor a turmas e disciplinas
            if ($turmas->isNotEmpty() && $disciplinas->isNotEmpty()) {
                $turma = $turmas->random();
                $disciplina = $disciplinas->random();
                
                DB::table('turma_disciplina_professor')->insert([
                    'turma_id' => $turma->id,
                    'disciplina_id' => $disciplina->id,
                    'professor_id' => $professor->id,
                    'ano_letivo_id' => $anoLetivo->id,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            }
            
            $index++;
        }
        
        // Criar 4 mulheres
        foreach ($nomesMulheres as $nome) {
            if (Professor::count() >= 10) break;
            
            $email = strtolower(str_replace(' ', '', $nome)) . $timestamp . $index . '@professor.sge.pt';
            
            if (User::where('email', $email)->exists()) {
                $index++;
                continue;
            }
            
            $user = User::create([
                'name' => $nome,
                'email' => $email,
                'password' => Hash::make($anoAtual),
                'tipo' => 'professor',
                'must_change_password' => true,
                'is_active' => true,
            ]);
            
            $professor = Professor::create([
                'user_id' => $user->id,
                'numero_funcionario' => 'PROF' . str_pad($index, 4, '0', STR_PAD_LEFT),
                'telefone' => '+258 8' . rand(1000000, 9999999),
                'endereco' => 'Endereço ' . $index . ', Maputo',
                'data_nascimento' => now()->subYears(rand(25, 55))->subDays(rand(0, 365)),
                'genero' => 'F',
            ]);
            
            // Alocar professor a turmas e disciplinas
            if ($turmas->isNotEmpty() && $disciplinas->isNotEmpty()) {
                $turma = $turmas->random();
                $disciplina = $disciplinas->random();
                
                DB::table('turma_disciplina_professor')->insert([
                    'turma_id' => $turma->id,
                    'disciplina_id' => $disciplina->id,
                    'professor_id' => $professor->id,
                    'ano_letivo_id' => $anoLetivo->id,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            }
            
            $index++;
        }
    }
    
    private function criarAvaliacoes($anoLetivo, $turmas, $disciplinas)
    {
        $trimestres = Trimestre::where('ano_letivo_id', $anoLetivo->id)->get();
        
        if ($trimestres->isEmpty() || $turmas->isEmpty() || $disciplinas->isEmpty()) {
            $this->command->warn('Não é possível criar avaliações: faltam trimestres, turmas ou disciplinas.');
            return;
        }
        
        $alunos = Aluno::all();
        
        foreach ($turmas as $turma) {
            $alunosTurma = $turma->alunos()->wherePivot('ano_letivo_id', $anoLetivo->id)->get();
            
            if ($alunosTurma->isEmpty()) continue;
            
            $disciplinasTurma = DB::table('turma_disciplina')
                ->where('turma_id', $turma->id)
                ->where('ano_letivo_id', $anoLetivo->id)
                ->pluck('disciplina_id')
                ->toArray();
            
            if (empty($disciplinasTurma)) continue;
            
            foreach ($alunosTurma->take(10) as $aluno) {
                $alunoIndex = $alunosTurma->search($aluno);
                $totalAlunos = $alunosTurma->count();
                $limiteReprovados = (int)($totalAlunos * 0.35); // Aproximadamente 35% reprovados, 65% aprovados
                $isReprovado = $alunoIndex < $limiteReprovados;
                
                foreach ($disciplinasTurma as $disciplinaId) {
                    foreach ($trimestres as $trimestre) {
                        // Verificar se já existe avaliação
                        $existe = Avaliacao::where('aluno_id', $aluno->id)
                            ->where('disciplina_id', $disciplinaId)
                            ->where('trimestre_id', $trimestre->id)
                            ->where('ano_letivo_id', $anoLetivo->id)
                            ->exists();
                        
                        if ($existe) continue;
                        
                        if ($isReprovado) {
                            // Notas abaixo de 10 para reprovação (0-9.9)
                            $a_pratica_1 = rand(0, 99) / 10;
                            $a_pratica_2 = rand(0, 99) / 10;
                            $acs_1 = rand(0, 99) / 10;
                            $acs_2 = rand(0, 99) / 10;
                            $at = rand(0, 99) / 10;
                        } else {
                            // Notas entre 10-20 para aprovação
                            $a_pratica_1 = rand(100, 200) / 10;
                            $a_pratica_2 = rand(100, 200) / 10;
                            $acs_1 = rand(100, 200) / 10;
                            $acs_2 = rand(100, 200) / 10;
                            $at = rand(100, 200) / 10;
                        }
                        
                        $dados = [
                            'aluno_id' => $aluno->id,
                            'disciplina_id' => $disciplinaId,
                            'turma_id' => $turma->id,
                            'trimestre_id' => $trimestre->id,
                            'ano_letivo_id' => $anoLetivo->id,
                            'modelo' => 'NACIONAL',
                            'a_pratica_1' => $a_pratica_1,
                            'a_pratica_2' => $a_pratica_2,
                            'acs_1' => $acs_1,
                            'acs_2' => $acs_2,
                            'at' => $at,
                        ];
                        
                        $avaliacaoService = App::make(AvaliacaoService::class);
                        $avaliacaoService->salvarAvaliacao($dados);
                    }
                }
            }
        }
    }
    
    private function criarTrabalhos($anoLetivo, $turmas, $disciplinas)
    {
        $professores = Professor::all();
        
        if ($professores->isEmpty()) {
            $this->command->warn('Nenhum professor encontrado para criar trabalhos.');
            return;
        }
        
        foreach ($turmas->take(5) as $turma) {
            $disciplinasTurma = DB::table('turma_disciplina')
                ->where('turma_id', $turma->id)
                ->where('ano_letivo_id', $anoLetivo->id)
                ->pluck('disciplina_id')
                ->toArray();
            
            if (empty($disciplinasTurma)) continue;
            
            foreach ($disciplinasTurma as $disciplinaId) {
                // Buscar professor que leciona esta disciplina nesta turma
                $professorTurma = DB::table('turma_disciplina_professor')
                    ->where('turma_id', $turma->id)
                    ->where('disciplina_id', $disciplinaId)
                    ->where('ano_letivo_id', $anoLetivo->id)
                    ->first();
                
                $professorId = $professorTurma ? $professorTurma->professor_id : $professores->random()->id;
                
                $trabalho = Trabalho::create([
                    'turma_id' => $turma->id,
                    'disciplina_id' => $disciplinaId,
                    'professor_id' => $professorId,
                    'ano_letivo_id' => $anoLetivo->id,
                    'titulo' => 'Trabalho de ' . Disciplina::find($disciplinaId)->nome,
                    'descricao' => 'Descrição do trabalho',
                    'data_entrega' => now()->addDays(rand(7, 30)),
                    'valor' => rand(10, 50),
                ]);
                
                // Atribuir trabalho a alguns alunos da turma
                $alunosTurma = $turma->alunos()->wherePivot('ano_letivo_id', $anoLetivo->id)->get();
                foreach ($alunosTurma->take(5) as $aluno) {
                    $trabalho->alunos()->attach($aluno->id, [
                        'entregue' => rand(0, 1),
                        'nota' => rand(0, 1) ? rand(100, 200) / 10 : null,
                    ]);
                }
            }
        }
    }
    
    private function criarEventos($anoLetivo, $turmas)
    {
        $tipos = ['Geral', 'Turma'];
        $eventosNomes = [
            'Reunião de Pais', 'Festa de Encerramento', 'Dia do Estudante',
            'Competição Desportiva', 'Feira de Ciências', 'Visita de Estudo',
            'Palestra', 'Workshop', 'Cerimónia de Abertura', 'Dia Cultural'
        ];
        
        foreach ($eventosNomes as $index => $nome) {
            $tipo = $tipos[array_rand($tipos)];
            $turmaId = null;
            
            if ($tipo == 'Turma' && $turmas->isNotEmpty()) {
                $turmaId = $turmas->random()->id;
            }
            
            Evento::create([
                'titulo' => $nome,
                'descricao' => 'Descrição do evento ' . $nome,
                'data' => now()->addDays(rand(1, 90)),
                'hora_inicio' => '08:00',
                'hora_fim' => '12:00',
                'tipo' => $tipo,
                'turma_id' => $turmaId,
                'ano_letivo_id' => $anoLetivo->id,
                'cancelado' => false,
            ]);
        }
    }
    
    private function criarMensalidades($anoLetivo)
    {
        $alunos = Aluno::all();
        
        if ($alunos->isEmpty()) {
            $this->command->warn('Nenhum aluno encontrado para criar mensalidades.');
            return;
        }
        
        $meses = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
        $ano = date('Y');
        
        foreach ($alunos as $aluno) {
            foreach ($meses as $mes) {
                // Verificar se já existe
                $existe = Financeiro::where('aluno_id', $aluno->id)
                    ->where('ano_letivo_id', $anoLetivo->id)
                    ->where('tipo', 'Mensalidade')
                    ->where('descricao', 'like', "%{$mes}/{$ano}%")
                    ->exists();
                
                if ($existe) continue;
                
                Financeiro::create([
                    'aluno_id' => $aluno->id,
                    'ano_letivo_id' => $anoLetivo->id,
                    'tipo' => 'Mensalidade',
                    'descricao' => "Mensalidade {$mes}/{$ano}",
                    'valor' => rand(500, 2000),
                    'data_vencimento' => date('Y-m-d', mktime(0, 0, 0, $mes, 5, $ano)),
                    'status' => rand(0, 1) ? 'PAGO' : 'PENDENTE',
                ]);
            }
        }
    }
}

