<?php

namespace App\Processors\Equipment;

use App\Entities\Equipment\ServerEntity;
use App\Services\Customer\ServiceService;
use App\Services\Equipment\ServerPartService;
use App\Services\Equipment\ServerService;
use App\Services\MyLogService;
use App\Services\Part\IPService;
use App\Services\Part\SWITCHService;
use CodeIgniter\Database\BaseConnection;
use RuntimeException;

class ServerV1Processor
{
  public function __construct(
    private BaseConnection $db,
    private ServerService $service,
    private ServiceService $serviceService,
    private ServerPartService $serverPartService,
    private IPService $ipService,
    private SWITCHService $switchService,
    private MyLogService $logService,
  ) {}

  public function create(array $formDatas): ServerEntity
  {
    $this->db->transStart();
    //1) 서버정보 생성
    //switch값이 없으면 null처리
    if (!array_key_exists('switch', $formDatas) || !$formDatas['switch']) {
      $formDatas['switch'] = null;
    }
    //switch값이 없으면 null처리
    if (!array_key_exists('ip', $formDatas) || !$this->service->getHelper()->isIPAddress($formDatas['ip'])) {
      $formDatas['ip'] = null;
    }
    $entity = $this->service->getModel()->create($formDatas);
    //2) 서버의 Type별 서버파트정보등록(서버파트연결 자동등록용)
    $this->serverPartService->attachToServer($entity);
    //3) Switch가 정의되어 있으면
    if ($entity->getSwitch()) {
      $this->switchService->attachToServer($entity);
    }
    //4) //IP가 정의되어 있으면
    if ($entity->getIP()) {
      $this->ipService->attachToServer($entity);
    }
    //5) Log처리
    $this->logService->create([
      'title' => "[{$entity->getTitle()}] 서버 추가",
      'status' => $entity->getStatus()
    ]);
    $this->db->transComplete();
    if ($this->db->transStatus() === false) {
      throw new RuntimeException('트랜잭션 실패');
    }
    return $entity;
  }
  public function modify(ServerEntity $entity, array $formDatas): ServerEntity
  {
    $this->db->transStart();
    //1) 사전처리 작업
    //Switch값이 정의되어 있으면
    $isChangedSwitch = false;
    if ($entity->getSwitch() != $formDatas['switch']) {
      //기존 Switch값과 다르고 기존 Switch값이 있으면 해지
      if ($entity->getSwitch()) {
        $this->switchService->detachFromServer($entity);
      }
      $isChangedSwitch = true;
    }
    //IP값이 정의되어 있으면
    $isChangedIP = false;
    //기존 IP값과 다르면
    if ($entity->getIP() != $formDatas['ip']) {
      //기존IP값과 다르고 기존 Switch값이 있으면 해지
      if ($entity->getIP()) {
        $this->ipService->detachFromServer($entity);
      }
      $isChangedIP = true;
    }
    //2) 서버정보 수정
    $entity = $this->service->getModel()->modify($entity, $formDatas);
    //3) Switch값이 있고 신규값인경우
    if ($entity->getSwitch() && $isChangedSwitch) {
      $this->switchService->attachToServer($entity);
    }
    //3) IP값이 있고 신규값인경우
    if ($entity->getIP() && $isChangedIP) {
      $this->ipService->attachToServer($entity);
    }
    //4) 서비스금액 설정:서비스가 연결되어 있고 대체서버가 아니면, 과금정의
    if ($entity->getServiceInfoUID() !== null && $entity->getType() !== SERVER['TYPES']['ALTERNATIVE']) {
      $this->service->setAmount($entity);
    }
    //5) Log처리
    $this->logService->create([
      'title' => "[{$entity->getTitle()}] 서버 정보변경",
      'status' => $entity->getStatus()
    ]);
    $this->db->transComplete();
    if ($this->db->transStatus() === false) {
      throw new RuntimeException('트랜잭션 실패');
    }
    return $entity;
  }

  public function delete(ServerEntity $entity): ServerEntity
  {
    //서비스가 연결되어있거나 , 사용가능 상태가 아니면 삭제불가
    if ($entity->getServiceInfoUID() !== null || $entity->getStatus() !== STATUS['AVAILABLE']) {
      throw new \Exception("서비스중인 서버는 삭제하실수 없습니다.");
    }
    $this->db->transStart();
    // 1) 기존 Switch값이 있으면 해지
    if ($entity->getSwitch()) {
      $this->switchService->detachFromServer($entity);
    }
    // 2) 기존 IP값이 있으면 해지
    if ($entity->getIP()) {
      $this->ipService->detachFromServer($entity);
    }
    // 3) 서버파트 정보 해지
    $this->serverPartService->detachFromServer($entity);
    // 4) 서버정보 삭제()
    $this->service->getModel()->delete($entity->getPK());
    // dd($entity);
    // 5) 로그
    $this->logService->create(formDatas: [
      'title'  => "{$entity->getTitle()} 서버 삭제",
      'status' => $entity->getStatus(),
    ]);
    $this->db->transComplete();
    if ($this->db->transStatus() === false) {
      throw new RuntimeException('트랜잭션 실패');
    }
    return $entity;
  }
}
