<?php

namespace App\Http\Controllers\Api\Hrms;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

use App\Models\Hrms\Attendance;
use App\Models\Hrms\Employee;
use App\Models\Hrms\ShiftMaster;
use App\Models\Hrms\AssingShift;
use App\Models\Hrms\LeaveMaster;
use App\Models\Hrms\Leave;
use App\Models\User;
use Validator;
use Auth;

class DashboardController extends Controller
{

    public function attendancePunchInPunchOut(Request $request)
    {
        $user = Auth::user();
        $todayDate = date('d-m-Y');
    
        try {
            // Collect punch in/out data if provided
            $data = ['punch_in', 'punch_out'];
            $obj = [];
            foreach ($data as $value) {
                if (!empty($request[$value])) {
                    $obj[$value] = $request[$value];
                }
            }
    
            // Get shift details for the user
            $shiftMaster = ShiftMaster::find($user['shift_id']);
            if (!$shiftMaster) {
                return response()->json(['error' => true, 'message' => 'Shift not found for the user'], 404);
            }
    
            // Populate attendance object
            $obj['user_id'] = $user->id;
            $obj['user_name'] = $user->first_name;
            $obj['date'] = $todayDate;
            $obj['shift_name'] = $shiftMaster->shift_name ?? '-';
            $obj['shift_id'] = $user->shift_id;
            $obj['status'] = '0'; // present
    
            if ($request->id > 0) {
                // Update existing attendance record
                try {
                    $attendance = Attendance::findOrFail($request['id']);
    
                    // Calculate punch-in and punch-out times
                    $punchInTime = new \DateTime($attendance['punch_in']);
                    $punchOutTime = new \DateTime($request['punch_out']);
    
                    // Handle punch-out time crossing midnight
                    if ($punchOutTime < $punchInTime) {
                        $punchOutTime->modify('+1 day');
                    }
    
                    // Calculate total hours worked
                    $interval = $punchInTime->diff($punchOutTime);
                    $total_hours_worked = $interval->format('%h Hrs and %i min');
                    $obj['total_hours_worked'] = $total_hours_worked;
    
                    // Calculate overtime if punch-out is after shift end time
                    $endtime = new \DateTime($request['punch_out']);
                    if ($punchOutTime > $endtime) {
                        $overtimeInterval = $endtime->diff($punchOutTime);
                        $total_overtime_worked = $overtimeInterval->format('%h Hrs and %i min');
                    } else {
                        $total_overtime_worked = "0 Hrs and 0 min";
                    }
                    $obj['overtime'] = $total_overtime_worked;
    
                    // Update attendance
                    $attendance->update($obj);
    
                } catch (\Exception $e) {
                    return response()->json(['error' => true, 'message' => 'Invalid ID to update'], 404);
                }
            } else {

                $checkAttendance = Attendance::where('user_id', $user->id)
                ->where('date',$todayDate)->where('is_disabled','0')
                ->where('organisation_id', $user['active_organisation'])
                ->first();

                if ($checkAttendance != null) {
                    $response = [
                        'message' => "Attendance already exist",
                        'success' => false,
                        'vendor' => $checkAttendance,
                    ];

                    return response()->json($response);
                }

                // Create a new attendance record
                $obj['punch_out'] = "-";
                $obj['total_hours_worked'] = "-";
                $obj['overtime'] = "-";
    
                $attendance = Attendance::create($obj);
            }
    
            return response()->json([
                'status' => 200,
                'message' => $request->id > 0 ? 'Punch out successfully' : 'Punch in successfully',
                'result' => $attendance
            ], 200);
    
        } catch (\Exception $e) {
            return response()->json(['error' => true, 'message' => $e->getMessage()], 500);
        }
    }
    
    public function getTodayAttendance(Request $request){

        $user=Auth::user();
        $todayDate = date('Y-m-d');

        if($user!=null){

            $attendanceList=Attendance::where('is_disabled','0')->where('user_id',$user['id'])
                ->whereDate('created_at',$todayDate)
                ->with('shiftMaster')
                ->with('employee');
                // ->where('organisation_id',$user['active_organisation']);

            $total_count = $attendanceList->count();
    
            $attendanceList = $attendanceList->orderby('id','desc')
                ->skip($request['noofrec']*($request['currentpage']-1))->take($request['noofrec']??100)
                ->first();

            $response=[
                'result'=>$attendanceList,
                'total_count'=>$total_count,
                'message'=>'Successful',
            ];

        } else {
            $response=[
                'result'=>$attendanceList,
                'total_count'=>$total_count,
                'message'=>'Invalid User'
            ];
        }

        return response()->json($response);
    }

    public function employeeStats(Request $request)
    {
        $user = Auth::user();
    
        if ($user != null) {
            // Get the current date
            $todayDate = date('Y-m-d');
    
            // Get the first and last date of the current month
            $currentMonthStart = date('Y-m-01');
            $currentMonthEnd = date('Y-m-t') . ' 23:59:59'; 
    
            // Get the first and last date of the last month
            $lastMonthStart = date('Y-m-01', strtotime('first day of last month'));
            $lastMonthEnd = date('Y-m-t', strtotime('last day of last month')) . ' 23:59:59'; 
    
            // Query to get all employees
            $employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation']);
    
            // 1. Total number of employees (Current month)
            $all_employee = $employee->count();
    
            // 1.1 Total number of employees (Last month)
            $last_month_all_employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->whereDate('created_at', '<=', $lastMonthEnd)
                ->count();
    
            // 2. Number of new employees in the current month
            $this_month_new_employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->where('updated_at', '>=', $currentMonthStart)->where('updated_at', '<=', $currentMonthEnd)
                ->count();
    
            // 2.1 Number of new employees in the last month
            $last_month_new_employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->whereDate('created_at', '<=', $lastMonthEnd)
                ->count();
    
            // 3. Number of resigned employees in the current month
            $this_month_resigned_employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->where('employee_status', 'Resigned')
                ->where('updated_at', '>=', $currentMonthStart)->where('updated_at', '<=', $currentMonthEnd)
                ->count();
    
            // 3.1 Number of resigned employees in the last month
            $last_month_resigned_employee = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->where('employee_status', 'Resigned')
                ->where('updated_at', '>=', $lastMonthStart)->where('updated_at', '<=', $lastMonthEnd)

                ->count();
    
            // 4. Number of employees on leave in the current month
            $this_month_on_leave = Leave::where('organisation_id', $user['active_organisation'])
                ->where('updated_at', '>=', $currentMonthStart)->where('updated_at', '<=', $currentMonthEnd)
                ->distinct('user_id') // Get unique users on leave
                ->count('user_id');
    
            // 4.1 Number of employees on leave in the last month
            $last_month_on_leave = Leave::where('organisation_id', $user['active_organisation'])
                ->where('updated_at', '>=', $lastMonthStart)->where('updated_at', '<=', $lastMonthEnd)
                ->distinct('user_id') // Get unique users on leave
                ->count('user_id');
    
            // Prepare response
            $response = [
                'all_employee' => $all_employee,
                'last_month_all_employee' => $last_month_all_employee,
                'new_employee' => $this_month_new_employee,
                'last_month_new_employee' => $last_month_new_employee,
                'resigned_employee' => $this_month_resigned_employee,
                'last_month_resigned_employee' => $last_month_resigned_employee,
                'on_leave' => $this_month_on_leave,
                'last_month_on_leave' => $last_month_on_leave,
                'message' => 'Successful',
            ];
        } else {
            // Return empty response for invalid user
            $response = [
                'all_employee' => 0,
                'last_month_all_employee' => 0,
                'new_employee' => 0,
                'last_month_new_employee' => 0,
                'resigned_employee' => 0,
                'last_month_resigned_employee' => 0,
                'on_leave' => 0,
                'last_month_on_leave' => 0,
                'message' => 'Invalid User',
            ];
        }
    
        return response()->json($response);
    }
    
    public function getAttendanceOverview(Request $request)
    {
        $user = Auth::user();
        $response = [];
        
        if ($user != null) {
            $todayDate = date('d-m-Y');
    
            // Determine the time period
            $filter = $request->input('filter', 'today'); // Default to "today"
            $startDate = $todayDate;
            $endDate = $todayDate;
    
            if ($filter == 'week') {
                $startDate = date('d-m-Y', strtotime('monday this week'));
                $endDate = date('d-m-Y', strtotime('sunday this week'));
            } elseif ($filter == 'month') {
                $startDate = date('01-m-Y');
                $endDate = date('t-m-Y');
            }
    
            // Base attendance query
            $attendanceList = Attendance::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->where('date', '>=', $startDate)->where('date', '<=', $endDate);

    
            // Counts for the selected period
            $total_present = (clone $attendanceList)->where('status', '0')->count();
            $total_absent = (clone $attendanceList)->where('status', '1')->count();
            $total_halfday = (clone $attendanceList)->where('status', '2')->count();
    
            // Total employees in the organization
            
            $total_emp = Employee::where('is_disabled', '0')
                ->where('organisation_id', $user['active_organisation'])
                ->count();

    
            // Response data
            $response = [
                'total_employee' => $total_emp,
                'total_present' => $total_present,
                'total_absent' => $total_absent,
                'total_halfday' => $total_halfday,
                'message' => 'Successful',
            ];
        } else {
            $response = [
                'message' => 'Invalid User',
            ];
        }
    
        return response()->json($response);
    }
    
    public function leaveTypeReport(Request $request)
    {
        $auth = Auth::user();
    
        try {
            $leaveMaster = LeaveMaster::where('is_disabled', '0')
                ->where('organisation_id', $auth['active_organisation'])
                ->get();
    
            $leaveReport = [];
    
            foreach ($leaveMaster as $leaveType) {
                $leave = Leave::where('leave_type_id', $leaveType->id)
                    ->where('is_disabled', '0')->where('organisation_id', $auth['active_organisation']);

                $fromDate = date('Y-m-01'); //month startdate
                $toDate = date('Y-m-t'); //month enddate

                $approved_leaves_count= (clone $leave)->where('status','Approved')
                ->where('updated_at', '>=', $fromDate)->where('updated_at', '<=', $toDate)->count();
                $pending_leaves_count= (clone $leave)->where('status','Pending')
                ->where('updated_at', '>=', $fromDate)->where('updated_at', '<=', $toDate)->count();
                $declined_leaves_count= (clone $leave)->where('status','Declined')
                ->where('updated_at', '>=', $fromDate)->where('updated_at', '<=', $toDate)->count();
                
                $totalCount = $approved_leaves_count + $pending_leaves_count + $declined_leaves_count;
                
                $leaveReport[] = [
                    'leave_type_id' => $leaveType->id, 
                    'leave_type' => $leaveType->leave_type, 
                    'available_days' => $leaveType->available_days,
                    'approved_leaves_count' => $approved_leaves_count,
                    'pending_leaves_count' => $pending_leaves_count,
                    'declined_leaves_count' => $declined_leaves_count,
                    'total_leaves_count' => $totalCount,
                ];
            }
    
            $response = [
                'success' => true,
                'leave_report' => $leaveReport,
            ];
    
            return response()->json($response);
    
        } catch (\Exception $e) {
            return response(['error' => true, 'message' => $e->getMessage()], 404);
        }
    }
    
    


}



