<?php
require_once __DIR__ . '/BaseModel.php';

/**
 * Maintenance Request Management Class
 * Handles maintenance requests, vendor assignment, and tracking
 */
class Maintenance extends BaseModel {
    protected $tableName = 'maintenance_requests';
    protected $tenantColumn = null; // Maintenance requests are isolated by property_id
    
    public function __construct() {
        parent::__construct();
    }
    
    /**
     * Create a new maintenance request
     */
    public function createRequest($data) {
        // Validate required fields
        $required = ['property_id', 'requester_id', 'category', 'subject', 'description'];
        foreach ($required as $field) {
            if (empty($data[$field])) {
                throw new Exception("Field {$field} is required");
            }
        }
        
        // Generate ticket number
        $ticketNumber = $this->generateTicketNumber();
        
        $requestData = [
            'ticket_number' => $ticketNumber,
            'property_id' => $data['property_id'],
            'unit_id' => $data['unit_id'] ?? null,
            'requester_id' => $data['requester_id'],
            'category' => $data['category'],
            'priority' => $data['priority'] ?? 'Medium',
            'subject' => $data['subject'],
            'description' => $data['description'],
            'images_json' => !empty($data['images']) ? json_encode($data['images']) : null,
            'preferred_visit_date' => $data['preferred_visit_date'] ?? null,
            'access_instructions' => $data['access_instructions'] ?? null,
            'status' => 'Open'
        ];
        
        $requestId = $this->create($requestData);
        
        // Send notification to property manager
        $this->notifyPropertyManager($requestId);
        
        return $requestId;
    }
    
    /**
     * Assign vendor to maintenance request
     */
    public function assignVendor($requestId, $vendorId, $scheduledDate = null, $costEstimate = null) {
        $request = $this->getById($requestId);
        
        if (!$request) {
            throw new Exception("Maintenance request not found");
        }
        
        $updateData = [
            'assigned_vendor_id' => $vendorId,
            'status' => 'Assigned'
        ];
        
        if ($scheduledDate) {
            $updateData['scheduled_date'] = $scheduledDate;
        }
        
        if ($costEstimate) {
            $updateData['cost_estimate'] = $costEstimate;
        }
        
        $this->update($requestId, $updateData);
        
        // Notify vendor
        $this->notifyVendor($requestId, $vendorId);
        
        return true;
    }
    
    /**
     * Update maintenance request status
     */
    public function updateStatus($requestId, $status, $adminNotes = null, $finalCost = null) {
        $updateData = ['status' => $status];
        
        if ($adminNotes) {
            $updateData['admin_notes'] = $adminNotes;
        }
        
        if ($finalCost !== null) {
            $updateData['final_cost'] = $finalCost;
        }
        
        if ($status === 'Completed') {
            $updateData['completed_date'] = date('Y-m-d H:i:s');
        }
        
        return $this->update($requestId, $updateData);
    }
    
    /**
     * Get maintenance request with details
     */
    public function getRequestDetails($id) {
        $request = $this->getById($id);
        
        if (!$request) {
            return null;
        }
        
        // Get requester details
        $sql = "SELECT id, first_name, last_name, email, phone FROM users WHERE id = ?";
        $result = $this->db->query($sql, [$request['requester_id']]);
        $request['requester'] = $result->fetch_assoc();
        
        // Get property details
        $propertyModel = new Property();
        $request['property'] = $propertyModel->getById($request['property_id']);
        
        // Get unit details if exists
        if ($request['unit_id']) {
            $unitModel = new Unit();
            $request['unit'] = $unitModel->getById($request['unit_id']);
        }
        
        // Get vendor details if assigned
        if ($request['assigned_vendor_id']) {
            $vendorModel = new Vendor();
            $request['vendor'] = $vendorModel->getById($request['assigned_vendor_id']);
        }
        
        // Parse images JSON
        if ($request['images_json']) {
            $request['images'] = json_decode($request['images_json'], true);
        }
        
        return $request;
    }
    
    /**
     * Get maintenance requests by property
     */
    public function getRequestsByProperty($propertyId, $status = null) {
        $sql = "SELECT mr.*, u.first_name, u.last_name, u.email, u.phone, un.unit_number 
                FROM maintenance_requests mr 
                INNER JOIN users u ON mr.requester_id = u.id 
                LEFT JOIN units un ON mr.unit_id = un.id 
                WHERE mr.property_id = ?";
        
        $params = [$propertyId];
        
        if ($status) {
            $sql .= " AND mr.status = ?";
            $params[] = $status;
        }
        
        $sql .= " ORDER BY 
                    CASE mr.priority 
                        WHEN 'Emergency' THEN 1 
                        WHEN 'High' THEN 2 
                        WHEN 'Medium' THEN 3 
                        ELSE 4 
                    END, 
                    mr.created_at DESC";
        
        $result = $this->db->query($sql, $params);
        $requests = [];
        
        while ($row = $result->fetch_assoc()) {
            $requests[] = $row;
        }
        
        return $requests;
    }
    
    /**
     * Get maintenance requests by tenant
     */
    public function getRequestsByTenant($tenantId) {
        $sql = "SELECT mr.*, p.name as property_name, un.unit_number 
                FROM maintenance_requests mr 
                INNER JOIN properties p ON mr.property_id = p.id 
                LEFT JOIN units un ON mr.unit_id = un.id 
                WHERE mr.requester_id = ? 
                ORDER BY mr.created_at DESC";
        
        $result = $this->db->query($sql, [$tenantId]);
        $requests = [];
        
        while ($row = $result->fetch_assoc()) {
            $requests[] = $row;
        }
        
        return $requests;
    }
    
    /**
     * Get maintenance requests by vendor
     */
    public function getRequestsByVendor($vendorId, $status = null) {
        $sql = "SELECT mr.*, p.name as property_name, un.unit_number, 
                       u.first_name, u.last_name, u.phone 
                FROM maintenance_requests mr 
                INNER JOIN properties p ON mr.property_id = p.id 
                LEFT JOIN units un ON mr.unit_id = un.id 
                LEFT JOIN users u ON mr.requester_id = u.id 
                WHERE mr.assigned_vendor_id = ?";
        
        $params = [$vendorId];
        
        if ($status) {
            $sql .= " AND mr.status = ?";
            $params[] = $status;
        }
        
        $sql .= " ORDER BY mr.scheduled_date ASC, mr.created_at DESC";
        
        $result = $this->db->query($sql, $params);
        $requests = [];
        
        while ($row = $result->fetch_assoc()) {
            $requests[] = $row;
        }
        
        return $requests;
    }
    
    /**
     * Generate ticket number
     */
    private function generateTicketNumber() {
        $prefix = 'MR';
        $year = date('Y');
        $month = date('m');
        
        // Get last ticket number
        $sql = "SELECT ticket_number FROM maintenance_requests 
                WHERE ticket_number LIKE ? 
                ORDER BY id DESC LIMIT 1";
        
        $pattern = "{$prefix}-{$year}{$month}-%";
        $result = $this->db->query($sql, [$pattern]);
        
        if ($result->num_rows > 0) {
            $lastTicket = $result->fetch_assoc();
            $lastNumber = (int)substr($lastTicket['ticket_number'], -4);
            $newNumber = $lastNumber + 1;
        } else {
            $newNumber = 1;
        }
        
        return sprintf("%s-%s%s-%04d", $prefix, $year, $month, $newNumber);
    }
    
    /**
     * Notify property manager (placeholder)
     */
    private function notifyPropertyManager($requestId) {
        // TODO: Implement notification system
    }
    
    /**
     * Notify vendor (placeholder)
     */
    private function notifyVendor($requestId, $vendorId) {
        // TODO: Implement notification system
    }
}
?>
