<?php

namespace App\Services;

use App\Repositories\SlaRepo;

class SlaService
{
  private SlaRepo $slaRepo;

  public function __construct()
  {
    $this->slaRepo = new SlaRepo();
  }

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

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

  public function save(
    string $namaSla,
    int $waktuResponJam,
    int $waktuPenyelesaianJam,
    ?string $deskripsi = null
  ) {
    $this->isValid(
      $namaSla,
      $waktuResponJam,
      $waktuPenyelesaianJam
    );

    return $this->slaRepo->save(
      $namaSla,
      $waktuResponJam,
      $waktuPenyelesaianJam,
      $deskripsi
    );
  }

  public function update(
    int $id,
    string $namaSla,
    int $waktuResponJam,
    int $waktuPenyelesaianJam,
    ?string $deskripsi = null
  ) {
    $sla = $this->slaRepo->findById($id);

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

    $this->isValid(
      $namaSla,
      $waktuResponJam,
      $waktuPenyelesaianJam,
      $id
    );

    return $this->slaRepo->update(
      $id,
      $namaSla,
      $waktuResponJam,
      $waktuPenyelesaianJam,
      $deskripsi
    );
  }

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

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

  private function validate(
    string $namaSla,
    int $waktuResponJam,
    int $waktuPenyelesaianJam,
    ?int $id = null
  ): array {

    $errors = [];

    if (trim($namaSla) === '') {
      $errors['namaSla'] = 'Nama SLA wajib diisi.';
    }

    if ($waktuResponJam <= 0) {
      $errors['waktuResponJam'] = 'Waktu respon harus lebih dari 0 jam.';
    }

    if ($waktuPenyelesaianJam <= 0) {
      $errors['waktuPenyelesaianJam'] = 'Waktu penyelesaian harus lebih dari 0 jam.';
    }

    if ($waktuPenyelesaianJam < $waktuResponJam) {
      $errors['waktuPenyelesaianJam'] =
        'Waktu penyelesaian tidak boleh lebih kecil dari waktu respon.';
    }

    // Nama SLA harus unik
    $sla = $this->slaRepo->findByNamaSla($namaSla);

    if (
      $sla !== null &&
      count($sla) > 0 &&
      $sla[0]->getId() !== $id
    ) {
      $errors['namaSla'] = 'Nama SLA sudah ada.';
    }

    return $errors;
  }

  private function isValid(
    string $namaSla,
    int $waktuResponJam,
    int $waktuPenyelesaianJam,
    ?int $id = null
  ): void {

    $errors = $this->validate(
      $namaSla,
      $waktuResponJam,
      $waktuPenyelesaianJam,
      $id
    );

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