<?php
namespace App\Modules\HR\Reports\Data;

use App\Modules\HR\Core\Models\Employee;
use Carbon\Carbon;

class EmployeeBirthdayReport
{
    public function getData($filters)
    {
        $start = Carbon::parse($filters['from_date']);
        $end   = Carbon::parse($filters['to_date']);

        $startMonth = $start->month;
        $startDay   = $start->day;

        $endMonth = $end->month;
        $endDay   = $end->day;

        $query = Employee::query()
            ->whereNotNull('date_of_birth');

        /*
        =========================
        BRANCH FILTER
        =========================
        */
        if (!empty($filters['branch_id'])) {
            $query->where('branch_id', $filters['branch_id']);
        }

        /*
        =========================
        DEPARTMENT FILTER
        =========================
        */
        if (!empty($filters['department_id'])) {
            $query->where('department_id', $filters['department_id']);
        }

        /*
        =========================
        BIRTHDAY RANGE FILTER
        =========================
        */

        if ($startMonth == $endMonth) {

            // Same month
            $query->whereMonth('date_of_birth', $startMonth)
                  ->whereDay('date_of_birth', '>=', $startDay)
                  ->whereDay('date_of_birth', '<=', $endDay);

        } else {

            $query->where(function ($q) use ($startMonth, $startDay, $endMonth, $endDay) {

                // From start month
                $q->where(function ($sub) use ($startMonth, $startDay) {
                    $sub->whereMonth('date_of_birth', $startMonth)
                        ->whereDay('date_of_birth', '>=', $startDay);
                })

                // Months between
                ->orWhere(function ($sub) use ($startMonth, $endMonth) {
                    $sub->whereMonth('date_of_birth', '>', $startMonth)
                        ->whereMonth('date_of_birth', '<', $endMonth);
                })

                // End month
                ->orWhere(function ($sub) use ($endMonth, $endDay) {
                    $sub->whereMonth('date_of_birth', $endMonth)
                        ->whereDay('date_of_birth', '<=', $endDay);
                });
            });
        }

        /*
        =========================
        SORT BY MONTH & DAY
        =========================
        */
        $employees = $query
            ->orderByRaw('MONTH(date_of_birth), DAY(date_of_birth)')
            ->get();

        return [
            'employees' => $employees,
            'filters'   => $filters
        ];
    }
}
