<?php

namespace App\Http\Controllers\Admin;

use App\LeaveHistory;
use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\LeaveHistoryResource;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Validator;

class LeaveHistoryController extends Controller
{
	const ITEM_PER_PAGE = 100;
	
	public function index(Request $request)
	{
		$searchParams = $request->all();
		$list = LeaveHistory::query();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$keyword = Arr::get($searchParams, 'keyword', '');
		$employeeId = Arr::get($searchParams, 'employee_id', '');
		$leaveTypeId = Arr::get($searchParams, 'leave_type_id', '');
		$fromDate = Arr::get($searchParams, 'from_date', '');
		$toDate = Arr::get($searchParams, 'to_date', '');
		
		if (!empty($keyword)) {
			$list->where(function ($query) use ($keyword) {
				$query->whereHas('employee', function ($q) use ($keyword) {
					$q->where('full_name', 'LIKE', '%' . $keyword . '%')
						->orWhere('employee_code', 'LIKE', '%' . $keyword . '%');
				})
					->orWhere('description', 'LIKE', '%' . $keyword . '%');
			});
		}
		if (!empty($employeeId)) {
			$list->where('employee_id', $employeeId);
		}
		if (!empty($leaveTypeId)) {
			$list->where('leave_type_id', $leaveTypeId);
		}
		if (!empty($fromDate)) {
			$list->where('from_date', '>=', $fromDate);
		}
		if (!empty($toDate)) {
			$list->where('to_date', '<=', $toDate);
		}
		
		$list->with([
			'employee:id,employee_code,first_name,last_name,full_name',
			'leaveType:id,name,code,affect_tenure,tenure_calculation_rate'
		])
			->orderBy('from_date', 'desc')
			->orderBy('id', 'desc');
		
		return LeaveHistoryResource::collection($list->paginate($limit));
	}
	
	public function all(Request $request)
	{
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$list = LeaveHistory::select(
			'id',
			'employee_id',
			'leave_type_id',
			'from_date',
			'to_date',
			'total_days',
		)
			->with([
				'employee:id,employee_code,first_name,last_name,full_name',
				'leaveType:id,name,code,affect_tenure,tenure_calculation_rate'
			])
			->orderBy('from_date', 'desc')
			->orderBy('id', 'desc');
		
		return LeaveHistoryResource::collection($list->paginate($limit));
	}
	
	public function show($id = 0)
	{
		$leaveHistory = LeaveHistory::with([
			'employee:id,employee_code,first_name,last_name,full_name',
			'leaveType:id,name,code,affect_tenure,tenure_calculation_rate'
		])->findOrFail($id);
		
		return new LeaveHistoryResource($leaveHistory);
	}
	
	public function store(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'employee_id'   => ['required', 'exists:employees,id'],
			'leave_type_id' => ['required', 'exists:leave_types,id'],
			'from_date'     => ['required', 'date'],
			'to_date'       => ['required', 'date', 'after_or_equal:from_date'],
		]);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$params = $request->all();
		
		// Kiểm tra xem có trùng thời gian nghỉ không
		$existingLeave = LeaveHistory::where('employee_id', $params['employee_id'])
			->where(function ($query) use ($params) {
				$query->whereBetween('from_date', [$params['from_date'], $params['to_date']])
					->orWhereBetween('to_date', [$params['from_date'], $params['to_date']]);
			})
			->exists();
		
		if ($existingLeave) {
			return response()->json([
				'error' => 'Cannot create leave history. There is already an overlapping leave period.'
			], 403);
		}
		
		// Tính số ngày nghỉ
		$startDate = \Carbon\Carbon::parse($params['from_date']);
		$endDate = \Carbon\Carbon::parse($params['to_date']);
		$totalDays = $endDate->diffInDays($startDate) + 1;
		
		$leaveHistory = LeaveHistory::create([
			'employee_id'   => $params['employee_id'],
			'leave_type_id' => $params['leave_type_id'],
			'from_date'     => $params['from_date'],
			'to_date'       => $params['to_date'],
			'total_days'    => $totalDays,
			'description'   => $params['description'] ?? null,
		]);
		
		return new LeaveHistoryResource($leaveHistory);
	}
	
	public function update(Request $request, $id = 0)
	{
		$validator = Validator::make($request->all(), [
			'employee_id'   => ['required', 'exists:employees,id'],
			'leave_type_id' => ['required', 'exists:leave_types,id'],
			'from_date'     => ['required', 'date'],
			'to_date'       => ['required', 'date', 'after_or_equal:from_date']
		]);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$leaveHistory = LeaveHistory::findOrFail($id);
		$params = $request->all();
		
		$existingLeave = LeaveHistory::where('employee_id', $params['employee_id'])
			->where('id', '!=', $id)
			->where(function ($query) use ($params) {
				$query->whereBetween('from_date', [$params['from_date'], $params['to_date']])
					->orWhereBetween('to_date', [$params['from_date'], $params['to_date']]);
			})
			->exists();
		
		if ($existingLeave) {
			return response()->json([
				'error' => 'Cannot update leave history. There is already an overlapping leave period.'
			], 403);
		}
		
		// Tính số ngày nghỉ
		$startDate = \Carbon\Carbon::parse($params['from_date']);
		$endDate = \Carbon\Carbon::parse($params['to_date']);
		$totalDays = $endDate->diffInDays($startDate) + 1;
		
		$leaveHistory->update([
			'employee_id'   => $params['employee_id'],
			'leave_type_id' => $params['leave_type_id'],
			'from_date'     => $params['from_date'],
			'to_date'       => $params['to_date'],
			'total_days'    => $totalDays,
			'description'   => $params['description'] ?? null
		]);
		
		return response()->json(null, 204);
	}
	
	public function destroy($id = 0)
	{
		$leaveHistory = LeaveHistory::findOrFail($id);
		$leaveHistory->delete();
		return response()->json(null, 204);
	}
	
	public function destroyMultiple(Request $request)
	{
		$validator = Validator::make($request->all(), ['ids' => 'required']);
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$listIds = $request->get('ids', []);
		LeaveHistory::whereIn('id', $listIds)->delete();
		return response()->json(null, 204);
	}
	
	public function approve($id = 0)
	{
		$leaveHistory = LeaveHistory::findOrFail($id);
		return response()->json(null, 204);
	}
	
	public function reject($id = 0)
	{
		$leaveHistory = LeaveHistory::findOrFail($id);
		return response()->json(null, 204);
	}
}