<?php

namespace App\Http\Controllers;

use App\Http\Requests\CustomScheduleAvailableRequest;
use App\Http\Requests\CustomScheduleProposeRequest;
use App\Http\Requests\CustomScheduleRefuseOpportunityRequest;
use App\Http\Requests\CustomScheduleRequest;
use App\Http\Requests\CustomScheduleVerifyCodeRequest;
use App\Http\Resources\CustomScheduleResource;
use App\Services\CustomScheduleService;
use Illuminate\Http\JsonResponse;

class CustomScheduleController extends Controller
{
    protected $customScheduleService;

    public function __construct(CustomScheduleService $customScheduleService)
    {
        $this->customScheduleService = $customScheduleService;
    }

    public function index(): JsonResponse
    {
        $customSchedules = $this->customScheduleService->getAll();

        return $this->successResponse(
            CustomScheduleResource::collection($customSchedules),
        );
    }

    public function store(CustomScheduleRequest $request): JsonResponse
    {
        try {
            $validated = $request->validated();

            $customSchedules = $this->customScheduleService->create($validated);

            $count = count($customSchedules);

            $message = trans_choice('messages.opportunities_created', $count, ['count' => $count]);

            return $this->successResponse(
                payload: CustomScheduleResource::collection($customSchedules),
                message: $message,
                code:    201,
            );
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 422);
        }
    }

    public function show(string $id): JsonResponse
    {
        $customSchedule = $this->customScheduleService->getById($id);

        return $this->successResponse(
            new CustomScheduleResource($customSchedule),
        );
    }

    public function update(CustomScheduleRequest $request, string $id): JsonResponse
    {
        try {
            $customSchedule = $this->customScheduleService->update($id, $request->validated());

            return $this->successResponse(
                payload: new CustomScheduleResource($customSchedule),
                message: __('messages.updated'),
            );
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 422);
        }
    }

    public function destroy(string $id): JsonResponse
    {
        try {
            $this->customScheduleService->delete($id);

            return $this->successResponse(
                message: __('messages.deleted'),
            );
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 422);
        }
    }

    //

    public function available(CustomScheduleAvailableRequest $request)
    {
        try {
            $providerId = $request->query('provider_id');

            if (! $providerId) {
                return $this->errorResponse(__('messages.provider_id_required'), 400);
            }

            $opportunities = $this->customScheduleService->getAvailableOpportunities($providerId);

            return $this->successResponse($opportunities);
        } catch (\Exception $e) {
            return $this->errorResponse(message: __('messages.error_fetching_data'), code: 500, exception: $e);
        }
    }

    public function getProvidersProposalsAndOpportunities($providerId)
    {
        try {
            $data = $this->customScheduleService->getProvidersProposalsAndOpportunities($providerId);

            return $this->successResponse($data);
        } catch (\Exception $e) {
            return $this->errorResponse(message: __('messages.error_fetching_data'), code: 500, exception: $e);
        }
    }

    public function groupedByClientCustom(): JsonResponse
    {
        $grouped = $this->customScheduleService->getSchedulesCustomGroupedByClient();

        return $this->successResponse($grouped);
    }

    public function opportunityProposals($scheduleId)
    {
        try {
            $proposals = $this->customScheduleService->getOpportunityProposals($scheduleId);

            return $this->successResponse($proposals);
        } catch (\Exception $e) {
            return $this->errorResponse(message: __('messages.error_fetching_data'), code: 500, exception: $e);
        }
    }

    public function providerProposals(CustomScheduleRequest $request)
    {
        try {
            $providerId = $request->query('provider_id');

            if (! $providerId) {
                return $this->errorResponse(__('messages.provider_id_required'), 400);
            }

            $proposals = $this->customScheduleService->getProviderProposals($providerId);

            return $this->successResponse($proposals);
        } catch (\Exception $e) {
            return $this->errorResponse(message: __('messages.error_fetching_data'), code: 500, exception: $e);
        }
    }

    //

    public function propose(CustomScheduleProposeRequest $request, $scheduleId)
    {
        try {
            $providerId = $request->input('provider_id');

            if (! $providerId) {
                return $this->errorResponse(__('messages.provider_id_required'), 400);
            }

            $proposal = $this->customScheduleService->proposeOpportunity($scheduleId, $providerId);

            return $this->successResponse($proposal, __('messages.proposal_sent'), 201);
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 400);
        }
    }

    public function acceptProposal($proposalId)
    {
        try {
            $schedule = $this->customScheduleService->acceptProposal($proposalId);

            return $this->successResponse($schedule, __('messages.provider_accepted'));
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 400);
        }
    }

    public function refuseProposal($proposalId)
    {
        try {
            $this->customScheduleService->refuseProposal($proposalId);

            return $this->successResponse(null, __('messages.provider_refused'));
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 400);
        }
    }

    //

    public function refuseOpportunity($scheduleId, CustomScheduleRefuseOpportunityRequest $request)
    {
        try {
            $this->customScheduleService->refuseOpportunity($scheduleId, $request->input('provider_id'));

            return $this->successResponse(null, __('messages.opportunity_refused'));
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage(), 400);
        }
    }

    //

    public function verifyCode($scheduleId, CustomScheduleVerifyCodeRequest $request)
    {
        try {
            $result = $this->customScheduleService->verifyScheduleCode($scheduleId, $request->input('code'));

            return $this->successResponse($result, __('messages.code_verified'));
        } catch (\Exception $e) {
            return $this->errorResponse(message: __('messages.error_fetching_data'), code: 500, exception: $e);
        }
    }
}
