<?php

require_once dirname(__DIR__) . '/models/Asset.php';
require_once dirname(__DIR__) . '/models/Maintenance.php';
require_once dirname(__DIR__) . '/models/Helpdesk.php';
require_once dirname(__DIR__) . '/models/SlaIncident.php';
require_once dirname(__DIR__) . '/models/Survey.php';

class Kpi {
    private $conn;
    private $asset;
    private $maintenance;
    private $helpdesk;
    private $slaIncident;
    private $survey; // Explicitly declare the property

    public function __construct($db) {
        $this->conn = $db;
        $this->asset = new Asset($this->conn);
        $this->maintenance = new Maintenance($this->conn);
        $this->helpdesk = new Helpdesk($this->conn);
        $this->slaIncident = new SlaIncident($this->conn);
        $this->survey = new Survey($this->conn);
    }

    // 1. Kerusakan Device <5% (Dari Total Keseluruhan Device)
    public function calculateDeviceDamagePercentage() {
        $totalAssets = $this->asset->getAssetCount();
        $damagedAssets = $this->asset->getAssetCountByStatus('Rusak');
        
        if ($totalAssets == 0) {
            return 0; // Avoid division by zero
        }
        
        return ($damagedAssets / $totalAssets) * 100;
    }

    // 2. Biaya Pengadaan Tinta Max Rp. 1.500.000 /bulan
    // This KPI requires actual expenditure tracking. For now, it's a placeholder.
    public function getInkProcurementCost($month, $year) {
        // In a real system, this would query an expenditure table.
        // For now, return a dummy value or require manual input.
        return 0; // Assuming 0 if no tracking system
    }

    // 3. Kepuasan Pelanggan Internal >85%
    public function getCustomerSatisfaction($month, $year) {
        $overall_avg_rating = $this->survey->getAverageRating(null, $month, $year); // Pass month and year
        // Assuming 5 is max rating, convert to percentage
        return ($overall_avg_rating / 5) * 100;
    }

    // 4. Response Time Help Desk <30mnt
    public function getAvgHelpdeskResponseTime($month, $year) {
        $query = "SELECT AVG(TIMESTAMPDIFF(MINUTE, created_at, response_at)) as avg_response_time
                  FROM helpdesk_tickets
                  WHERE response_at IS NOT NULL AND status IN ('In Progress', 'Resolved', 'Closed')
                  AND MONTH(created_at) = :month AND YEAR(created_at) = :year";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":month", $month);
        $stmt->bindParam(":year", $year);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        return $result['avg_response_time'] ?? 0; // Returns average minutes
    }
    
    // 5. Tersosialisasinya perubahan sistem kepada user dalam waktu 1x24jam
    // This KPI requires a communication logging system. Placeholder.
    public function getSystemChangeSocialization() {
        return "Manual"; // Requires manual assessment
    }

    // 6. Preventive Maintenance Hardware 90% /Bulan
    public function calculatePreventiveMaintenancePercentage($month, $year) {
        // Assumption: "Preventive Maintenance" is a type of action.
        // Also, it's unclear what "90% /Bulan" means. 90% of what?
        // Let's assume it means 90% of total assets received *some* maintenance in the month.
        // A more robust KPI would need a definition of 'preventive' action and target assets.

        $totalAssets = $this->asset->getAssetCount();
        if ($totalAssets == 0) {
            return 0;
        }

        $start_date = date("Y-m-01", strtotime("$year-$month-01"));
        $end_date = date("Y-m-t", strtotime("$year-$month-01"));

        $query = "SELECT COUNT(DISTINCT id_aset) as maintained_assets_count
                  FROM maintenance_history
                  WHERE tanggal_maintenance BETWEEN :start_date AND :end_date";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':start_date', $start_date);
        $stmt->bindParam(':end_date', $end_date);
        $stmt->execute();
        $maintainedAssets = $stmt->fetch(PDO::FETCH_ASSOC)['maintained_assets_count'];

        return ($maintainedAssets / $totalAssets) * 100;
    }

    // 7. Penerapan 5R
    // This KPI is qualitative. Placeholder.
    public function get5RImplementation() {
        return "Manual"; // Requires manual assessment
    }

    // 8. Downtime <3 /bln dengan range time <30mnt
    public function calculateDowntimeKPI($month, $year) {
        $start_date = date("Y-m-01", strtotime("$year-$month-01"));
        $end_date = date("Y-m-t", strtotime("$year-$month-01"));

        $query_total = "SELECT COUNT(*) as total_incidents
                        FROM sla_incidents
                        WHERE waktu_mulai BETWEEN :start_date AND :end_date";
        $stmt_total = $this->conn->prepare($query_total);
        $stmt_total->bindParam(':start_date', $start_date);
        $stmt_total->bindParam(':end_date', $end_date);
        $stmt_total->execute();
        $totalIncidents = $stmt_total->fetch(PDO::FETCH_ASSOC)['total_incidents'];

        $query_good = "SELECT COUNT(*) as good_incidents
                       FROM sla_incidents
                       WHERE waktu_mulai BETWEEN :start_date AND :end_date
                         AND durasi_downtime_minutes < 30"; // Downtime less than 30 minutes
        $stmt_good = $this->conn->prepare($query_good);
        $stmt_good->bindParam(':start_date', $start_date);
        $stmt_good->bindParam(':end_date', $end_date);
        $stmt_good->execute();
        $goodIncidents = $stmt_good->fetch(PDO::FETCH_ASSOC)['good_incidents'];

        // KPI is "Downtime <3 /bln with range time <30mnt".
        // This suggests: (1) count of incidents < 3, AND (2) each of those incidents is <30min.
        // Or it means count of incidents with <30min downtime is less than 3.
        // Let's go with: number of incidents with downtime >= 30 minutes should be < 3.
        $incidentsOver30Min = $totalIncidents - $goodIncidents;
        
        return [
            'total_incidents' => $totalIncidents,
            'incidents_under_30_min' => $goodIncidents,
            'incidents_over_30_min' => $incidentsOver30Min,
            'kpi_met' => ($incidentsOver30Min < 3) // Assuming KPI target is less than 3 incidents over 30 min per month
        ];
    }
    
    // 9. Implementasi Lean Management (Kaizen)
    // This KPI is qualitative. Placeholder.
    public function getLeanManagementImplementation() {
        return "Manual"; // Requires manual assessment
    }
}
