<?php

namespace App\Http\Controllers\Api\V1;

use App\Domain\Financial\Models\Invoice;
use App\Domain\Participant\Models\Participant;
use App\Domain\Shared\Models\ContactMessage;
use App\Domain\Training\Models\Evaluation;
use App\Domain\Training\Models\TrainingSession;
use App\Domain\Website\Models\WebsiteSetting;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $user = $request->user();
        $participants = $this->getAuthorizedParticipants($user);

        $childrenSummary = $participants->map(function (Participant $p) {
            $nextSession = $this->getNextSession($p);
            $outstandingBalance = Invoice::where('billable_type', 'App\\Domain\\Participant\\Models\\Participant')
                ->where('billable_id', $p->id)
                ->whereNotIn('status', ['cancelled', 'draft', 'paid'])
                ->sum('due_amount');

            return [
                'uuid' => $p->uuid,
                'name_ar' => $p->person?->name_ar ?? $p->name_ar ?? '',
                'photo_url' => $p->photo_path ? asset('storage/' . $p->photo_path) : null,
                'status' => $p->status->value ?? $p->status,
                'outstanding_balance' => $outstandingBalance,
                'outstanding_display' => number_format($outstandingBalance / 100, 2) . ' ج.م',
                'next_session' => $nextSession ? [
                    'date' => $nextSession->session_date?->toDateString() ?? $nextSession->session_date,
                    'start_time' => $nextSession->start_time,
                    'group_name' => $nextSession->group?->name_ar ?? '',
                ] : null,
            ];
        });

        $totalOutstanding = $childrenSummary->sum('outstanding_balance');

        $todaySessions = $this->getTodaySessions($participants);

        $unreadMessages = ContactMessage::where('user_id', $user->id)
            ->whereNotNull('reply')
            ->where('is_read', false)
            ->count();

        $unreadNotifications = $user->unreadNotifications()->count();

        $recentEvaluations = Evaluation::whereIn('participant_id', $participants->pluck('id'))
            ->where('status', 'shared')
            ->where('shared_at', '>=', now()->subDays(30))
            ->count();

        $announcement = $this->getAnnouncement();

        return response()->json([
            'data' => [
                'children' => $childrenSummary,
                'totals' => [
                    'outstanding_balance' => $totalOutstanding,
                    'outstanding_display' => number_format($totalOutstanding / 100, 2) . ' ج.م',
                    'children_count' => $participants->count(),
                    'today_sessions' => $todaySessions->count(),
                    'unread_messages' => $unreadMessages,
                    'unread_notifications' => $unreadNotifications,
                    'recent_evaluations' => $recentEvaluations,
                ],
                'today_sessions' => $todaySessions->map(fn ($s) => [
                    'session_date' => $s->session_date,
                    'start_time' => $s->start_time,
                    'end_time' => $s->end_time,
                    'status' => $s->status->value ?? $s->status,
                    'group_name' => $s->group?->name_ar ?? '',
                    'facility_name' => $s->facility?->name_ar ?? '',
                ])->values(),
                'announcement' => $announcement,
            ],
        ]);
    }

    private function getAuthorizedParticipants($user): \Illuminate\Support\Collection
    {
        $personId = $user->person_id;
        if (!$personId) {
            return collect();
        }

        $direct = Participant::where('person_id', $personId)
            ->with('person')
            ->get();

        $guardian = \App\Domain\Identity\Models\Guardian::where('person_id', $personId)->first();
        $guardianParticipants = collect();

        if ($guardian) {
            $guardianParticipants = $guardian->participants()->with('person')->get();
        }

        return $direct->merge($guardianParticipants)->unique('id');
    }

    private function getNextSession(Participant $p): ?TrainingSession
    {
        $groupIds = $p->activeEnrollments()->pluck('training_group_id');
        if ($groupIds->isEmpty()) {
            return null;
        }

        return TrainingSession::whereIn('training_group_id', $groupIds)
            ->where('session_date', '>=', now()->toDateString())
            ->whereIn('status', ['scheduled'])
            ->with('group:id,name_ar,name')
            ->orderBy('session_date')
            ->orderBy('start_time')
            ->first();
    }

    private function getTodaySessions($participants): \Illuminate\Support\Collection
    {
        $groupIds = collect();
        foreach ($participants as $p) {
            $groupIds = $groupIds->merge($p->activeEnrollments()->pluck('training_group_id'));
        }
        $groupIds = $groupIds->unique();

        if ($groupIds->isEmpty()) {
            return collect();
        }

        return TrainingSession::whereIn('training_group_id', $groupIds)
            ->where('session_date', now()->toDateString())
            ->whereIn('status', ['scheduled', 'in_progress'])
            ->with(['group:id,name_ar,name', 'facility:id,name_ar,name'])
            ->orderBy('start_time')
            ->get();
    }

    private function getAnnouncement(): ?array
    {
        $settings = WebsiteSetting::first();
        if (!$settings || empty($settings->announcement_bar)) {
            return null;
        }

        $bar = $settings->announcement_bar;
        $enabled = $bar['enabled'] ?? false;

        if (!$enabled) {
            return null;
        }

        return [
            'text' => $bar['text'] ?? '',
            'link' => $bar['link'] ?? null,
            'type' => $bar['type'] ?? 'info',
        ];
    }
}
