<?php

namespace App\Http\Controllers;

use App\Gates\PageGate;
use App\Repos\CreditRepo;
use App\Repos\PageRepo;
use App\Services\OpenaiService;
use App\Services\ResponseService;
use App\Services\ValidationService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Throwable;

class PageController extends Controller
{
    public function read(int $id)
    {
        try {
            $rules = [
                'id' => ['required', 'exists:pages,id'],
            ];
            ValidationService::validate(compact('id'), $rules);
            $page = PageRepo::read($id);
            return ResponseService::ok($page);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }

    public function create(Request $request)
    {
        try {
            $rules = [
                'prompt' => ['required', 'string'],
            ];
            ValidationService::validate($request->all(), $rules);
            $user = $request->user();
            $prompt = "Black outline line art with white background of $request->prompt";
            $illustration = OpenaiService::createImage($prompt);
            $pageData = [
                'user_id' => $user->id,
                'prompt' => $request->prompt,
                'illustration' => $illustration,
            ];
            $page = PageRepo::create($pageData);
            CreditRepo::decrementByUserId($user->id, 'page_creation');
            return ResponseService::ok($page);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }

    public function paginate(Request $request)
    {
        try {
            $query = $request->query();
            $sorts = [
                'oldest',
                'latest',
                'trending',
                'popularity',
                'mostFavorited',
                'mostColored',
            ];
            $scopes = [
                'public',
                'favorited',
                'owned',
                'colored'
            ];
            $rules = [
                'page' => ['required', 'integer', 'min:1'],
                'search' => ['nullable', 'string'],
                'sort' => ['nullable', Rule::in($sorts)],
                'scope' => ['required', Rule::in($scopes)],
            ];
            ValidationService::validate($query, $rules);
            $result = PageRepo::paginate(
                $request->query('page'),
                $request->query('search'),
                $request->query('sort'),
                $request->query('scope'),
            );
            return ResponseService::ok($result);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }

    public function toggleBlocked(int $id)
    {
        try {
            $rules = [
                'id' => ['required', 'exists:pages,id'],
            ];
            ValidationService::validate(compact('id'), $rules);
            PageRepo::toggleBlockedOrFail($id);
            $result = ['toggled' => true];
            return ResponseService::ok($result);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }

    public function toggleFavorited(Request $request, int $id)
    {
        try {
            $rules = [
                'id' => ['required', 'exists:pages,id'],
            ];
            ValidationService::validate(compact('id'), $rules);
            PageGate::canToggleFavorite();
            $user = $request->user();
            $page = PageRepo::toggleFavoritedOrFail($id, $user->id);
            $page->isFavorited
                ? PageRepo::incrementFavoritedCount($id)
                : PageRepo::decrementFavoritedCount($id);
            $result = ['toggled' => true];
            return ResponseService::ok($result);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }

    public function generatePrompt()
    {
        try {
            $message = 'Write a concise one-sentence that describes a scene for a drawing student to illustrate.';
            $prompt = OpenaiService::chat($message);
            $result = compact('prompt');
            return ResponseService::ok($result);
        } catch (Throwable $error) {
            return ResponseService::handleError($error);
        }
    }
}
