<?php

namespace App\Http\Controllers\API\v1;

use App\Http\Controllers\Controller;
use App\Models\Employee;
use App\Models\EmployeePaymentContributionHistory;
use App\Models\Loan;
use App\Models\PaymentContribution;
use App\Models\PaymentContributionHistory;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Throwable;

class PaymentContributionController extends Controller
{
    public function index(Request $request)
    {
        //
        $keyword = $request->input('keyword', null);
        $perPage = $request->input('per_page',PHP_INT_MAX);
        $sortBy = $request->input('sortBy', '');
        $sortType = $request->input('sortType', '');

        $data = PaymentContribution::with(
            'employee:id,employee_id,firstname,lastname',
            'payroll_item:id,name'
            )
            ->whereHas('payroll_item', fn($q) => $q->whereNull('deleted_at'))
            ->when($keyword, function($q) use ($keyword) {
            $keyword = str_replace([';',','], ' ',$keyword);
            $keyword = str_replace('  ',' ',$keyword);
            $keywords = explode(" ",$keyword);
            foreach($keywords as $word) {
                $q->where(fn($q2) => $q2->where('employee_id','like',"{$word}%")
                    ->orWhereHas('employee', fn($q3) =>
                        $q3->where('lastname', 'like',"%{$word}%")
                        ->orWhere('middlename', 'like',"%{$word}%")
                        ->orWhere('firstname', 'like',"%{$word}%"))
                    ->orWhereHas('payroll_item', fn($q3) =>
                        $q3->where('name', 'like',"%{$word}%")));
            };
        });

        // Handling sorting
        if (!empty($sortBy) && !empty($sortType)) {
            // Check if the sortBy is 'fullname', then sort by both firstname and lastname
            if ($sortBy === 'fullname') {
                $data = $data->join('employees', 'payment_contributions.employee_id', '=', 'employees.employee_id')
                            ->orderBy('employees.firstname', $sortType)
                            ->orderBy('employees.lastname', $sortType);
            } else {
                $data = $data->orderBy($sortBy, $sortType);
            }
        }

        $data = $data->orderBy('created_at', 'desc')->paginate($perPage);
        return response()->json($data);
    }

    public function show(string $id)
    {
        $data = EmployeePaymentContributionHistory::where('employee_pc_id', '=', $id)->get();

        return response()->json($data);
    }

    public function getRecordByEmployee(Request $request)
    {
        $employee = Auth::user();

        //
        $keyword = $request->input('keyword', '');
        $perPage = $request->input('per_page',PHP_INT_MAX);
        $sortBy = $request->input('sortBy', '');
        $sortType = $request->input('sortType', '');

        $data = PaymentContribution::with(
            'employee:id,employee_id,firstname,lastname',
            'payroll_item:id,name'
            )->where(function ($query) use ($keyword) {
                $keyword = str_replace(" ", "%", $keyword);
                $query->where('employee_id', 'like', '%' . $keyword . '%');
            });

        if (!empty($sortBy) && !empty($sortType)) {
            $data = $data->orderBy($sortBy, $sortType);
        }

        $data = $data->where('employee_id', $employee->employee_id);
        $data = $data->paginate($perPage);

        return response()->json($data);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'employee_id' => "required",
        ]);

        if ($validator->fails()) {
            return $this->validationErrorResponse($validator);
        }

        $user = Employee::where('employee_id', $request->employee_id)->first();

        DB::beginTransaction();

        try {

            $status = PaymentContribution::create([
                'employee_id' => $request->employee_id,
                'company_id' => $user->company_id,
                'dealer_id' => $user->dealer_id,
                'contribution_id' => $request->contribution_id,
                'amount' => $request->amount,
                'frequency' => $request->frequency,
                'effectivity_date' => $request->effectivity_date,
                'credit' => $request->credit,
                'remarks' => $request->remarks,
            ]);

            DB::commit();

            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $status
            ], 201);

        } catch (Exception $e) {
            DB::rollBack();
            return response()->json([
                'status' => false,
                'message' => 'An error occurred!',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function update(Request $request, int $id)
    {
        $data = PaymentContribution::where('id', $id)->first();

        // dd($request->all());
        $validator = Validator::make($request->all(), [
            'employee_id' => "required",
        ]);

        /** If validation fails return with error message */
        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        DB::connection()->beginTransaction();

        try {
            $data->employee_id = $request->employee_id;
            $data->contribution_id = $request->contribution_id;
            $data->amount = $request->amount;
            $data->frequency = $request->frequency;
            $data->credit = $request->credit;
            $data->effectivity_date = $request->effectivity_date;
            $data->remarks = $request->remarks;

            $data->save();

            DB::connection()->commit();

            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $data
            ],201);

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    private function validationErrorResponse($validator)
    {
        return response()->json([
            'status' => false,
            'message' => 'Validation failed!',
            'error' => $validator->errors()
        ], 422);
    }

    public function activation(Request $request, int $id)
    {
        $data = PaymentContribution::find($id);

        DB::connection()->beginTransaction();

        try {
                $loan_paused_history = PaymentContributionHistory::create([
                    'employee_pc_id' => $data->id,
                    'date_pause' => $request->formType == 'pause' ? date('Y-m-d H:i:s') : null,
                    'date_resume' => $request->formType != 'pause' ? date('Y-m-d H:i:s') : null
                ]);

            DB::connection()->commit();

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }

        try {
            $data->paused = $request->formType == 'pause' ? 1 : 0;
            $data->resume_date = $request->formType == 'pause' ? $request->resume_date : null;

            $data->save();

            DB::connection()->commit();

            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $data
            ],201);

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    public function destroy(int $id)
    {
        $data = PaymentContribution::find($id);

        DB::connection()->beginTransaction();

        $data->delete();

        DB::connection()->commit();

        return response()->json(['message' => "Record successfully deleted!"],201);
    }
}
