<?php

namespace App\Services;

use App\Repositories\StatusTicketRepo;

class StatusTicketService
{
  private StatusTicketRepo $statusTicketRepo;

  public function __construct()
  {
    $this->statusTicketRepo = new StatusTicketRepo();
  }

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

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

  public function init()
  {
    if (count($this->statusTicketRepo->findAll()) > 0) {
      return;
    }

    $statuses = [
      ['OPEN',        1, 'Tiket baru dibuat dan menunggu penugasan.'],
      ['ASSIGNED',    2, 'Tiket telah ditugaskan kepada teknisi.'],
      ['IN PROGRESS', 3, 'Teknisi sedang mengerjakan tiket.'],
      ['ESCALATED',   4, 'Tiket dieskalasikan ke teknisi atau level penanganan yang lebih tinggi.'],
      ['SOLVED',      5, 'Permasalahan telah berhasil diselesaikan dan menunggu konfirmasi penutupan.'],
      ['CANCELED',    6, 'Tiket dibatalkan sehingga proses penanganan dihentikan.'],
    ];

    foreach ($statuses as $status) {
      $this->statusTicketRepo->save(
        $status[0],
        $status[1],
        $status[2]
      );
    }
  }

  public function update(
    int $id,
    string $namaStatus,
    int $urutan,
    ?string $deskripsi = null
  ) {
    $status = $this->statusTicketRepo->findById($id);

    if (empty($status)) {
      throw new \Exception('Status tiket tidak ditemukan.');
    }

    $this->isValid(
      $namaStatus,
      $urutan,
      $id
    );

    return $this->statusTicketRepo->update(
      $id,
      $namaStatus,
      $urutan,
      $deskripsi
    );
  }

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

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

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

    $errors = [];

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

    if ($urutan <= 0) {
      $errors['urutan'] = 'Urutan harus lebih dari 0.';
    }

    $status = $this->statusTicketRepo->findByNamaStatus($namaStatus);

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

    return $errors;
  }

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

    $errors = $this->validate(
      $namaStatus,
      $urutan,
      $id
    );

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

  public function getAvailableStatus(string $currentStatus)
  {
    $allowedStatus = $this->getAvailableStatuses($currentStatus);

    return $this->statusTicketRepo->findByNames($allowedStatus);
  }

  public function findByName(string $name)
  {
    return $this->statusTicketRepo->findByNamaStatus($name);
  }

  function getAvailableStatuses(string $currentStatus): array
  {
    return match ($currentStatus) {
      'OPEN' => ['CANCELED'],
      'ASSIGNED' => ['IN PROGRESS', 'CANCELED'],
      'IN PROGRESS' => ['SOLVED', 'CANCELED'],
      'ESCALATED' => ['IN PROGRESS', 'SOLVED', 'CANCELED'],
      default => []
    };
  }
}
