<?php

namespace App\Controllers;

use App\Entities\CommonEntity;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\ResponseInterface;
use RuntimeException;

/**
 * AbstractCRUDController
 * 단일 레코드 생성(C), 조회(R), 수정(U), 삭제(D) 로직을 담당합니다. (SRP: Single Record Management)
 */
abstract class AbstractCRUDController extends AbstractWebController
{
  // 💡 핵심 1: 각 자식 클래스가 사용할 Entity 클래스 경로를 반환하도록 강제
  // 이 메서드는 자식 클래스에서 반드시 구현되어야 합니다.
  // --- 생성 (Create) ---
  protected function create_form_process(array $formDatas = []): array
  {
    //초기 기본 Default값 지정
    $formDatas = $this->request->getVar();
    return $formDatas;
  }

  protected function create_form_result_process(string $action): string|RedirectResponse
  {
    return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate'));
  }

  public function create_form(): string|RedirectResponse
  {
    try {
      $action = __FUNCTION__;
      $formDatas = $this->create_form_process();
      $this->action_init_process($action, $formDatas);
      $this->addViewDatas('formDatas', $formDatas);
      return $this->create_form_result_process($action);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 생성폼 오류:" . $e->getMessage());
    }
  }
  protected function create_process(array $formDatas): CommonEntity
  {
    return $this->service->create($formDatas);
  }

  protected function create_result_process($entity, ?string $redirect_url = null): string|RedirectResponse
  {
    return $this->action_redirect_process(
      'info',
      "{$this->getTitle()}에서 {$entity->getTitle()} 생성이 완료되었습니다.",
      $redirect_url ?? '/' . implode('/', [...$this->getActionPaths(), 'view']) . '/' . $entity->getPK()
    );
  }

  public function create(): string|RedirectResponse|ResponseInterface
  {
    try {
      $action = __FUNCTION__;
      $this->action_init_process($action);
      $entity = $this->create_process($this->request->getPost());
      // 💡 동적으로 가져온 Entity 클래스 이름으로 instanceof 검사
      $entityClass = $this->service->getEntityClass();
      if (!$entity instanceof $entityClass) {
        throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생:Return Type은 {$entityClass}만 가능");
      }
      return $this->create_result_process($entity);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 생성 오류:" . $e->getMessage());
    }
  }

  // --- 수정 (Modify) ---
  protected function modify_form_process($uid): CommonEntity
  {
    return $this->service->getEntity($uid);
  }

  protected function modify_form_result_process(string $action): string|RedirectResponse
  {
    return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate'));
  }

  public function modify_form($uid): string|RedirectResponse
  {
    try {
      if (!$uid) {
        throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()}에 번호가 정의 되지 않았습니다.");
      }
      $entity = $this->modify_form_process($uid);
      $this->addViewDatas('entity', $entity);
      $action = __FUNCTION__;
      //FormService에서 필요한 기존 데이터를 $entity에서 추출해서 넘김
      $this->action_init_process($action, $entity->toArray());
      return $this->modify_form_result_process($action);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 수정폼 오류:" . $e->getMessage());
    }
  }

  protected function modify_process($uid, array $formDatas): CommonEntity
  {
    return $this->service->modify($uid, $formDatas);
  }

  protected function modify_result_process($entity, ?string $redirect_url = null): string|RedirectResponse
  {
    return $this->action_redirect_process(
      'info',
      "{$this->getTitle()}에서 {$entity->getTitle()} 수정이 완료되었습니다.",
      $redirect_url ?? '/' . implode('/', [...$this->getActionPaths(), 'view']) . '/' . $entity->getPK()
    );
  }
  public function modify($uid): string|RedirectResponse|ResponseInterface
  {
    try {
      if (!$uid) {
        throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()}에 번호가 정의 되지 않았습니다.");
      }
      $action = __FUNCTION__;
      $this->action_init_process($action);
      $entity = $this->modify_process($uid, $this->request->getPost());
      $this->addViewDatas('entity', $entity);
      return $this->modify_result_process($entity);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 수정 오류:" . $e->getMessage());
    }
  }

  // --- 삭제 (Delete) ---
  protected function delete_process($uid): CommonEntity
  {
    return $this->service->delete($uid);
  }
  protected function delete_result_process($entity, ?string $redirect_url = null): string|RedirectResponse
  {
    return $this->action_redirect_process('info', "{$this->getTitle()}에서 {$entity->getTitle()} 삭제가 완료되었습니다.", $redirect_url);
  }
  public function delete($uid): RedirectResponse
  {
    try {
      if (!$uid) {
        throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()}에 번호가 정의 되지 않았습니다.");
      }
      $entity = $this->service->getEntity($uid);
      //Delete처리
      $entity = $this->delete_process($uid);
      return $this->delete_result_process($entity);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 삭제 오류:" . $e->getMessage());
    }
  }

  // --- 상세보기 (View) ---
  protected function view_process($uid): CommonEntity
  {
    return $this->service->getEntity($uid);
  }
  protected function view_result_process(string $action): string
  {
    return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate'));
  }
  public function view($uid): string|RedirectResponse
  {
    try {
      if (!$uid) {
        throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()}에 번호가 정의 되지 않았습니다.");
      }
      //View처리
      $entity = $this->view_process($uid);
      $action = __FUNCTION__;
      //FormService에서 필요한 기존 데이터를 $entity에서 추출해서 넘김
      $this->action_init_process($action, $entity->toArray());
      $this->addViewDatas('entity', $entity);
      return $this->view_result_process($action);
    } catch (\Throwable $e) {
      return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 상세보기 오류:" . $e->getMessage());
    }
  }
}
