<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Requests\Blog\FaqRequest;
use App\Http\Resources\FaqResource;
use App\Models\Faq;
use App\Support\ApiResponse;
use App\Support\MorphTypeResolver;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use InvalidArgumentException;

class FaqController extends Controller
{
  public function index(Request $request)
  {
    Gate::authorize('viewAny', Faq::class);

    try {
      $query = Faq::query()->reorder()->orderBy('order')->orderBy('id');

      if ($request->filled('model_type')) {
        $query->where('model_type', MorphTypeResolver::resolve($request->string('model_type')));
      }

      if ($request->filled('model_id')) {
        $query->where('model_id', $request->integer('model_id'));
      }

      if (! $request->user()?->hasRole('admin')) {
        $query->where('status', Faq::STATUS_APPROVED);
      } elseif ($request->filled('status')) {
        $query->where('status', $request->string('status'));
      }

      $perPage = min($request->integer('per_page', 50), 100);

      return FaqResource::collection(
        $request->boolean('noPaginate') ? $query->get() : $query->paginate($perPage)
      );
    } catch (InvalidArgumentException $exception) {
      return ApiResponse::response(message: $exception->getMessage(), status: 422);
    }
  }

  public function store(FaqRequest $request)
  {
    Gate::authorize('create', Faq::class);

    try {
      DB::beginTransaction();

      $data = $request->validated();
      $data['model_type'] = MorphTypeResolver::resolve($data['model_type']);
      $data['created_by'] = Auth::id();
      $data['status'] = $data['status'] ?? Faq::STATUS_APPROVED;

      $faq = Faq::create($data);

      DB::commit();
    } catch (InvalidArgumentException $exception) {
      return ApiResponse::response(message: $exception->getMessage(), status: 422);
    } catch (Exception $exception) {
      DB::rollBack();

      return ApiResponse::response(message: $exception->getMessage(), status: 419);
    }

    return ApiResponse::created(new FaqResource($faq), 'سوال متداول با موفقیت ثبت شد.');
  }

  public function show(Faq $faq)
  {
    Gate::authorize('view', $faq);

    return new FaqResource($faq);
  }

  public function update(FaqRequest $request, Faq $faq)
  {
    Gate::authorize('update', $faq);

    try {
      DB::beginTransaction();

      $data = $request->validated();

      if (isset($data['model_type'])) {
        $data['model_type'] = MorphTypeResolver::resolve($data['model_type']);
      }

      $data['updated_by'] = Auth::id();
      $faq->update($data);

      DB::commit();
    } catch (InvalidArgumentException $exception) {
      return ApiResponse::response(message: $exception->getMessage(), status: 422);
    } catch (Exception $exception) {
      DB::rollBack();

      return ApiResponse::response(message: $exception->getMessage(), status: 419);
    }

    return new FaqResource($faq->fresh());
  }

  public function destroy(Faq $faq)
  {
    Gate::authorize('delete', $faq);

    try {
      DB::beginTransaction();
      $faq->delete();
      DB::commit();
    } catch (Exception $exception) {
      DB::rollBack();

      return ApiResponse::response(message: $exception->getMessage(), status: 419);
    }

    return ApiResponse::success(message: 'با موفقیت حذف شد');
  }
}
