<?php

namespace App\Services;

use App\Repositories\PriorityRepo;

class PriorityService
{
  private PriorityRepo $priorityRepo;

  public function __construct()
  {
    $this->priorityRepo = new PriorityRepo();
  }

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

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

  /**
   * Inisialisasi data default prioritas.
   * Hanya akan membuat data yang belum ada.
   */
  public function init(): void
  {
    $priorities = [
      [
        'nama' => 'HIGH',
        'level' => 3,
        'deskripsi' => 'Prioritas tinggi'
      ],
      [
        'nama' => 'MEDIUM',
        'level' => 2,
        'deskripsi' => 'Prioritas sedang'
      ],
      [
        'nama' => 'LOW',
        'level' => 1,
        'deskripsi' => 'Prioritas rendah'
      ]
    ];

    foreach ($priorities as $priority) {

      $exists = $this->priorityRepo->findByNamaPrioritas($priority['nama']);

      if (empty($exists)) {
        $this->priorityRepo->save(
          $priority['nama'],
          $priority['level'],
          $priority['deskripsi']
        );
      }
    }
  }

  public function update(
    int $id,
    string $namaPrioritas,
    int $level,
    ?string $deskripsi = null
  ) {
    $priority = $this->priorityRepo->findById($id);

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

    $this->isValid($namaPrioritas, $level, $id);

    return $this->priorityRepo->update(
      $id,
      $namaPrioritas,
      $level,
      $deskripsi
    );
  }

  private function validate(
    string $namaPrioritas,
    int $level,
    ?int $id = null
  ): array {

    $errors = [];

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

    if ($level < 1) {
      $errors['level'] = 'Level tidak valid.';
    }

    $byName = $this->priorityRepo->findByNamaPrioritas($namaPrioritas);

    if (!empty($byName) && $byName[0]->getId() !== $id) {
      $errors['namaPrioritas'] = 'Nama prioritas sudah ada.';
    }

    $byLevel = $this->priorityRepo->findByLevel($level);

    if (!empty($byLevel) && $byLevel[0]->getId() !== $id) {
      $errors['level'] = 'Level sudah digunakan.';
    }

    return $errors;
  }

  private function isValid(
    string $namaPrioritas,
    int $level,
    ?int $id = null
  ): void {

    $errors = $this->validate(
      $namaPrioritas,
      $level,
      $id
    );

    if (!empty($errors)) {
      throw new \Exception(implode(', ', $errors));
    }
  }
}
