<?php

namespace App\Helpers;

use App\Repositories\ActivityLogRepository;
use App\Repositories\SlaRepo;
use App\Repositories\TicketRepo;
use DateTime;

class SlaCalculator
{

  private ActivityLogRepository $activityLogRepository;
  private TicketRepo $ticketRepository;
  private SlaRepo $slaRepo;

  public function __construct()
  {

    $this->activityLogRepository = new ActivityLogRepository();
    $this->ticketRepository = new TicketRepo();
    $this->slaRepo = new SlaRepo();
  }

  public static function getSlaStatus(
    string $createdAt,
    string $deadline
  ): array {

    $created = new DateTime($createdAt);
    $deadline = new DateTime($deadline);
    $now = new DateTime();

    $totalSeconds = $deadline->getTimestamp() - $created->getTimestamp();
    $elapsedSeconds = $now->getTimestamp() - $created->getTimestamp();

    // Belum mulai
    $elapsedSeconds = max(0, $elapsedSeconds);

    $percentage = ($elapsedSeconds / $totalSeconds) * 100;
    $percentage = round($percentage);

    if ($percentage <= 50) {
      return [
        'status' => 'Sesuai SLA',
        'color' => 'success',
        'percentage' => $percentage
      ];
    }

    if ($percentage <= 75) {
      return [
        'status' => 'Perlu Perhatian',
        'color' => 'primary',
        'percentage' => $percentage
      ];
    }

    if ($percentage <= 95) {
      return [
        'status' => 'Mendekati Batas SLA',
        'color' => 'warning',
        'percentage' => $percentage
      ];
    }

    return [
      'status' => 'Melewati SLA',
      'color' => 'danger',
      'percentage' => min($percentage, 100)
    ];
  }

  public static function getSlaCompleted(
    string $createdAt,
    string $completionDate,
    int $slaPenyelesaian
  ): int {

    $created = new DateTime($createdAt);
    $completed = new DateTime($completionDate);

    // Selisih dalam detik
    $elapsedSeconds = $completed->getTimestamp() - $created->getTimestamp();

    // Ubah ke menit
    $elapsedMinutes = $elapsedSeconds / 60;

    // SLA (jam -> menit)
    $slaMinutes = $slaPenyelesaian * 60;

    // Persentase sisa SLA
    $resolutionPercent = 100 - (($elapsedMinutes / $slaMinutes) * 100);

    // Batasi 0 - 100
    $resolutionPercent = max(0, min(100, $resolutionPercent));

    return round($resolutionPercent);
  }

  public function getSlaResponse(int $ticketId): array
  {
    $assigned = $this->activityLogRepository->findFirstTimeAssigned($ticketId);

    if (!$assigned) {
      return [
        'color' => 'secondary',
        'status' => 'Belum direspons',
        'responseMinutes' => 0,
        'slaMinutes' => 0,
        'responsePercent' => 0,
      ];
    }

    $ticket = $this->ticketRepository->findById($ticketId);
    $sla = $this->slaRepo->findById($ticket->getSlaId());

    $responseMinutes = (strtotime($assigned['tanggal_aktivitas']) - strtotime($ticket->getTanggalDibuat())) / 60;
    $slaMinutes = $sla->getWaktuResponJam() * 60;

    $responsePercent = round(
      min(100, ($responseMinutes / $slaMinutes) * 100),
      1
    );

    $color = match (true) {
      $responsePercent <= 50 => 'success',
      $responsePercent <= 75 => 'primary',
      $responsePercent <= 95 => 'warning',
      default => 'danger',
    };

    return [
      'color' => $color,
      'status' => $responseMinutes <= $slaMinutes
        ? 'Response berhasil dipenuhi'
        : 'Response SLA terlampaui',
      'responseMinutes' => $responseMinutes,
      'slaMinutes' => $slaMinutes,
      'responsePercent' => $responsePercent,
    ];
  }

  public function getSlaResolution(int $ticketId): array
  {
    $ticket = $this->ticketRepository->findById($ticketId);
    $sla = $this->slaRepo->findById($ticket->getSlaId());
    $createdTime = strtotime($ticket->getTanggalDibuat());

    // Jika tiket sudah selesai gunakan tanggal selesai,
    // jika belum gunakan waktu sekarang
    if ($ticket->isClosed()) {
      $endTime = strtotime($ticket->getTanggalUpdate());
    } else {
      $endTime = time();
    }

    $elapsedMinutes = ($endTime - $createdTime) / 60;
    $slaMinutes = $sla->getWaktuPenyelesaianJam() * 60;
    $remainingMinutes = max(0, $slaMinutes - $elapsedMinutes);

    // Semakin cepat selesai semakin besar
    $resolutionPercent = 100 - (($elapsedMinutes / $slaMinutes) * 100);
    $resolutionPercent = max(0, min(100, $resolutionPercent));
    $resolutionPercent = round($resolutionPercent, 1);

    $color = match (true) {
      $resolutionPercent >= 75 => 'success',
      $resolutionPercent >= 50 => 'primary',
      $resolutionPercent >= 25 => 'warning',
      default => 'danger',
    };

    return [
      'color' => $color,
      'resolutionPercent' => $resolutionPercent,
      'elapsedMinutes' => round($elapsedMinutes),
      'remainingMinutes' => round($remainingMinutes),
      'slaMinutes' => $slaMinutes,
      'remainingText' => $this->formatDuration($remainingMinutes),
      'status' => $remainingMinutes > 0
        ? 'SLA masih terpenuhi'
        : 'Resolution SLA terlampaui'
    ];
  }

  private function formatDuration(float $minutes): string
  {
    $minutes = max(0, (int) round($minutes));

    $days = intdiv($minutes, 1440);
    $minutes %= 1440;

    $hours = intdiv($minutes, 60);
    $minutes %= 60;

    $parts = [];

    if ($days > 0) {
      $parts[] = $days . ' Hari';
    }

    if ($hours > 0) {
      $parts[] = $hours . ' Jam';
    }

    if ($minutes > 0 || empty($parts)) {
      $parts[] = $minutes . ' Menit';
    }

    return implode(' ', $parts);
  }
}
