<?php

namespace App\Http\Controllers;

use App\Models\LedgGrp;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Throwable;

class LedgGrpController extends Controller
{
    /* ================= INDEX ================= */

    public function index()
    {
        try {

            $data = LedgGrp::orderBy('Gr_St')
                ->orderBy('Gr_Sr')
                ->get();

            return response()->json([
                'status' => 'success',
                'message' => 'Ledger groups fetched successfully',
                'data' => $data
            ]);

        } catch (Throwable $e) {

            Log::error('Fetch Error: ' . $e->getMessage());

            return response()->json([
                'status' => 'error',
                'message' => 'Unable to fetch ledger groups',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /* ================= SHOW ================= */

    public function show($id)
    {
        $data = LedgGrp::find($id);

        if (!$data) {
            return response()->json([
                'status' => 'error',
                'message' => 'Ledger group not found'
            ], 404);
        }

        return response()->json([
            'status' => 'success',
            'data' => $data
        ]);
    }

    /* ================= STORE ================= */

    public function store(Request $request)
    {
        try {

            $level = $request->input('Gr_St', 1);

            $series = LedgGrp::where('Gr_St', $level)->count() + 1;

            $prefix = str_pad($series, 2, '0', STR_PAD_LEFT);
            $codeFormat = $prefix . '000000';

            $data = [
                'Gr_Nm'  => $request->input('Gr_Nm'),
                'Up_Gr'  => $request->input('Up_Gr', $codeFormat),
                'Gr_St'  => $level,
                'Gr_Sr'  => $series,
                'is_del' => $request->input('is_del', 'N'),
                'Gr_Exp' => $request->input('Gr_Exp', 'N'),
                'Gr_Buk' => $request->input('Gr_Buk', 'N'),
                'Gr_Prt' => $request->input('Gr_Prt', 'N'),
                'Gr_Cd'  => $request->input('Gr_Cd', $codeFormat),
            ];

            if (!$request->has('Gr_Nm') || !$request->has('Gr_St')) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Gr_Nm and Gr_St are required'
                ], 422);
            }

            $ledger = LedgGrp::create($data);

            return response()->json([
                'status' => 'success',
                'message' => 'Ledger group created successfully',
                'data' => $ledger,
                'auto_calculated' => [
                    'Gr_St' => $data['Gr_St'],
                    'Gr_Sr' => $data['Gr_Sr'],
                    'Gr_Cd' => $data['Gr_Cd'],
                    'Up_Gr' => $data['Up_Gr']
                ]
            ], 201);

        } catch (Throwable $e) {

            Log::error('Create Error: ' . $e->getMessage());

            return response()->json([
                'status' => 'error',
                'message' => 'Unable to create ledger group',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /* ================= UPDATE ================= */

    public function update(Request $request, $id)
    {
        try {

            $ledger = LedgGrp::find($id);

            if (!$ledger) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Ledger group not found'
                ], 404);
            }

            $validatedData = $request->validate([
                'Gr_Nm'  => 'sometimes|nullable|string|max:50',
                'Up_Gr'  => 'sometimes|nullable|string|max:8',
                'Gr_Sr'  => 'sometimes|nullable|integer',
                'Gr_St'  => 'sometimes|nullable|integer',
                'is_del' => 'sometimes|nullable|string',
                'Gr_Exp' => 'sometimes|nullable|string|in:Y,N',
                'Gr_Buk' => 'sometimes|nullable|string|in:Y,N',
                'Gr_Prt' => 'sometimes|nullable|string|in:Y,N',
                'Gr_Cd'  => 'sometimes|nullable|string|max:8',
            ]);

            $ledger->update($validatedData);

            return response()->json([
                'status' => 'success',
                'message' => 'Ledger group updated successfully',
                'data' => $ledger
            ]);

        } catch (ValidationException $e) {

            return response()->json([
                'status' => 'error',
                'errors' => $e->errors()
            ], 422);

        } catch (Throwable $e) {

            Log::error('Update Error: ' . $e->getMessage());

            return response()->json([
                'status' => 'error',
                'message' => 'Unable to update ledger group',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /* ================= DELETE ================= */

    public function destroy($id)
    {
        $ledger = LedgGrp::find($id);

        if (!$ledger) {
            return response()->json([
                'status' => 'error',
                'message' => 'Ledger group not found'
            ], 404);
        }

        $ledger->delete();

        return response()->json([
            'status' => 'success',
            'message' => 'Ledger group deleted successfully'
        ]);
    }

        /**
     * GET by Organization
     */
    public function getByOrganization($orgId)
    {
        try {
            $groups = LedgGrp::where('Org_Id', $orgId)
                ->orderBy('Gr_St')
                ->orderBy('Gr_Sr')
                ->get();

            return response()->json([
                'status' => 'success',
                'message' => 'Groups fetched successfully',
                'data' => $groups,
                'count' => $groups->count()
            ]);
        } catch (Throwable $e) {
            Log::error('Get By Organization Error: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Unable to fetch groups',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
