<?php
require_once 'config/database.php';

// class EscalationsController {
//     private $conn;

//     public function __construct() {
//         $database = new Database();
//         $this->conn = $database->getConnection();
//     }

//     public function createEscalation($data) {
//         if (!isset($data['follow_up_id'], $data['reason'], $data['escalated_by'], $data['assigned_to'])) {
//             return json_encode(['status' => 'error', 'message' => 'Missing required fields']);
//         }

//         $query = "INSERT INTO escalations (follow_up_id, reason, escalated_by, assigned_to, status) VALUES (:follow_up_id, :reason, :escalated_by, :assigned_to, 'pending')";
//         $stmt = $this->conn->prepare($query);
//         $stmt->bindParam(':follow_up_id', $data['follow_up_id']);
//         $stmt->bindParam(':reason', $data['reason']);
//         $stmt->bindParam(':escalated_by', $data['escalated_by']);
//         $stmt->bindParam(':assigned_to', $data['assigned_to']);

//         if ($stmt->execute()) {
//             return json_encode(['status' => 'success', 'message' => 'Escalation created']);
//         } else {
//             return json_encode(['status' => 'error', 'message' => 'Error creating escalation']);
//         }
//     }

//     public function getEscalations($filters) {
//         $query = "SELECT * FROM escalations WHERE 1=1";
//         $params = [];
//         if (!empty($filters['status'])) {
//             $query .= " AND status = :status";
//             $params[':status'] = $filters['status'];
//         }
//         $stmt = $this->conn->prepare($query);
//         $stmt->execute($params);
//         $escalations = $stmt->fetchAll(PDO::FETCH_ASSOC);
//         return json_encode(['status' => 'success', 'data' => $escalations]);
//     }

//     public function resolveEscalation($data) {
//         if (!isset($data['id'], $data['resolution'])) {
//             return json_encode(['status' => 'error', 'message' => 'Missing required fields']);
//         }

//         $query = "UPDATE escalations SET status = 'resolved', resolution = :resolution, updated_at = NOW() WHERE id = :id";
//         $stmt = $this->conn->prepare($query);
//         $stmt->bindParam(':resolution', $data['resolution']);
//         $stmt->bindParam(':id', $data['id']);

//         if ($stmt->execute()) {
//             return json_encode(['status' => 'success', 'message' => 'Escalation resolved']);
//         } else {
//             return json_encode(['status' => 'error', 'message' => 'Error resolving escalation']);
//         }
//     }
// }

// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);


class EscalationsController {
    private $conn;

    public function __construct() {
        $database = new Database();
        $this->conn = $database->getConnection();
    }

    private function validate($data, $required = []) {
        foreach ($required as $field) {
            if (!isset($data[$field]) || trim($data[$field]) === '') {
                return ['status' => 'error', 'message' => "Missing required field: $field"];
            }
        }
        return null;
    }

    // CREATE
    public function create($data, $userId, $userName) {
        $required = ['invoice_id', 'reason', 'description', 'escalated_to', 'due_date', 'priority'];
        $error = $this->validate($data, $required);
        if ($error) return json_encode($error);

        // Generate escalation_id
        $query = "SELECT MAX(CAST(SUBSTRING(escalation_id, 4) AS UNSIGNED)) AS max_id FROM escalations";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        $maxId = $stmt->fetchColumn();
        $newId = $maxId ? $maxId + 1 : 1;
        $escalationId = 'ESC' . str_pad($newId, 5, '0', STR_PAD_LEFT);

        $query = "INSERT INTO escalations (
            escalation_id, invoice_id, reason, priority, description,
            escalated_by, escalated_by_name,
            escalated_to, escalated_to_name,
            due_date
        ) VALUES (
            :escalation_id, :invoice_id, :reason, :priority, :description,
            :escalated_by, :escalated_by_name,
            :escalated_to, :escalated_to_name,
            :due_date
        )";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':escalation_id', $escalationId);
        $stmt->bindParam(':invoice_id', $data['invoice_id']);
        $stmt->bindParam(':reason', $data['reason']);
        $stmt->bindParam(':priority', $data['priority']);
        $stmt->bindParam(':description', $data['description']);
        $stmt->bindParam(':escalated_by', $userId);
        $stmt->bindParam(':escalated_by_name', $data['escalated_by_name']);
        $stmt->bindParam(':escalated_to', $data['escalated_to']);
        $stmt->bindParam(':escalated_to_name', $data['escalated_to_name']);
        $stmt->bindParam(':due_date', $data['due_date']);

        return $stmt->execute()
            ? json_encode(['status' => 'success', 'message' => 'Escalation created'])
            : json_encode(['status' => 'error', 'message' => 'Failed to create escalation']);
    }
    public function getList($filters = [], $userId, $userRole) {
        // normalize role/id types to avoid strict comparison mismatches and accidental binding of missing params
        $userRole = (int)$userRole;
        $userId = (int)$userId;

        $query = "SELECT 
            e.*,
            i.tax_number,
            CONCAT(i.first_name, ' ', i.last_name) AS taxpayer_name,
            i.amount
        FROM escalations e
        LEFT JOIN invoices i ON e.invoice_id = i.invoice_number
        WHERE e.deleted_at IS NULL";

        $params = [];

        // Role-based filtering
        if ($userRole === 3) { // Agent
            $query .= " AND e.escalated_by = :user_id";
            $params[':user_id'] = $userId;
        } elseif ($userRole === 2) { // Supervisor
            $query .= " AND e.escalated_by = :user_id";
            $params[':user_id'] = $userId;

            // $query .= " AND e.escalated_to = :user_id";
            // $params[':user_id'] = $userId;
        } elseif ($userRole === 1) { // Admin
            // Admin can see all escalations
        }

        // Search
        if (!empty($filters['search'])) {
            $search = "%" . $filters['search'] . "%";
            $query .= " AND (e.invoice_id LIKE :search OR e.id LIKE :search OR i.first_name LIKE :search OR i.last_name LIKE :search)";
            $params[':search'] = $search;
        }

        // Filters
        if (!empty($filters['status']) && $filters['status'] !== 'all') {
            $query .= " AND e.status = :status";
            $params[':status'] = $filters['status'];
        }
        if (!empty($filters['priority']) && $filters['priority'] !== 'all') {
            $query .= " AND e.priority = :priority";
            $params[':priority'] = $filters['priority'];
        }

        $query .= " ORDER BY 
            FIELD(e.priority, 'critical', 'high', 'medium') DESC,
            e.due_date ASC";

        $stmt = $this->conn->prepare($query);
        $stmt->execute($params);
        $escalations = $stmt->fetchAll(PDO::FETCH_ASSOC);

        return json_encode([
            'status' => 'success',
            'data' => $escalations,
            'counts' => $this->getCounts($userId, $userRole)
        ]);
    }

    private function getCounts($userId, $userRole) {
        $query = "SELECT 
            COUNT(*) as total,
            SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
            SUM(CASE WHEN status = 'in_review' THEN 1 ELSE 0 END) as in_review,
            SUM(CASE WHEN status = 'resolved' THEN 1 ELSE 0 END) as resolved,
            SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END) as closed
        FROM escalations WHERE deleted_at IS NULL";

        if ($userRole === 3) {
            $query .= " AND escalated_by = :user_id";
        } elseif ($userRole === 2) {
            $query .= " AND escalated_to = :user_id";
        }

        $stmt = $this->conn->prepare($query);
        if ($userRole !== 1) $stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    // GET SINGLE
    public function getOne($id, $userId, $userRole) {
        $query = "SELECT e.*, i.amount, i.tax_number,
                  CONCAT(i.first_name, ' ', i.last_name) AS taxpayer_name
                  FROM escalations e
                  LEFT JOIN invoices i ON e.invoice_id = i.invoice_number
                  WHERE e.id = :id AND e.deleted_at IS NULL";

        if ($userRole === 3) {
            $query .= " AND e.escalated_by = :user_id";
        } elseif ($userRole === 2) {
            $query .= " AND e.escalated_to = :user_id";
        }

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        // Bind :user_id only when the query includes it (roles 2 or 3)
        if ($userRole === 3 || $userRole === 2) {
            $stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
        }
        $stmt->execute();
        $esc = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$esc) return json_encode(['status' => 'error', 'message' => 'Not found']);

        // Get comments
        $comments = $this->getComments($id);
        $esc['comments'] = $comments;

        return json_encode(['status' => 'success', 'data' => $esc]);
    }

    // ADD COMMENT
    public function addComment($escalationId, $data, $userId, $userName) {
        $query = "INSERT INTO escalation_comments (
            escalation_id, author_id, author_name, content, is_internal, created_at
        ) VALUES (
            :escalation_id, :author_id, :author_name, :content, :is_internal, NOW()
        )";

        $stmt = $this->conn->prepare($query);
        $stmt->bindValue(':escalation_id', $escalationId);
        $stmt->bindValue(':author_id', $userId);
        $stmt->bindValue(':author_name', $data['author_name']);
        $stmt->bindValue(':content', $data['content']);
        $stmt->bindValue(':is_internal', $data['is_internal'] ?? 0, PDO::PARAM_INT);

        return $stmt->execute()
            ? json_encode(['status' => 'success', 'message' => 'Comment added'])
            : json_encode(['status' => 'error', 'message' => 'Failed to add comment']);
    }

    private function getComments($escalationId) {
        $query = "SELECT * FROM escalation_comments 
                  WHERE escalation_id = :id 
                  ORDER BY created_at ASC";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $escalationId);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    // RESOLVE
    public function resolve($id, $data, $userId) {
        $query = "UPDATE escalations 
                  SET status = 'resolved', 
                      resolution = :resolution, 
                      resolution_date = NOW()
                  WHERE id = :id AND escalated_to = :user_id AND deleted_at IS NULL";
        $stmt = $this->conn->prepare($query);
        $stmt->bindValue(':id', $id);
        $stmt->bindValue(':resolution', $data['resolution']);
        $stmt->bindValue(':user_id', $userId);

        return $stmt->execute()
            ? json_encode(['status' => 'success', 'message' => 'Escalation resolved'])
            : json_encode(['status' => 'error', 'message' => 'Failed to resolve']);
    }

    // UPDATE STATUS (in_review, pending → in_review, etc.)
    public function updateStatus($id, $status, $userId, $userRole) {
        $allowed = ['pending','in_review','resolved','closed'];
        if (!in_array($status, $allowed)) {
            return json_encode(['status' => 'error', 'message' => 'Invalid status']);
        }

        $query = "UPDATE escalations SET status = :status WHERE id = :id AND deleted_at IS NULL";
        if ($userRole === 3) $query .= " AND escalated_by = :user_id";
        elseif ($userRole === 2) $query .= " AND escalated_to = :user_id";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $id);
        $stmt->bindParam(':status', $status);
        if ($userRole !== 1) $stmt->bindParam(':user_id', $userId);

        return $stmt->execute()
            ? json_encode(['status' => 'success', 'message' => 'Status updated'])
            : json_encode(['status' => 'error', 'message' => 'Failed to update']);
    }

    // SOFT DELETE
    public function delete($id, $userId, $userRole) {
        $query = "UPDATE escalations SET deleted_at = NOW() WHERE id = :id AND deleted_at IS NULL";
        if ($userRole === 3) $query .= " AND escalated_by = :user_id";
        elseif ($userRole === 2) $query .= " AND escalated_to = :user_id";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $id);
        if ($userRole !== 1) $stmt->bindParam(':user_id', $userId);

        return $stmt->execute()
            ? json_encode(['status' => 'success', 'message' => 'Escalation deleted'])
            : json_encode(['status' => 'error', 'message' => 'Failed to delete']);
    }
}
