<?php

namespace App\Http\Controllers\API\v1;
use App\Http\Controllers\Controller;

use App\Models\AdjustmentsAndDeductions;
use App\Models\Employee;
use App\Models\EmployeeBenefits;
use App\Models\Role;
use App\Models\RoleCompanyAccess;
use App\Models\RolePermission;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Throwable;

class AdjustmentsAndDeductionsController extends Controller
{
    public function index(Request $request)
    {
        $user = Auth::user();
        $keyword = $request->input('keyword', null);
        $perPage = $request->input('per_page', 10);
        $page = $request->input('page', 1);
        $sortBy = $request->input('sortBy', 'created_at');
        $sortType = $request->input('sortType', 'desc');
        $tag = $request->input('tag', null);
        
        $dealers = RoleCompanyAccess::where('role_id', $user->roles[0]->id)->pluck('dealership_id')->toArray();
        
        $data = AdjustmentsAndDeductions::query()
            ->with(['employee:employee_id,firstname,lastname', 'payroll_item:id,name,add_less,tag'])
            ->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}%")));
                }
            })
            ->when($tag, function($when) use ($tag) {
                return $when->when($tag == 'adjustment', function($q) {
                    return $q->whereHas('payroll_item', function($q2) {
                        return $q2->whereNull('tag')
                            ->orWhere('tag', 1);
                    })->whereHas('payroll_item', function($q2) {
                        return $q2->where(function($q3) {
                            $q3->whereNull('add_less')
                                ->orWhere('add_less', '')
                                ->orWhere('add_less', 1);
                        });
                    });
                })->when($tag == 'deduction', function($q) use ($tag) {
                    return $q->whereHas('payroll_item', fn($q2) => $q2->where('tag', $tag));
                });
            })
            // Add default filter for adjustments (based on your frontend filter)
            ->when(is_null($tag), function($q) {
                return $q->whereHas('payroll_item', function($q2) {
                    return $q2->whereNull('tag')
                        ->where(function($q3) {
                            $q3->whereNull('add_less')
                                ->orWhere('add_less', '')
                                ->orWhere('add_less', 1);
                        });
                });
            })
            ->whereHas('payroll_item', fn($q) => $q->whereNull('deleted_at'));
        
        // Handling sorting
        if ($sortBy === 'fullname') {
            // Use a subquery approach to avoid JOIN duplication issues
            $data = $data->orderBy(
                \DB::raw("(SELECT CONCAT(lastname, ' ', firstname) FROM employees WHERE employees.employee_id = adjustments_and_deductions.employee_id LIMIT 1)"),
                $sortType
            );
        } else {
            $data = $data->orderBy($sortBy, $sortType);
        }
        
        // Apply pagination
        $paginated = $data->paginate($perPage, ['*'], 'page', $page);
        
        return response()->json([
            'data' => $paginated->items(),
            'total' => $paginated->total(),
            'per_page' => $paginated->perPage(),
            'current_page' => $paginated->currentPage(),
            'last_page' => $paginated->lastPage(),
        ], 200);
    }

    public function store(Request $request)
    {

        $recurring = ($request->recurring && $request->recurring !== 'null' && $request->recurring !== 'false' && trim($request->recurring) !== '' ? 1 : 0);

        $request['recurring'] = $recurring;

        // Validate the incoming request data
        $validator = Validator::make($request->all(), [
            'employee_id' => [
                'required',
            ],
            'payroll_item_id' => [
                'required',
            ],
            'date_from' => [
                'required',
            ],
            'amount' => [
                'required',
            ],
            'frequency' => [
                '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 {

            foreach ($request->employee_id as $employee) {
                $employee_info = Employee::select('company_id', 'dealer_id')->where('employee_id', $employee)->first();

                $request['company_id'] = $employee_info->company_id;
                $request['dealer_id'] = $employee_info->dealer_id;

                $request['employee_id'] = $employee;

                $data = AdjustmentsAndDeductions::create($request->all());

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

            // $data = AdjustmentsAndDeductions::create($request->all());

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

            return response()->json([
                'message' => 'Record Successfully added!',
                'status' => 'success',
            ],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 update(Request $request, int $id)
    {
        $data = AdjustmentsAndDeductions::where('id', $id)->first();

        if (!$data) {
            return response()->json(['messages' => 'No data found.'], 404);
        }

        $recurring = ($request->recurring && $request->recurring !== 'null' && $request->recurring !== 'false' && trim($request->recurring) !== '' ? 1 : 0);

        $request['recurring'] = $recurring;

        $validator = Validator::make($request->all(),
            [
                'employee_id' => [
                    'required',
                ],
                'payroll_item_id' => [
                    'required',
                ],
                'date_from' => [
                    'required',
                ],
                'amount' => [
                    'required',
                ],
                'frequency' => [
                    '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->fill($request->all());
            $data->save();

            $data->touch();

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

            return response()->json([
                'message' => 'Record Successfully updated!',
                'status' => 'success',
                '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 = AdjustmentsAndDeductions::find($id);
        if(!$data)
        {
            return response()->json(['message' => "Record not found!"],204);
        }
        DB::connection()->beginTransaction();
        $data->delete();
        DB::connection()->commit();
        return response()->json(['message' => "Record successfully deleted!"],201);
    }

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

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


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

            $data->save();
            $data->touch();

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

            return response()->json([
                'status'  => true,
                'message' => 'Record updated 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()
            ]);
        }
    }
}
