<?php

namespace App\Http\Controllers\Plans;

use App\Http\Controllers\Controller;
use App\Http\Requests\PlansRequest;
use App\Traits\Basics\HandlesJsonExceptions;
use App\Traits\Basics\HasCrudActions;
use App\Traits\Basics\Yajra\Plans\PlansTable;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\Plan;
use Illuminate\View\View;
use Exception;
use Throwable;

class PlansController extends Controller
{
    use PlansTable;
    use HasCrudActions, HandlesJsonExceptions;

    /** ==============* Properties *============== */
    protected string $model = Plan::class;
    protected string $viewPath = 'plans.';

    /** ==============* Index & View *============== */
    public function index(): View
    {
        return view("{$this->viewPath}.index");
    }

    /** ==============* Statics *============== */
    public function statics(): JsonResponse
    {
        try {
            $stats = [
                'total' => $this->model::count(),
                'active' => $this->model::where('is_active', true)->count(),
                'inactive' => $this->model::where('is_active', false)->count(),
                'new_today' => $this->model::whereDate('created_at', today())->count(),
            ];

            return response()->json([
                'success' => true,
                'stats' => $stats,
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /** ==============* create & Store *============== */
    public function store(PlansRequest $request): ?JsonResponse
    {
        $lock = acquire_lock("{$this->model}_lock");

        if ($lock instanceof JsonResponse) {
            return $lock;
        }

        try {
            DB::beginTransaction();

            $data = $request->except(['_token', '_method']);
            $data["created_by"] = Auth::id();
            $isSessions = $data["type"] === 'sessions';

            if ($isSessions) {
                $data["sessions_count"] = null;
            }

            $this->model::create($data);

            DB::commit();

            return response()->json(["success" => __("messages.success_creating_item")]);
        } catch (Exception $e) {
            DB::rollBack();
            return response()->json(['error' => $e->getMessage()]);
        } finally {
            optional($lock)->release();
        }
    }

    public function edit(string $id): ?JsonResponse
    {
        try {
            $id = decrypt($id);
            $item = $this->model::query()->where('id', $id)->first();

            if (!$item) {
                return response()->json([
                    'error'   => true,
                    'message' => __('messages.not_found')
                ], 404);
            }

            return response()->json($item);

        } catch (Throwable $e) {
            return response()->json([
                'error'   => true,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    public function update(PlansRequest $request): ?JsonResponse
    {
        try {
            DB::beginTransaction();

            $data = $request->except(['_token', '_method']);
            $id = $data['id'];

            $item = $this->model::query()->find($id);

            if ($item === null) {
                return response()->json([
                    'error'   => true,
                    'message' => __('messages.not_found')
                ]);
            }

            $isSessions = $data["type"] === 'sessions';

            if ($isSessions) {
                $data["sessions_count"] = null;
            }

            $item->update($data);

            DB::commit();

            return response()->json([
                "success" => true,
                "message" => __("messages.success_updating_item")
            ]);
        } catch (Exception $e) {
            DB::rollBack();

            return response()->json([
                'error'   => true,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /** ==============* Common Actions: Update Status & Destroy *============== */
    public function updateStatus(Request $request, int $id): ?JsonResponse
    {
        return $this->updateStatusCommon($request, $this->model, $id, 'is_active');
    }
    public function updateStatusSelector(Request $request): ?JsonResponse
    {
        return $this->updateStatusSelectorCommon($request, $this->model, 'is_active');
    }

    public function destroy(int $id): ?JsonResponse
    {
        $item = $this->model::findOrFail($id);
        return $this->destroyCommon($item);
    }
    public function destroySelector(Request $request): ?JsonResponse
    {
        return $this->destroySelectorCommon($request, $this->model);
    }

}
