<?php

namespace App\Services;

use App\Repositories\TeknisiRepo;

class TeknisiService
{
  private TeknisiRepo $teknisiRepo;

  public function __construct()
  {
    $this->teknisiRepo = new TeknisiRepo();
  }

  public function findAll()
  {
    return $this->teknisiRepo->findAll();
  }

  public function findAktif()
  {
    return $this->teknisiRepo->findAktif();
  }

  public function findById(int $id)
  {
    return $this->teknisiRepo->findById($id);
  }

  public function save(
    int $userId,
    ?string $spesialisasi,
    string $statusAktif
  ) {
    $this->isValid(
      $userId,
      $spesialisasi,
      $statusAktif
    );

    return $this->teknisiRepo->save(
      $userId,
      $spesialisasi,
      $statusAktif
    );
  }

  public function update(
    int $id,
    ?string $spesialisasi,
    string $statusAktif
  ) {
    $teknisi = $this->teknisiRepo->findById($id);

    if (empty($teknisi)) {
      throw new \Exception('Teknisi tidak ditemukan.');
    }

    $this->isValid(
      $teknisi->getUserId(),
      $spesialisasi,
      $statusAktif,
      $id
    );

    return $this->teknisiRepo->update(
      $id,
      $spesialisasi,
      $statusAktif
    );
  }

  public function delete(int $id)
  {
    return $this->teknisiRepo->delete($id);
  }

  // ===========================
  // Validation
  // ===========================

  private function validate(
    int $userId,
    ?string $spesialisasi,
    string $statusAktif,
    ?int $id = null
  ): array {

    $errors = [];

    if ($userId <= 0) {
      $errors['userId'] = 'User wajib dipilih.';
    }

    if (!in_array($statusAktif, ['AKTIF', 'CUTI', 'NONAKTIF'])) {
      $errors['statusAktif'] = 'Status teknisi tidak valid.';
    }

    // Satu user hanya boleh menjadi satu teknisi
    $teknisi = $this->teknisiRepo->findByUserId($userId);

    if (
      $teknisi !== null &&
      $teknisi->getId() !== $id
    ) {
      $errors['userId'] = 'User sudah terdaftar sebagai teknisi.';
    }

    return $errors;
  }

  private function isValid(
    int $userId,
    ?string $spesialisasi,
    string $statusAktif,
    ?int $id = null
  ): void {

    $errors = $this->validate(
      $userId,
      $spesialisasi,
      $statusAktif,
      $id
    );

    if (count($errors) > 0) {
      throw new \Exception(implode(', ', $errors));
    }
  }

  // find by user id
  public function findByUserId(int $userId)
  {
    return $this->teknisiRepo->findByUserId($userId);
  }
}
