<?php

namespace App\Modules\Company\Whiteboard;

use App\Modules\Company\Whiteboard\AssignWorker\AssignWorkerWithConflict;
use App\Modules\Company\Whiteboard\AssignWorker\AssignWorkerWithoutConflict;
use App\Modules\Company\Whiteboard\AssignWorker\ConflictChecker\AssignedAvailabilityConflictChecker;
use App\Modules\Company\Whiteboard\AssignWorker\ConflictChecker\UnavailableSchedulesConflictChecker;
use App\Modules\Company\Whiteboard\Validation;
use App\Traits\UserTraits;
use App\Traits\ValidatorTraits;
use Illuminate\Support\Facades\DB;

class AssignWorkerToProject
{
    use UserTraits, ValidatorTraits;

    private $assignedAvailabilityConflictChecker;
    private $assignWorkerWithConflict;
    private $assignWorkerWithoutConflict;
    private $unavailableSchedulesConflictChecker;
    private $validation;

    public function __construct()
    {
        $this->assignedAvailabilityConflictChecker = new AssignedAvailabilityConflictChecker;
        $this->unavailableSchedulesConflictChecker = new UnavailableSchedulesConflictChecker;
        $this->assignWorkerWithConflict = new AssignWorkerWithConflict;
        $this->assignWorkerWithoutConflict = new AssignWorkerWithoutConflict;
        $this->validation = new Validation;
    }

    public function assignWorkerToProject($payload)
    {
        $companyId = $this->getCurrentUser()->company_id;
        $projectId = $payload->project_id;
        $workerId = $payload->worker_id;
        $workerType = $payload->worker_type;
        $action = $payload->action;
        $userInputStartDate = date('Y-m-d', strtotime($payload->start_date));
        $userInputEndDate = date('Y-m-d', strtotime($payload->end_date));

        $validation = $this->validation->validatePayloadOnAssigningWorker($payload, $userInputStartDate, $userInputEndDate);
        if (!$validation) {
            return $validation;
        }

        $checkConflictForUnavailableSchedules = $this->unavailableSchedulesConflictChecker->checkConflictForUnavailableSchedules(
            $companyId,
            $workerId,
            $workerType,
            $userInputStartDate,
            $userInputEndDate);
        if ($checkConflictForUnavailableSchedules != 'no conflict') {
            return $checkConflictForUnavailableSchedules;
        }

        $checkConflictForAssignedAvailability = $this->assignedAvailabilityConflictChecker->checkConflictForAssignedAvailability(
            $companyId,
            $workerId,
            $workerType,
            $userInputStartDate,
            $userInputEndDate);
        if ($action == null) {
            if ($checkConflictForAssignedAvailability) {
                return $checkConflictForAssignedAvailability;
            } else {
                DB::beginTransaction();
                $assignWorkerTransaction = $this->assignWorkerWithoutConflict->assign(
                    $companyId,
                    $workerId,
                    $userInputStartDate,
                    $userInputEndDate,
                    $workerType,
                    $projectId);
                if (!$assignWorkerTransaction) {
                    DB::rollBack();
                    return response()->json(['error' => 'Server error.']);
                } else {
                    DB::commit();
                    return response()->json(['success' => 'Data added successfully.'])->setStatusCode(201);
                }
            }
        } else if ($action == 'override') {
            DB::beginTransaction();
            $assignWorkerTransaction = $this->assignWorkerWithConflict->override(
                $companyId,
                $workerId,
                $userInputStartDate,
                $userInputEndDate,
                $workerType,
                $projectId);
            if (!$assignWorkerTransaction) {
                DB::rollBack();
                return response()->json(['error' => 'Server error.']);
            } else {
                DB::commit();
                return response()->json(['success' => 'Data added successfully.'])->setStatusCode(201);
            }
        }
    }
}
