<?php

namespace App\Http\Controllers;

use {{modelNamespace}}\{{modelName}};
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use \Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Woo\GridView\DataProviders\EloquentDataProvider;

class {{modelName}}Controller extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('permission:{{modelRoute}} view', only: ['index', 'show']),
            new Middleware('permission:{{modelRoute}} create', only: ['create', 'store']),
            new Middleware('permission:{{modelRoute}} edit', only: ['edit', 'update']),
            new Middleware('permission:{{modelRoute}} delete', only: ['destroy']),
        ];
    }

    public function index(Request $request): View
    {
        $query = {{modelName}}::query();

        // tambahkan kolom yang mau dikecualikan di pencarian
        $except = ['created_by', 'updated_by'];

        $columns = collect($query->getModel()->getFillable())->filter(function ($item) use ($except) {
            return !in_array($item, $except);
        })->toArray();

        $selectedColumns = $request->get('col', $columns);

        if ($search = $request->get('search')) {
            $query->where(function ($query) use ($search, $selectedColumns) {
                foreach ($selectedColumns as $column) {
                    $query->orWhere($column, 'like', '%' . $search . '%');
                }
            });
        }
        
        ${{modelVariable}} = $query->paginate(10);

        if ($request->header('HX-Request')) {
            return view('{{modelRoute}}.includes.index-table', compact('{{modelVariable}}'));
        }

        return view('{{modelRoute}}.index', compact('{{modelVariable}}', 'columns', 'selectedColumns'));
    }

    public function create(): View
    {
        ${{modelVariable}} = new {{modelName}}();

        return view('{{modelRoute}}.create', compact('{{modelVariable}}'));
    }

    public function store(Request $request): RedirectResponse
    {
        $validatedData = $request->validate([
            {{validationRules}}
        ]);

        try {
            {{modelName}}::create($validatedData);
        } catch (\Illuminate\Database\QueryException $e) {
            return redirect()->back()
                ->withInput($request->all())
                ->with('error', 'Terjadi kesalahan saat membuat data.');
        }

        return redirect()->route('{{modelRoute}}.index')
            ->with('success', '{{modelTitle}} berhasil dibuat');
    }

    public function show({{modelName}} ${{modelVariable}}): View
    {
        return view('{{modelRoute}}.show', compact('{{modelVariable}}'));
    }

    public function edit({{modelName}} ${{modelVariable}}): View
    {
        return view('{{modelRoute}}.edit', compact('{{modelVariable}}'));
    }

    public function update(Request $request, {{modelName}} ${{modelVariable}}): RedirectResponse
    {
        $validatedData = $request->validate([
            {{validationRules}}
        ]);

        try {
            ${{modelVariable}}->update($validatedData);
        } catch (\Illuminate\Database\QueryException $e) {
            if ($e->getCode() == '23000') {
                return redirect()->back()
                    ->withInput($request->all())
                    ->with('error', 'Data {{modelTitleLower}} ini sudah digunakan dan tidak dapat diperbarui.');
            }
            return redirect()->back()
                ->withInput($request->all())
                ->with('error', 'Terjadi kesalahan saat memperbarui data.');
        }

        return redirect()->route('{{modelRoute}}.index')
            ->with('success', '{{modelTitle}} berhasil diperbarui');
    }

    public function destroy({{modelName}} ${{modelVariable}}): RedirectResponse
    {
        try {
            ${{modelVariable}}->delete();
        } catch (\Illuminate\Database\QueryException $e) {
            if ($e->getCode() == '23000') {
                return redirect()->route('{{modelRoute}}.index')
                    ->with('error', 'Data {{modelTitleLower}} ini sudah digunakan dan tidak dapat dihapus.');
            }
            return redirect()->route('{{modelRoute}}.index')
                ->with('error', 'Terjadi kesalahan saat menghapus data.');
        }

        return redirect()->route('{{modelRoute}}.index')
            ->with('success', '{{modelTitle}} berhasil dihapus');
    }
}