<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\Goal;
use App\Models\PerformanceReview;
use Carbon\Carbon;
use Illuminate\Http\Request;

class PerformanceDashboardController extends Controller
{
    public function index(Request $request)
    {
        $companyId = (int) ($request->user()?->company_id ?? 0);

        if ($companyId <= 0) {
            return view('performance.dashboard', $this->emptyPayload());
        }

        $now = Carbon::now();
        $monthStart = $now->copy()->startOfMonth();
        $today = $now->toDateString();

        $totalGoals = Goal::query()->count();
        $goalsCompleted = Goal::query()->where('status', 'completed')->count();
        $goalsOnTrack = Goal::query()->where('status', 'on_track')->count();
        $goalsAtRisk = Goal::query()->whereIn('status', ['at_risk', 'behind'])->count();
        $goalsActive = Goal::query()->where('status', '!=', 'completed')->count();

        $goalsOverdue = Goal::query()
            ->where('status', '!=', 'completed')
            ->whereNotNull('due_date')
            ->whereDate('due_date', '<', $today)
            ->count();

        $goalsDueSoon = Goal::query()
            ->where('status', '!=', 'completed')
            ->whereNotNull('due_date')
            ->whereBetween('due_date', [$today, $now->copy()->addDays(14)->toDateString()])
            ->count();

        $reviewsPending = PerformanceReview::query()->where('status', 'pending')->count();
        $reviewsCompletedMtd = PerformanceReview::query()
            ->where('status', 'completed')
            ->where(function ($q) use ($monthStart, $now) {
                $q->where(function ($q1) use ($monthStart, $now) {
                    $q1->whereNotNull('review_date')
                        ->whereBetween('review_date', [$monthStart->toDateString(), $now->toDateString()]);
                })->orWhere(function ($q2) use ($monthStart, $now) {
                    $q2->whereNull('review_date')
                        ->whereBetween('updated_at', [$monthStart->startOfDay(), $now->copy()->endOfDay()]);
                });
            })
            ->count();

        $avgRating = round((float) PerformanceReview::query()->whereNotNull('rating')->avg('rating'), 1);

        $goalStatusLabels = ['On track', 'At risk', 'Behind', 'Completed'];
        $goalStatusKeys = ['on_track', 'at_risk', 'behind', 'completed'];
        $byStatus = Goal::query()
            ->selectRaw('status, COUNT(*) as total')
            ->groupBy('status')
            ->pluck('total', 'status')
            ->toArray();
        $goalStatusCounts = [];
        foreach ($goalStatusKeys as $key) {
            $goalStatusCounts[] = (int) ($byStatus[$key] ?? 0);
        }

        $reviewsTrend = $this->reviewsCompletedByMonth($now);

        $recentGoals = Goal::query()
            ->with(['user:id,name', 'department:id,name'])
            ->orderByDesc('updated_at')
            ->limit(8)
            ->get();

        $recentReviews = PerformanceReview::query()
            ->with(['user:id,name', 'reviewer:id,name'])
            ->orderByDesc('updated_at')
            ->limit(8)
            ->get();

        return view('performance.dashboard', [
            'kpis' => [
                'total_goals' => $totalGoals,
                'goals_active' => $goalsActive,
                'goals_on_track' => $goalsOnTrack,
                'goals_at_risk' => $goalsAtRisk,
                'goals_completed' => $goalsCompleted,
                'goals_overdue' => $goalsOverdue,
                'goals_due_soon' => $goalsDueSoon,
                'reviews_pending' => $reviewsPending,
                'reviews_completed_mtd' => $reviewsCompletedMtd,
                'avg_rating' => $avgRating,
            ],
            'chartGoalsByStatus' => [
                'labels' => $goalStatusLabels,
                'data' => $goalStatusCounts,
            ],
            'chartReviewsTrend' => $reviewsTrend,
            'recentGoals' => $recentGoals,
            'recentReviews' => $recentReviews,
        ]);
    }

    /**
     * @return array{labels: array<int, string>, completed: array<int, int>}
     */
    private function reviewsCompletedByMonth(Carbon $now): array
    {
        $labels = [];
        $completed = [];
        for ($i = 5; $i >= 0; $i--) {
            $d = $now->copy()->subMonths($i);
            $labels[] = $d->format('M Y');
            $completed[] = (int) PerformanceReview::query()
                ->where('status', 'completed')
                ->where(function ($q) use ($d) {
                    $q->where(function ($q1) use ($d) {
                        $q1->whereYear('review_date', $d->year)
                            ->whereMonth('review_date', $d->month);
                    })->orWhere(function ($q2) use ($d) {
                        $q2->whereNull('review_date')
                            ->whereYear('updated_at', $d->year)
                            ->whereMonth('updated_at', $d->month);
                    });
                })
                ->count();
        }

        return ['labels' => $labels, 'completed' => $completed];
    }

    /**
     * @return array<string, mixed>
     */
    private function emptyPayload(): array
    {
        return [
            'kpis' => [
                'total_goals' => 0,
                'goals_active' => 0,
                'goals_on_track' => 0,
                'goals_at_risk' => 0,
                'goals_completed' => 0,
                'goals_overdue' => 0,
                'goals_due_soon' => 0,
                'reviews_pending' => 0,
                'reviews_completed_mtd' => 0,
                'avg_rating' => 0,
            ],
            'chartGoalsByStatus' => ['labels' => [], 'data' => []],
            'chartReviewsTrend' => ['labels' => [], 'completed' => []],
            'recentGoals' => collect(),
            'recentReviews' => collect(),
        ];
    }
}
