<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Modules\Hr\TimeLog;
use App\Modules\Hr\UserDetails;
use App\Modules\Hr\Models\ProcessedTimeLog;
use App\Models\User;

class ProcessTimeLogs extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'process:timelogs';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Processes the clocking time logs.';

    protected $start_date;
    protected $end_date;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();

        $this->start_date = Carbon::yesterday()->toDateString();
        $this->end_date = Carbon::yesterday()->endOfDay()->toDateString();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $users = User::get(['id']);

        $users->each(function($user) {
            $this->processUserTimeLogs($user->id);
        });

        $this->info('Command executed succesfully.');
    }

    protected function processUserTimeLogs($user_id)
    {
        $user_details = UserDetails::find($user_id);
        $ratePerHour = $user_details ? $user_details->rate_per_hour : 7;
        $department_id = $user_details ? $user_details->department_id : null;

        // Fetch the clocking times for the interval $start - $end - MODERNIZED
        $in = TimeLog::where('user_id', $user_id)
                     ->whereDate('time', '>=', $this->start_date)
                     ->whereDate('time', '<=', $this->end_date)
                     ->where('type', 'in')
                     ->orderBy('time', 'asc')
                     ->get();

        $out = TimeLog::where('user_id', $user_id)
                     ->whereDate('time', '>=', $this->start_date)
                     ->whereDate('time', '<=', $this->end_date)
                     ->where('type', 'out')
                     ->orderBy('time', 'asc')
                     ->get();

        // Generate a data array of all the times
        $data = [];
        $total_hours = 0;
        $total_money = 0;

        foreach ($in as $i => $clockIn) {
            $date = date('Y-m-d', strtotime($clockIn->time));
            $found = false;

            foreach ($out as $j => $clockOut) {
                if ($date == date('Y-m-d', strtotime($clockOut->time))) {
                    $dt1 = Carbon::parse($clockOut->time);
                    $dt2 = Carbon::parse($clockIn->time);
                    $hours = number_format($dt1->diffInSeconds($dt2) / 3600, 2);
                    $money = number_format($hours * $ratePerHour, 2);
                    $data[] = [$date, $clockIn->time, $clockOut->time, $hours, $money];
                    $total_hours += $hours;
                    $total_money += $money;
                    $found = true;
                    unset($out[$j]);
                    break;
                }
            }

            if (! $found) {
                $data[] = [$date, $clockIn->time, null, 0, 0];
            }

            unset($in[$i]);
        }

        // Check the left clockout times
        foreach ($out as $j => $clockOut) {
            $date = date('Y-m-d', strtotime($clockOut->time));
            $data[] = [$date, null, $clockOut->time, null, 0, 0];
        }

        // Sort the results by the date
        usort($data, function ($a, $b) {
            return $b[1] < $a[1];
        });

        foreach ($data as $value) {
            ProcessedTimeLog::create([
                'user_id'       => $user_id,
                'date'          => $value[0],
                'clock_in'      => $value[1],
                'clock_out'     => $value[2],
                'hours'         => $value[3] ? : 0,
                'money'         => $value[4] ? : 0,
                'department_id' => $department_id,
            ]);
        }
    }

}
