<?php

    namespace Modules\Lpj\Http\Controllers;

    use App\Http\Controllers\Controller;
    use Exception;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\DB;
    use Illuminate\Support\Facades\Log;
    use Maatwebsite\Excel\Facades\Excel;
    use Modules\Lpj\Exports\NilaiPlafondExport;
    use Modules\Lpj\Http\Requests\NilaiPlafondRequest;
    use Modules\Lpj\Models\NilaiPlafond;

    class NilaiPlafondController extends Controller
    {
        public $user;

        /**
         * Menampilkan halaman daftar Nilai Plafond.
         * Log setiap akses dan sebelum return view.
         */
        public function index()
        {
            Log::info('NilaiPlafondController@index: akses halaman index');
            return \view('lpj::nilai_plafond.index');
        }

        /**
         * Menyimpan data Nilai Plafond baru termasuk field biaya.
         * Gunakan validasi dari NilaiPlafondRequest, log proses, dan bungkus dengan transaksi DB.
         */
        public function store(NilaiPlafondRequest $request)
        {
            Log::info('NilaiPlafondController@store: mulai proses simpan');
            $validate = $request->validated();

            if ($validate) {
                DB::beginTransaction();
                try {
                    $record = NilaiPlafond::create($validate);
                    DB::commit();

                    Log::info('NilaiPlafondController@store: simpan berhasil', ['id' => $record->id]);
                    return \redirect()
                        ->route('basicdata.nilai-plafond.index')
                        ->with('success', 'Nilai Plafond berhasil dibuat');
                } catch (Exception $e) {
                    DB::rollBack();
                    Log::error('NilaiPlafondController@store: simpan gagal', ['error' => $e->getMessage()]);

                    return \redirect()
                        ->route('basicdata.nilai-plafond.create')
                        ->with('error', 'Gagal membuat Nilai Plafond');
                }
            }
        }

        /**
         * Menampilkan form pembuatan Nilai Plafond.
         * Log akses sebelum return view.
         */
        public function create()
        {
            Log::info('NilaiPlafondController@create: akses halaman create');
            return \view('lpj::nilai_plafond.create');
        }

        /**
         * Menampilkan form edit Nilai Plafond berdasarkan ID.
         * Gunakan transaksi untuk pembacaan data dan logging.
         */
        public function edit($id)
        {
            Log::info('NilaiPlafondController@edit: mulai proses edit', ['id' => $id]);

            DB::beginTransaction();
            try {
                $nilaiPlafond = NilaiPlafond::find($id);
                DB::commit();

                Log::info('NilaiPlafondController@edit: data ditemukan', ['id' => $id]);
                return \view('lpj::nilai_plafond.create', compact('nilaiPlafond'));
            } catch (Exception $e) {
                DB::rollBack();
                Log::error('NilaiPlafondController@edit: gagal mengambil data', ['id' => $id, 'error' => $e->getMessage()]);
                return \redirect()
                    ->route('basicdata.nilai-plafond.index')
                    ->with('error', 'Gagal mengambil data Nilai Plafond');
            }
        }

        /**
         * Memperbarui data Nilai Plafond termasuk field biaya.
         * Validasi input, logging, dan gunakan transaksi DB.
         */
        public function update(NilaiPlafondRequest $request, $id)
        {
            Log::info('NilaiPlafondController@update: mulai proses update', ['id' => $id]);
            $validate = $request->validated();

            if ($validate) {
                DB::beginTransaction();
                try {
                    $nilaiPlafond = NilaiPlafond::find($id);
                    if (!$nilaiPlafond) {
                        Log::warning('NilaiPlafondController@update: data tidak ditemukan', ['id' => $id]);
                        DB::rollBack();
                        return \redirect()
                            ->route('basicdata.nilai-plafond.index')
                            ->with('error', 'Data Nilai Plafond tidak ditemukan');
                    }

                    $nilaiPlafond->update($validate);
                    DB::commit();

                    Log::info('NilaiPlafondController@update: update berhasil', ['id' => $id]);
                    return \redirect()
                        ->route('basicdata.nilai-plafond.index')
                        ->with('success', 'Nilai Plafond berhasil diperbarui');
                } catch (Exception $e) {
                    DB::rollBack();
                    Log::error('NilaiPlafondController@update: update gagal', ['id' => $id, 'error' => $e->getMessage()]);

                    return \redirect()
                        ->route('basicdata.nilai-plafond.edit', $id)
                        ->with('error', 'Gagal memperbarui Nilai Plafond');
                }
            }
        }

        /**
         * Menghapus data Nilai Plafond berdasarkan ID.
         * Logging setiap langkah dan gunakan transaksi DB.
         */
        public function destroy($id)
        {
            Log::info('NilaiPlafondController@destroy: mulai proses hapus', ['id' => $id]);
            DB::beginTransaction();
            try {
                $nilaiPlafond = NilaiPlafond::find($id);
                if (!$nilaiPlafond) {
                    DB::rollBack();
                    Log::warning('NilaiPlafondController@destroy: data tidak ditemukan', ['id' => $id]);
                    return \response()->json(['success' => false, 'message' => 'Data Nilai Plafond tidak ditemukan']);
                }

                $nilaiPlafond->delete();
                DB::commit();

                Log::info('NilaiPlafondController@destroy: hapus berhasil', ['id' => $id]);
                return \response()->json(['success' => true, 'message' => 'Nilai Plafond berhasil dihapus']);
            } catch (Exception $e) {
                DB::rollBack();
                Log::error('NilaiPlafondController@destroy: hapus gagal', ['id' => $id, 'error' => $e->getMessage()]);
                return \response()->json(['success' => false, 'message' => 'Gagal menghapus Nilai Plafond']);
            }
        }

        /**
         * Menyediakan data untuk datatables dengan pencarian, sortir, dan paginasi.
         * Logging proses dan gunakan transaksi DB untuk konsistensi pembacaan.
         */
        public function dataForDatatables(Request $request)
        {
            Log::info('NilaiPlafondController@dataForDatatables: mulai proses');

            if (is_null($this->user) || !$this->user->can('nilai_plafond.view')) {
                //abort(403, 'Sorry! You are not allowed to view users.');
            }

            DB::beginTransaction();
            try {
                // Retrieve data from the database
                $query = NilaiPlafond::query();

                // Apply search filter if provided
                if ($request->has('search') && !empty($request->get('search'))) {
                    $search = $request->get('search');
                    $query->where(function ($q) use ($search) {
                        $q->where('code', 'LIKE', "%$search%");
                        $q->orWhere('name', 'LIKE', "%$search%");
                    });
                }

                // Apply sorting if provided
                if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
                    $order  = $request->get('sortOrder');
                    $column = $request->get('sortField');
                    $query->orderBy($column, $order);
                }

                // Get the total count of records
                $totalRecords = $query->count();

                // Apply pagination if provided
                if ($request->has('page') && $request->has('size')) {
                    $page   = $request->get('page');
                    $size   = $request->get('size');
                    $offset = ($page - 1) * $size; // Calculate the offset

                    $query->skip($offset)->take($size);
                }

                // Get the filtered count of records
                $filteredRecords = $query->count();

                // Get the data for the current page
                $data = $query->get();

                // Calculate the page count
                $pageCount = ceil($totalRecords / $request->get('size'));

                // Calculate the current page number
                $currentPage = 0 + 1;

                DB::commit();
                Log::info('NilaiPlafondController@dataForDatatables: proses selesai, mengembalikan data');

                // Return the response data as a JSON object
                return \response()->json([
                    'draw'            => $request->get('draw'),
                    'recordsTotal'    => $totalRecords,
                    'recordsFiltered' => $filteredRecords,
                    'pageCount'       => $pageCount,
                    'page'            => $currentPage,
                    'totalCount'      => $totalRecords,
                    'data'            => $data,
                ]);
            } catch (Exception $e) {
                DB::rollBack();
                Log::error('NilaiPlafondController@dataForDatatables: gagal memproses data', ['error' => $e->getMessage()]);
                return \response()->json([
                    'draw'            => $request->get('draw'),
                    'recordsTotal'    => 0,
                    'recordsFiltered' => 0,
                    'pageCount'       => 0,
                    'page'            => 1,
                    'totalCount'      => 0,
                    'data'            => [],
                ]);
            }
        }

        /**
         * Mengekspor data Nilai Plafond ke Excel.
         * Log akses sebelum proses download.
         */
        public function export()
        {
            Log::info('NilaiPlafondController@export: mulai proses export');
            return Excel::download(new NilaiPlafondExport, 'nilai_plafond.xlsx');
        }
    }
