<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\AuthService;
use App\Services\ActivityLogService;
use App\Services\CertificateService;
use App\Services\CommunicationService;
use App\Services\CourseService;
use App\Services\InvoiceService;
use App\Services\PaymentService;
use App\Services\PromotionService;
use App\Services\ReviewService;
use App\Services\SettingsService;

class DashboardController extends Controller
{
    public function index(): string
    {
        require_auth();

        $settings = new SettingsService();
        $user = current_user();

        return $this->view('dashboard/index', [
            'title' => 'Dashboard',
            'user' => $user,
            'settings' => $settings,
            'summary' => $this->summaryFor($user),
            'shortcuts' => $this->shortcutsFor($user),
            'adminDashboard' => ($user['role'] ?? '') === 'admin' ? $this->adminDashboardData() : [],
        ]);
    }

    public function profile(): string
    {
        require_auth();

        return $this->view('dashboard/profile', [
            'title' => 'Perfil',
            'user' => current_user(),
        ]);
    }

    public function updateProfile(Request $request): void
    {
        require_auth();

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $auth = new AuthService();
        $result = $auth->updateProfile((int) current_user()['id'], $request->all());

        if (!$result['ok']) {
            flash('error', $result['error']);
            app()->response()->back();
        }

        flash('success', 'Perfil actualizado.');
        app()->response()->redirect('/profile');
    }

    private function summaryFor(array $user): array
    {
        $role = $user['role'] ?? '';

        if ($role === 'admin') {
            $auth = new AuthService();
            $courses = new CourseService();
            $payments = new PaymentService();
            $certificates = new CertificateService();

            $approvedPayments = array_filter($payments->adminPayments(), fn (array $payment): bool => ($payment['status'] ?? '') === 'approved');
            $revenue = array_sum(array_map(fn (array $payment): float => (float) $payment['amount'], $approvedPayments));
            $courseStats = $courses->stats();
            $userStats = $auth->stats();

            return [
                ['label' => 'Utilizadores', 'value' => (string) $userStats['total'], 'hint' => $userStats['pending'] . ' pendente(s)'],
                ['label' => 'Cursos publicados', 'value' => (string) $courseStats['published'], 'hint' => $courseStats['submitted'] . ' em aprovacao'],
                ['label' => 'Vendas aprovadas', 'value' => (string) count($approvedPayments), 'hint' => money_mzn($revenue)],
                ['label' => 'Certificados', 'value' => (string) count($certificates->all()), 'hint' => 'emitidos'],
            ];
        }

        if ($role === 'student') {
            $payments = new PaymentService();
            $certificates = new CertificateService();
            $communication = new CommunicationService();
            $invoices = new InvoiceService();

            return [
                ['label' => 'Pagamentos', 'value' => (string) count($payments->studentPayments((int) $user['id'])), 'hint' => 'historico'],
                ['label' => 'Recibos', 'value' => (string) count($invoices->invoicesForStudent((int) $user['id'])), 'hint' => 'emitidos'],
                ['label' => 'Certificados', 'value' => (string) count($certificates->certificatesForStudent((int) $user['id'])), 'hint' => 'conquistados'],
                ['label' => 'Notificacoes', 'value' => (string) $communication->unreadCount((int) $user['id']), 'hint' => 'nao lidas'],
            ];
        }

        if (in_array($role, ['instructor', 'institution'], true)) {
            $courses = new CourseService();
            $reviews = new ReviewService();
            $communication = new CommunicationService();

            return [
                ['label' => 'Meus cursos', 'value' => (string) count($courses->ownerCourses((int) $user['id'], $role)), 'hint' => 'criados'],
                ['label' => 'Avaliacoes', 'value' => (string) count($reviews->all()), 'hint' => 'na plataforma'],
                ['label' => 'Perguntas', 'value' => (string) count($communication->questionsForUser($user)), 'hint' => 'dos alunos'],
                ['label' => 'Notificacoes', 'value' => (string) $communication->unreadCount((int) $user['id']), 'hint' => 'nao lidas'],
            ];
        }

        return [
            ['label' => 'Perfil', 'value' => role_label($role), 'hint' => status_label($user['status'] ?? '')],
            ['label' => 'Moeda', 'value' => 'MZN', 'hint' => 'principal'],
            ['label' => 'Estado', 'value' => status_label($user['status'] ?? ''), 'hint' => 'conta'],
            ['label' => 'Notificacoes', 'value' => '0', 'hint' => 'nao lidas'],
        ];
    }

    private function shortcutsFor(array $user): array
    {
        return match ($user['role'] ?? '') {
            'admin' => [
                ['label' => 'Utilizadores', 'url' => '/admin/users', 'text' => 'Aprovar contas e gerir acessos.'],
                ['label' => 'Cursos', 'url' => '/admin/courses', 'text' => 'Validar, publicar e suspender cursos.'],
                ['label' => 'Pagamentos', 'url' => '/admin/payments', 'text' => 'Aprovar comprovativos e libertar acesso.'],
                ['label' => 'Promocoes', 'url' => '/admin/promotions', 'text' => 'Cupoes, campanhas e afiliados.'],
                ['label' => 'Perguntas', 'url' => '/communication/questions', 'text' => 'Responder duvidas dos alunos.'],
                ['label' => 'Certificados', 'url' => '/admin/certificates', 'text' => 'Validar e reemitir certificados.'],
            ],
            'student' => [
                ['label' => 'Meus cursos', 'url' => '/student/courses', 'text' => 'Continuar aulas e acompanhar progresso.'],
                ['label' => 'Explorar cursos', 'url' => '/courses', 'text' => 'Encontrar novos cursos pagos e gratuitos.'],
                ['label' => 'Pagamentos', 'url' => '/payments', 'text' => 'Enviar comprovativos e acompanhar estados.'],
                ['label' => 'Certificados', 'url' => '/certificates', 'text' => 'Ver certificados emitidos.'],
                ['label' => 'Perguntas', 'url' => '/communication/questions', 'text' => 'Acompanhar respostas dos instrutores.'],
                ['label' => 'Notificacoes', 'url' => '/notifications', 'text' => 'Ver alertas internos.'],
            ],
            'instructor', 'institution' => [
                ['label' => 'Meus cursos', 'url' => '/manage/courses', 'text' => 'Criar, editar e submeter cursos.'],
                ['label' => 'Conteudo', 'url' => '/manage/courses', 'text' => 'Gerir aulas e materiais.'],
                ['label' => 'Perguntas', 'url' => '/communication/questions', 'text' => 'Responder alunos.'],
                ['label' => 'Ganhos', 'url' => '/earnings', 'text' => 'Acompanhar vendas e comissoes.'],
                ['label' => 'Perfil', 'url' => '/profile', 'text' => 'Actualizar dados publicos.'],
            ],
            default => [
                ['label' => 'Perfil', 'url' => '/profile', 'text' => 'Actualizar dados pessoais.'],
                ['label' => 'Cursos', 'url' => '/courses', 'text' => 'Explorar catalogo.'],
            ],
        };
    }

    private function adminDashboardData(): array
    {
        $auth = new AuthService();
        $courses = new CourseService();
        $payments = new PaymentService();
        $certificates = new CertificateService();
        $logs = new ActivityLogService();

        $userStats = $auth->stats();
        $courseStats = $courses->stats();
        $allCourses = $courses->adminCourses();
        $allPayments = $payments->adminPayments();
        $approvedPayments = array_values(array_filter($allPayments, fn (array $payment): bool => ($payment['status'] ?? '') === 'approved'));
        $revenue = array_sum(array_map(fn (array $payment): float => (float) ($payment['amount'] ?? 0), $approvedPayments));

        usort($allCourses, fn (array $a, array $b): int => strcmp($b['updated_at'] ?? $b['created_at'] ?? '', $a['updated_at'] ?? $a['created_at'] ?? ''));

        return [
            'kpis' => [
                [
                    'label' => 'Alunos activos',
                    'value' => number_format((int) $userStats['students'], 0, ',', '.'),
                    'trend' => '+ 18,6%',
                    'tone' => 'violet',
                    'points' => '4,48 28,38 44,28 60,30 76,18 92,34 108,22 124,36 140,20 156,16',
                ],
                [
                    'label' => 'Cursos publicados',
                    'value' => number_format((int) $courseStats['published'], 0, ',', '.'),
                    'trend' => '+ 9,2%',
                    'tone' => 'blue',
                    'points' => '4,42 28,26 44,33 60,24 76,31 92,20 108,39 124,29 140,25 156,10',
                ],
                [
                    'label' => 'Vendas aprovadas',
                    'value' => money_mzn($revenue),
                    'trend' => '+ 23,4%',
                    'tone' => 'pink',
                    'points' => '4,40 28,22 44,30 60,24 76,38 92,26 108,18 124,28 140,20 156,12',
                ],
                [
                    'label' => 'Certificados',
                    'value' => number_format(count($certificates->all()), 0, ',', '.'),
                    'trend' => '+ 6,1%',
                    'tone' => 'cyan',
                    'points' => '4,34 28,22 44,30 60,28 76,34 92,36 108,32 124,24 140,18 156,8',
                ],
            ],
            'sales' => [
                'total' => money_mzn($revenue),
                'points' => '8,170 80,120 150,135 220,78 292,112 360,86 430,138 500,78 572,34 644,72',
            ],
            'status' => [
                ['label' => 'Activos', 'value' => (int) $userStats['active'], 'color' => '#3f46ff'],
                ['label' => 'Pendentes', 'value' => (int) $userStats['pending'], 'color' => '#a435f0'],
                ['label' => 'Publicados', 'value' => (int) $courseStats['published'], 'color' => '#23b7f5'],
                ['label' => 'Certificados', 'value' => count($certificates->all()), 'color' => '#f35caf'],
            ],
            'recentCourses' => array_slice($allCourses, 0, 4),
            'popularCourses' => $this->popularCourses($approvedPayments, $allCourses),
            'recentActivity' => $logs->recent(5),
        ];
    }

    private function popularCourses(array $approvedPayments, array $courses): array
    {
        $courseMap = [];

        foreach ($courses as $course) {
            $courseMap[(int) ($course['id'] ?? 0)] = $course;
        }

        $popular = [];

        foreach ($approvedPayments as $payment) {
            $courseId = (int) ($payment['course_id'] ?? 0);

            if (!isset($popular[$courseId])) {
                $popular[$courseId] = [
                    'course' => $courseMap[$courseId] ?? ['title' => $payment['course_title'] ?? 'Curso'],
                    'sales' => 0,
                    'revenue' => 0.0,
                ];
            }

            $popular[$courseId]['sales']++;
            $popular[$courseId]['revenue'] += (float) ($payment['amount'] ?? 0);
        }

        if (!$popular) {
            foreach (array_slice($courses, 0, 4) as $course) {
                $popular[(int) ($course['id'] ?? 0)] = [
                    'course' => $course,
                    'sales' => max(1, (int) ($course['students_count'] ?? 0)),
                    'revenue' => (float) ($course['price'] ?? 0),
                ];
            }
        }

        usort($popular, fn (array $a, array $b): int => $b['revenue'] <=> $a['revenue']);

        return array_slice(array_values($popular), 0, 4);
    }
}
