<?php

namespace Modules\Travel\Http\Controllers\Api\V11;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Modules\Travel\Entities\TravelExpense;
use Modules\Travel\Entities\TravelExpenseLog;
use App\Models\Expenses\IncomeExpenseCategory;
use App\Helpers\CoreApp\Traits\ApiReturnFormatTrait;
use Modules\Travel\Http\Requests\TravelExpenseRequest;
use Modules\Travel\Transformers\TravelExpenseResource;
use Modules\Travel\Http\Enums\ModeOfTransportationEnum;
use Modules\Travel\Repositories\TravelExpenseRepository;
use Modules\Travel\Transformers\TravelExpenseLogResource;

class TravelExpenseApiController extends Controller
{
    use ApiReturnFormatTrait;

    protected $travelExpenseRepo;

    public function __construct()
    {
        $this->travelExpenseRepo = new TravelExpenseRepository;
    }

    /**
     * Display a listing of the resource.
     * @return Response
     */
    public function index()
    {
        try {
            $travelExpenses = TravelExpense::query()
                            ->where('employee_id', auth()->id())
                            ->when(!isAdminOrHr(), fn ($q) => $q->where('employee_id', auth()->id()))
                            ->when(request('travel_plan_id') && request('travel_plan_id') != null, function ($q) {
                                $q->where('travel_plan_id', request('travel_plan_id'));
                            })
                            ->when(request('date') && request('date') != null, function ($q) {
                                $q->where('date', Carbon::parse(request('date'))->format('Y-m-d'));
                            })
                            ->latest('id')
                            ->paginate(10);

            $data           = TravelExpenseResource::collection($travelExpenses)->response()->getData(true);

            return $this->responseWithSuccess('Success', $data, 200);
        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }
    }

    public function expenseLogs($id)
    {
        try {
            $travelExpenseLogs  = TravelExpenseLog::query()
                                ->where('travel_expense_id', $id)
                                ->latest('id')
                                ->get();

            $data               = TravelExpenseLogResource::collection($travelExpenseLogs);

            return $this->responseWithSuccess('Success', $data, 200);
        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }
    }

    public function categories()
    {
        try {
            $travelExpenses = IncomeExpenseCategory::where('type', 'Travel')->where('status_id', 1)->get(['id', 'name']);
            return $this->responseWithSuccess('Success', $travelExpenses, 200);
        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }
    }

    public function modes()
    {
        try {
            $modes = array_map(fn(ModeOfTransportationEnum $mode) => $mode->value, ModeOfTransportationEnum::cases());
            return $this->responseWithSuccess('Success', $modes, 200);
        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Response
     */
    public function store(TravelExpenseRequest $request)
    {
        try {

            $travelExpense = $this->travelExpenseRepo->storeTravelExpense($request, $request->travel_plan_id);

            return $this->responseWithSuccess(__('Travel Meeting has been created successfully!'), new TravelExpenseResource($travelExpense), 200);

        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }        
    }

    /**
     * Show the specified resource.
     * @param int $id
     * @return Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Response
     */
    public function update(TravelExpenseRequest $request, $id)
    {
        try {

            $travelExpense = $this->travelExpenseRepo->updateTravelExpense($request, $request->travel_plan_id, $id);

            return $this->responseWithSuccess(__('Travel Expense has been updated successfully!'), new TravelExpenseResource($travelExpense), 200);

        } catch (\Throwable $th) {
            return $this->responseWithError(__('Something went wrong.'), [$th->getMessage()], 400);
        }        
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Response
     */
    public function destroy($id)
    {
        //
    }
}
