<?php

namespace lib\Services;

use lib\Core\Service as Core;
use lib\Configs\Pagination;

abstract class CommonService extends Core
{
    private $_model = null;
    public function __construct()
    {
        parent::__construct();
    } //
    abstract public function getModelClass(): string;
    abstract public function getEntityClass(): string;
    final public function getModel(): mixed
    {
        if ($this->_model === null) {
            $modelClass = $this->getModelClass();
            $this->_model = new $modelClass();
            // $this->_model->setDebug(true);
        }
        return $this->_model;
    }
    final public function getEntity(): mixed
    {
        $result = $this->getModel()->get();
        if (!$result) { //결과값이 없으면 null
            return $result;
        }
        $entityClass = $this->getEntityClass();
        return new $entityClass($result);
    }
    final public function getEntities(): array
    {
        $entitys = [];
        foreach ($this->getModel()->getAll() as $result) {
            $entityClass = $this->getEntityClass();
            $entity = new $entityClass($result);
            $pairField = $this->getModel()->getPairField();
            // echo "pairField:" . $pairField . "<BR>";
            $entitys[$entity->$pairField] = $entity;
        }
        return $entitys;
    } // 
    final public function getCount(string $select = "COUNT(*) as cnt", string $column = 'cnt'): int
    {
        return $this->getModel()->count($select, $column);
    }
    final public function getList($curPage = null, $perPage = null): array
    {
        $total = $this->getCount();
        $curPage = $curPage ?? 1;
        $perPage = $perPage ?? APP_VIEW_LIST_PERPAGE;
        $curPage = (int)$curPage;
        $perPage = (int)$perPage;
        $curPage = intval($curPage > 0 ? $curPage : 1);
        $perPage = intval($perPage > 0 ? $perPage : APP_VIEW_LIST_PERPAGE);
        //limit, offset 설정
        $this->getModel()->limit($perPage);
        $this->getModel()->offset(($curPage - 1) * $perPage);
        $entities         = $this->getEntities();
        $pagination = new Pagination($total, $curPage, $perPage);
        return [$total, $entities, $pagination, $curPage, $perPage];
    }

    protected function insert(array $formData): mixed
    {
        $insertId = $this->getModel()->insert($formData);
        if (!$insertId) {
            throw new \Exception("Insert Error : " . $this->getModel()->getLastError());
        }
        $entityClass = $this->getEntityClass();
        $entity = new $entityClass($formData);
        $pkField = $this->getModel()::PKFIELD;
        $entity->$pkField = $insertId;
        return $entity;
    } //

    //transaction관련련
    final public function beginTransaction(): void
    {
        $this->getModel()->beginTransaction();
    }
    final public function commit(): void
    {
        $this->getModel()->commit();
    }
    final public function rollBack(): void
    {
        $this->getModel()->rollBack();
    }
} //Class
