<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

abstract class BaseMasterController extends Controller
{
    protected string $modelClass;
    protected string $title;
    protected string $routeName;

    public function index(Request $request): View
    {
        $query = $this->modelClass::query();

        if ($request->filled('q')) {
            $q = $request->string('q')->toString();
            $query->where(function ($inner) use ($q) {
                $inner->where('name', 'like', "%{$q}%")
                    ->orWhere('code', 'like', "%{$q}%");
            });
        }

        $items = $query->latest('id')->paginate(20)->withQueryString();
        $editItem = $request->filled('edit') ? $this->modelClass::find($request->integer('edit')) : null;

        return view('admin.masters.index', compact('items', 'editItem') + [
            'title' => $this->title,
            'routeName' => $this->routeName,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $data = $this->validatedData($request);
        $this->modelClass::create($data);

        return redirect()->route($this->routeName)->with('success', rtrim($this->title, 's') . ' created successfully.');
    }

    public function edit(int $id): RedirectResponse
    {
        return redirect()->route($this->routeName, ['edit' => $id]);
    }

    public function update(Request $request, int $id): RedirectResponse
    {
        $item = $this->modelClass::findOrFail($id);
        $item->update($this->validatedData($request, $id));

        return redirect()->route($this->routeName)->with('success', rtrim($this->title, 's') . ' updated successfully.');
    }

    public function destroy(int $id): RedirectResponse
    {
        $item = $this->modelClass::findOrFail($id);
        $item->delete();

        return redirect()->route($this->routeName)->with('success', rtrim($this->title, 's') . ' deleted successfully.');
    }

    protected function validatedData(Request $request, ?int $id = null): array
    {
        $table = (new $this->modelClass)->getTable();
        $data = $request->validate([
            'name' => ['required', 'string', 'max:150', Rule::unique($table, 'name')->ignore($id)],
            'code' => ['nullable', 'string', 'max:50', Rule::unique($table, 'code')->ignore($id)],
            'status' => ['required', 'in:Active,Inactive'],
        ]);

        if (blank($data['code'] ?? null)) {
            $data['code'] = strtoupper(substr(preg_replace('/[^A-Za-z0-9]/', '', $data['name']), 0, 3)) . '-' . random_int(100, 999);
        }

        return $data;
    }
}
