<?php

namespace App\Controllers\Ajax;

use App\Controllers\AbstractCRUDController;
use App\Exceptions\FormValidationException;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

abstract class AjaxController extends AbstractCRUDController
{
    private $_layout = "front";
    protected $layouts = [];
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->addActionPaths($this->_layout);
        $this->layouts = LAYOUTS[$this->_layout];
    }
    protected function action_init_process(string $action, array $formDatas = []): void
    {
        parent::action_init_process($action, $formDatas);
        $this->addViewDatas("layout", $this->layouts);
        $this->addViewDatas("title", $this->getTitle());
        $this->addViewDatas("helper", $this->service->getHelper());
        $this->service->getActionForm()->form_init_process($action, $formDatas);
        $this->addViewDatas("formFields", $this->service->getActionForm()->getFormFields());
        $this->addViewDatas("formRules", $this->service->getActionForm()->getFormRules());
        $this->addViewDatas("formFilters", $this->service->getActionForm()->getFormFilters());
        $this->addViewDatas("formOptions", $this->service->getActionForm()->getFormOptions());
        $this->addViewDatas("index_actionButtons", $this->service->getActionForm()->getActionButtons());
        $this->addViewDatas("index_batchjobFields", $this->service->getActionForm()->getBatchjobFilters());
        $this->addViewDatas("index_batchjobButtons", $this->service->getActionForm()->getBatchjobButtons());
    }

    protected function ok(array $data = [], int $status = 200): ResponseInterface
    {
        return $this->response->setStatusCode($status)->setJSON([
            "ok" => true,
            ...$data,
        ]);
    }

    protected function fail(string $message, int $status = 400, array $extra = []): ResponseInterface
    {
        return $this->response->setStatusCode($status)->setJSON([
            "ok" => false,
            "message" => $message,
            ...$extra,
        ]);
    }

    protected function requireAjax()
    {
        // fetch + X-Requested-With 로 들어오는 경우
        if (!$this->request->isAJAX()) {
            return $this->fail("Invalid request", 400);
        }
        return null;
    }

    protected function handleException(\Throwable $e): ResponseInterface
    {
        if ($e instanceof FormValidationException) {
            // ✅ 필드별 + 전역 메시지
            return $this->fail(
                $e->getMessage() ?: "입력값을 확인해 주세요.",
                422,
                ["errors" => $e->getErrors()]
            );
        }

        log_message("error", "[AJAX] " . $e->getMessage());

        return $this->fail("처리 중 오류가 발생했습니다.", 500);
    }

    public function create(): ResponseInterface
    {
        if (!$this->request->isAJAX()) {
            return $this->response->setStatusCode(400)->setJSON([
                "ok" => false,
                "message" => static::class . "->" . __FUNCTION__ . "에서 오류발생: AJAX요청 형식이 아닙니다."
            ]);
        }
        try {
            $formDatas = $this->request->getPost();
            // log_message("error", "POST=" . json_encode($formDatas, JSON_UNESCAPED_UNICODE));
            $entity = $this->service->create($formDatas);
            return $this->response->setStatusCode(201)->setJSON([
                "ok" => true,
                "message" => "문의가 접수되었습니다.",
                "data" => ["pk" => $entity->getPK()],
            ]);
        } catch (FormValidationException $e) {
            // log_message("error", "CAUGHT FormValidationException: " . print_r($e->getErrors(), true));
            // ✅ 혹시 서비스에서 예외를 감싸버린 경우에도 에러를 최대한 복구
            $errors = service("validation")->getErrors();
            if (!empty($errors)) {
                log_message("error", "FALLBACK validation errors: " . print_r($errors, true));
                return $this->response->setStatusCode(422)->setJSON([
                    "ok" => false,
                    "message" => "입력값을 확인해 주세요.",
                    "errors" => $errors,
                ]);
            }
            return $this->response->setStatusCode(422)->setJSON([
                "ok" => false,
                "message" => "입력값을 확인해 주세요.",
                "errors" => $e->getErrors(),
            ]);
        } catch (\Throwable $e) {
            return $this->response->setStatusCode(500)->setJSON([
                "ok" => false,
                "message" => "처리 중 오류가 발생했습니다.\n" . $e->getMessage(),
            ]);
        }
    }
}
