<?php

namespace App\Http\Controllers;

use App\Models\Company;
use App\Models\Department;
use App\Models\Staff;
use App\Models\Unit;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;

class AnalyticsController extends Controller
{
    public function index(Request $request)
    {
        $user         = Auth::user();
        $isSuperAdmin = $user->role === 'super_admin';
        $companyId    = $request->get('company_id');
        $deptId       = $request->get('department_id');

        // ── Base staff scope for overview ─────────────────────────────────────
        $staffQuery = Staff::with(['company', 'department', 'unit']);
        if (!$isSuperAdmin) {
            $staffQuery->where('company_id', $user->company_id);
        } elseif ($companyId) {
            $staffQuery->where('company_id', $companyId);
        }
        if ($deptId) {
            $staffQuery->where('department_id', $deptId);
        }

        $staff = $staffQuery->get();
        $now   = Carbon::now();

        // ── Overview charts ───────────────────────────────────────────────────
        $byCompany = $staff->groupBy(fn ($s) => $s->company?->name ?? 'Unknown')
            ->map->count()->sortDesc();

        $byGender = $staff->groupBy(fn ($s) => ucfirst($s->gender ?? 'Unknown'))
            ->map->count()->sortDesc();

        $byEmploymentType = $staff->groupBy(fn ($s) => $s->employment_type ?? 'Unknown')
            ->map->count()->sortDesc();

        $byStatus = $staff->groupBy(fn ($s) => ucfirst($s->status ?? 'Unknown'))
            ->map->count()->sortDesc();

        $byDepartment = $staff->groupBy(fn ($s) => $s->department?->name ?? 'Unassigned')
            ->map->count()->sortDesc()->take(10);

        $byUnit = $staff->groupBy(fn ($s) => $s->unit?->name ?? 'Unassigned')
            ->map->count()->sortDesc()->take(10);

        $byAgeGroup = $staff->groupBy(function ($s) use ($now) {
            if (!$s->date_of_birth) return 'Unknown';
            $age = Carbon::parse($s->date_of_birth)->age;
            if ($age < 25) return '< 25';
            if ($age < 35) return '25–34';
            if ($age < 45) return '35–44';
            if ($age < 55) return '45–54';
            return '55+';
        })->map->count();

        $ageOrder   = ['< 25', '25–34', '35–44', '45–54', '55+', 'Unknown'];
        $byAgeGroup = collect($ageOrder)->filter(fn ($k) => $byAgeGroup->has($k))
            ->mapWithKeys(fn ($k) => [$k => $byAgeGroup[$k]]);

        $byTenure = $staff->groupBy(function ($s) use ($now) {
            if (!$s->join_date) return 'Unknown';
            $years = Carbon::parse($s->join_date)->diffInYears($now);
            if ($years < 1)  return '< 1 year';
            if ($years < 3)  return '1–2 years';
            if ($years < 5)  return '3–4 years';
            if ($years < 10) return '5–9 years';
            return '10+ years';
        })->map->count();

        $tenureOrder = ['< 1 year', '1–2 years', '3–4 years', '5–9 years', '10+ years', 'Unknown'];
        $byTenure    = collect($tenureOrder)->filter(fn ($k) => $byTenure->has($k))
            ->mapWithKeys(fn ($k) => [$k => $byTenure[$k]]);

        $byNationality = $staff->groupBy(fn ($s) => $s->nationality ?? 'Unknown')
            ->map->count()->sortDesc()->take(8);

        // ── By Company breakdown (super_admin only) ───────────────────────────
        $companyBreakdown = collect();
        if ($isSuperAdmin) {
            foreach (Company::orderBy('name')->get() as $c) {
                $cStaff = Staff::with(['department', 'unit'])
                    ->where('company_id', $c->id)->get();

                $companyBreakdown->push([
                    'id'                 => $c->id,
                    'name'               => $c->name,
                    'industry'           => $c->industry,
                    'total'              => $cStaff->count(),
                    'active'             => $cStaff->where('status', 'active')->count(),
                    'by_gender'          => $cStaff->groupBy(fn ($s) => ucfirst($s->gender ?? 'Unknown'))->map->count()->sortDesc(),
                    'by_status'          => $cStaff->groupBy(fn ($s) => ucfirst($s->status ?? 'Unknown'))->map->count()->sortDesc(),
                    'by_employment_type' => $cStaff->groupBy(fn ($s) => $s->employment_type ?? 'Unknown')->map->count()->sortDesc(),
                    'by_department'      => $cStaff->groupBy(fn ($s) => $s->department?->name ?? 'Unassigned')->map->count()->sortDesc()->take(6),
                ]);
            }
        }

        // ── By Department breakdown ───────────────────────────────────────────
        $deptQuery = Department::with('company');
        if (!$isSuperAdmin) {
            $deptQuery->where('company_id', $user->company_id);
        } elseif ($companyId) {
            $deptQuery->where('company_id', $companyId);
        }

        $departmentBreakdown = $deptQuery->orderBy('name')->get()->map(function ($d) {
            $dStaff = Staff::with('unit')->where('department_id', $d->id)->get();

            return [
                'id'                 => $d->id,
                'name'               => $d->name,
                'company'            => $d->company?->name,
                'total'              => $dStaff->count(),
                'active'             => $dStaff->where('status', 'active')->count(),
                'by_gender'          => $dStaff->groupBy(fn ($s) => ucfirst($s->gender ?? 'Unknown'))->map->count()->sortDesc(),
                'by_status'          => $dStaff->groupBy(fn ($s) => ucfirst($s->status ?? 'Unknown'))->map->count()->sortDesc(),
                'by_employment_type' => $dStaff->groupBy(fn ($s) => $s->employment_type ?? 'Unknown')->map->count()->sortDesc(),
                'by_unit'            => $dStaff->groupBy(fn ($s) => $s->unit?->name ?? 'Unassigned')->map->count()->sortDesc(),
            ];
        });

        // ── By Unit breakdown ─────────────────────────────────────────────────
        $unitQuery = Unit::with('department.company');
        if (!$isSuperAdmin) {
            $unitQuery->whereHas('department', fn ($q) => $q->where('company_id', $user->company_id));
        } elseif ($companyId) {
            $unitQuery->whereHas('department', fn ($q) => $q->where('company_id', $companyId));
        }
        if ($deptId) {
            $unitQuery->where('department_id', $deptId);
        }

        $unitBreakdown = $unitQuery->orderBy('name')->get()->map(function ($u) {
            $uStaff = Staff::where('unit_id', $u->id)->get();

            return [
                'id'                 => $u->id,
                'name'               => $u->name,
                'department'         => $u->department?->name,
                'company'            => $u->department?->company?->name,
                'total'              => $uStaff->count(),
                'active'             => $uStaff->where('status', 'active')->count(),
                'by_gender'          => $uStaff->groupBy(fn ($s) => ucfirst($s->gender ?? 'Unknown'))->map->count()->sortDesc(),
                'by_status'          => $uStaff->groupBy(fn ($s) => ucfirst($s->status ?? 'Unknown'))->map->count()->sortDesc(),
                'by_employment_type' => $uStaff->groupBy(fn ($s) => $s->employment_type ?? 'Unknown')->map->count()->sortDesc(),
            ];
        });

        // ── Filter option lists ───────────────────────────────────────────────
        $companies = $isSuperAdmin
            ? Company::orderBy('name')->get(['id', 'name'])
            : collect();

        $departmentsList = Department::query()
            ->when(!$isSuperAdmin, fn ($q) => $q->where('company_id', $user->company_id))
            ->when($companyId && $isSuperAdmin, fn ($q) => $q->where('company_id', $companyId))
            ->orderBy('name')
            ->get(['id', 'name', 'company_id']);

        $totalDepts = Department::when(
            !$isSuperAdmin,
            fn ($q) => $q->where('company_id', $user->company_id)
        )->count();

        $totalUnits = Unit::when(
            !$isSuperAdmin,
            fn ($q) => $q->whereHas('department', fn ($dq) => $dq->where('company_id', $user->company_id))
        )->count();

        return Inertia::render('Analytics/Index', [
            'stats' => [
                'total'       => $staff->count(),
                'active'      => $staff->where('status', 'active')->count(),
                'companies'   => $isSuperAdmin ? Company::count() : 1,
                'departments' => $totalDepts,
                'units'       => $totalUnits,
            ],
            'byCompany'           => $byCompany,
            'byGender'            => $byGender,
            'byEmploymentType'    => $byEmploymentType,
            'byStatus'            => $byStatus,
            'byDepartment'        => $byDepartment,
            'byUnit'              => $byUnit,
            'byAgeGroup'          => $byAgeGroup,
            'byTenure'            => $byTenure,
            'byNationality'       => $byNationality,
            'companyBreakdown'    => $companyBreakdown,
            'departmentBreakdown' => $departmentBreakdown,
            'unitBreakdown'       => $unitBreakdown,
            'companies'           => $companies,
            'departments'         => $departmentsList,
            'filters'             => [
                'company_id'    => $companyId,
                'department_id' => $deptId,
            ],
        ]);
    }
}
