<?php

namespace App\Http\Controllers\Backend\Attendance;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Brian2694\Toastr\Facades\Toastr;
use App\Models\HRM\Attendance\Holiday;
use App\Repositories\HolidayRepository;
use App\Models\Hrm\Department\Department;
use App\Http\Requests\HolidayAssignRequest;
use App\Helpers\CoreApp\Traits\AuthorInfoTrait;
use Modules\SpecialAttendance\Entities\DutyCalendar;
use App\Models\coreApp\Relationship\RelationshipTrait;

class HolidayController extends Controller
{
    use AuthorInfoTrait, RelationshipTrait;

    protected $holidayRepository;
    protected $model;

    public function __construct(HolidayRepository $holidayRepository, Holiday $holiday)
    {
        $this->holidayRepository = $holidayRepository;
        $this->model = $holiday;
    }

    public function index(Request $request)
    {
        try {
            if ($request->ajax()) {
                return $this->holidayRepository->table($request);
            }
            $data['table']    = route('holidaySetup.index');
            $data['url_id']    = 'holiday_table_url';
            $data['class']     = 'table_class';
            $data['delete_url'] =  route('holidaySetup.deleteData');
            $data['checkbox'] = false;

            $data['fields'] = $this->holidayRepository->fields();
            $data['title'] = _trans('leave.Holiday list');
            $data['holidays'] = $this->holidayRepository->index();
            return view('backend.attendance.holiday.index', compact('data'));
        } catch (\Throwable $th) {
            Toastr::error(_trans('response.Something went wrong.'), 'Error');
            return redirect()->back();
        }
    }

    public function create()
    {
        $data['title'] = _trans('leave.Add holiday');

        return view('backend.attendance.holiday.create', compact('data'));
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'title' => 'required',
            'description' => 'required',
            'start_date' => 'required|date|after:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'status_id' => 'required'
        ], [
            'title.required'                    => _trans('common.Title_required'),
            'description.required'              => _trans('common.Description_required'),
            'start_date.required'               => _trans('common.Start date required'),
            'start_date.date'                   => _trans('common.Start date must be_date'),
            'start_date.start_date_after_today' => _trans('common.Start date must after today'),
            'end_date.required'                 => _trans('common.End date required'),
            'end_date.date'                     => _trans('common.End date must be date'),
            'end_date.after_or_equal'           => _trans('common.End date after or equal start date'),
            'status_id.required'                => _trans('common.Status required'),
        ]);

        try {
            $exists = $this->model->where(function ($query) use ($request) {
                $query->whereBetween('start_date', [$request->start_date, $request->end_date])
                    ->orWhereBetween('end_date', [$request->start_date, $request->end_date])
                    ->orWhere(function ($q) use ($request) {
                        $q->where('start_date', '<=', $request->start_date)
                            ->where('end_date', '>=', $request->end_date);
                    });
            })->exists();

            if ($exists) {
                return back()->withErrors(['start_date' => 'A holiday already exists within this date range.'])->withInput();
            }

            $this->holidayRepository->store($request);

            Toastr::success(_trans('response.Operation successful'), 'Success');
            return redirect()->route('holidaySetup.index');
        } catch (\Exception $exception) {
            info($exception->getMessage());
            Toastr::error(_trans('response.Something went wrong'), 'Error');
            return redirect()->back();
        }
    }

    public function show(Holiday $holiday)
    {
        $data['title'] = _trans('leave.Edit Holiday');
        $data['holiday'] = $holiday;

        return view('backend.attendance.holiday.edit', compact('data'));
    }

    public function update(Request $request, Holiday $holiday)
    {
        $this->validate($request, [
            'title' => 'required',
            'description' => 'required',
            'start_date' => 'required|date|after:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'status_id' => 'required'
        ], [
            'title.required'                    => _trans('common.Title_required'),
            'description.required'              => _trans('common.Description_required'),
            'start_date.required'               => _trans('common.Start date required'),
            'start_date.date'                   => _trans('common.Start date must be_date'),
            'start_date.start_date_after_today' => _trans('common.Start date must after today'),
            'end_date.required'                 => _trans('common.End date required'),
            'end_date.date'                     => _trans('common.End date must be date'),
            'end_date.after_or_equal'           => _trans('common.End date after or equal start date'),
            'status_id.required'                => _trans('common.Status required'),
        ]);

        try {

            $exists = $this->model->where(function ($query) use ($request) {
                $query->whereBetween('start_date', [$request->start_date, $request->end_date])
                    ->orWhereBetween('end_date', [$request->start_date, $request->end_date])
                    ->orWhere(function ($q) use ($request) {
                        $q->where('start_date', '<=', $request->start_date)
                            ->where('end_date', '>=', $request->end_date);
                    });
            })->where('id', '!=', $holiday->id)->exists();

            if ($exists) {
                return back()->withErrors(['start_date' => 'A holiday already exists within this date range.'])->withInput();
            }

            $this->holidayRepository->update($request, $holiday);

            Toastr::success(_trans('response.Operation successful'), 'Success');
            return redirect()->route('holidaySetup.index');
        } catch (\Exception $exception) {
            info($exception->getMessage());
            Toastr::error(_trans('response.Something went wrong'), 'Error');
            return redirect()->back();
        }
    }

    public function delete(Holiday $holiday_id)
    {
        try {
            $dutyCalendar = DutyCalendar::where('holiday_id', $holiday_id->id)->exists();

            if ($dutyCalendar) {
                Toastr::error(_trans('response.This holiday is used in duty calendar'), 'Error');
                return redirect()->back();
            }

            $this->holidayRepository->delete($holiday_id);
            Toastr::success(_trans('leave.Holiday has been deleted'), 'Success');
            return redirect()->back();
        } catch (\Exception $exception) {
            info($exception->getMessage());
            Toastr::error(_trans('response.Something went wrong'), 'Error');
            return redirect()->back();
        }
    }

    public function deleteData(Request $request)
    {
        if (demoCheck()) {
            return $this->responseWithError(_trans('message.You cannot delete for demo'), [], 400);
        }
        return $this->holidayRepository->destroyAll($request);
    }

    public function assignModal()
    {
        try {
            $data['title']  = _trans('attendance.Holiday Assign');
            $data['url']    = route('holidaySetup.assign');
            $data['button'] = _trans('common.Save');

            $data['departments'] = Department::select('id', 'title')->get();

            $data['holidays'] = Holiday::where('status_id', 1)
                ->where('year', date('Y'))
                ->get(['id', 'title', 'start_date', 'end_date'])
                ->map(function ($item) {
                    $item->holiday = $item->title . ' [' . $item->start_date . ' - ' . $item->end_date . ']';

                    return $item;
                });

            return view('backend.attendance.holiday.assign-modal', compact('data'));
        } catch (\Throwable $th) {
            return response()->json('fail');
        }
    }

    public function assign(HolidayAssignRequest $request)
    {
        try {
            return $this->holidayRepository->assign($request);
        } catch (\Throwable $th) {
            Toastr::error(_trans('response.Please click on button!'), 'Error');
            return redirect()->back();
        }
    }
}
