<?php
declare(strict_types=1);

// Christo Lochenberg Developments | info@christodev.co.za | +27 61 523 9126

use Dompdf\Dompdf;
use Dompdf\Options;

class AdminJobcards extends Controller {
    
    private $jobcardModel;
    private $userModel;
    private $partnerModel;

    public function __construct() {
        if (!isLoggedIn() || !isAdmin()) {
            header('Location: ' . URLROOT . '/users/login');
            exit;
        }

        $this->jobcardModel = $this->model('Jobcard');
        $this->userModel = $this->model('User');
        $this->partnerModel = $this->model('Partner');
    }

    public function jobcards(): void {
        $jobcards = $this->jobcardModel->getJobcards('admin', (int)$_SESSION['user_id']);

        $data = [
            'title' => 'Jobcard Management',
            'description' => 'Create, assign, and monitor technical support jobcards.',
            'jobcards' => $jobcards,
            'help_title' => 'Admin Jobcards Guide',
            'help_content' => '
                <h4 class="font-bold text-gray-800 dark:text-gray-200 mt-0">Managing Jobcards</h4>
                <p>As an administrator, you have full visibility into the lifecycle of every jobcard in the system.</p>
                <ul class="list-disc pl-5 space-y-2 mt-2">
                    <li><strong>Creation:</strong> When creating a jobcard, you must assign it to a Client. You can also optionally assign it to a Partner or dispatch it directly to a Technician from the start.</li>
                    <li><strong>Assignment:</strong> Jobcards remain in a "Created" state until a Technician is assigned. Once assigned, the technician will receive an email notification.</li>
                </ul>
            '
        ];

        $this->view('admin/jobcards/index', $data);
    }

    public function createJobcard(): void {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
            
            $data = [
                'client_id' => empty($_POST['client_id']) ? null : (int)$_POST['client_id'],
                'partner_id' => empty($_POST['partner_id']) ? null : (int)$_POST['partner_id'],
                'technician_id' => empty($_POST['technician_id']) ? null : (int)$_POST['technician_id'],
                'instructions' => trim($_POST['instructions']),
                'client_err' => '',
                'instructions_err' => ''
            ];

            if (empty($data['client_id'])) {
                $data['client_err'] = 'You must select a client for this jobcard.';
            }

            if (empty($data['instructions'])) {
                $data['instructions_err'] = 'Please provide instructions for the technician.';
            }

            if (empty($data['client_err']) && empty($data['instructions_err'])) {
                $jobNumber = $this->jobcardModel->createJobcard($data);
                
                if ($jobNumber) {
                    $settings = getSettings();
                    $appName = $settings['app_name'] ?? SITENAME;
                    $clientUser = $this->userModel->getUserById($data['client_id']);

                    $providerName = $appName;
                    $partnerEmail = '';
                    if (!empty($data['partner_id'])) {
                        $partner = $this->partnerModel->getPartnerById($data['partner_id']);
                        if ($partner) {
                            $providerName = $partner->name;
                            $partnerEmail = $partner->email;
                        }
                    }

                    $techNameText = '<span style="color:#eab308; font-weight:bold;">A technician will be assigned to this jobcard soon.</span>';
                    $techEmail = '';
                    $techNamePlain = 'Unassigned';
                    
                    if (!empty($data['technician_id'])) {
                        $techUser = $this->userModel->getUserById($data['technician_id']);
                        if ($techUser) {
                            $techNameText = $techUser->name;
                            $techNamePlain = $techUser->name;
                            $techEmail = $techUser->email;
                        }
                    }

                    // 1. Email Client
                    $clientBody = "<h2>Jobcard Created: {$jobNumber}</h2>";
                    $clientBody .= "<p>Hello {$clientUser->name},</p>";
                    $clientBody .= "<p>A new jobcard has been logged for you by <strong>{$providerName}</strong>.</p>";
                    $clientBody .= "<div style='background-color:#f8fafc; padding:15px; border-radius:8px; border:1px solid #e2e8f0; margin-bottom:15px;'>";
                    $clientBody .= "<p style='margin-top:0;'><strong>Technician Status:</strong> {$techNameText}</p>";
                    $clientBody .= "</div>";
                    $clientBody .= "<p><strong>Instructions / Issue:</strong><br>" . nl2br(htmlspecialchars($data['instructions'])) . "</p>";
                    sendEmail($clientUser->email, "Jobcard Created: {$jobNumber}", $clientBody);

                    // 2. Email Partner OR Admin
                    $notifyBody = "<h2>Jobcard Logged: {$jobNumber}</h2>";
                    $notifyBody .= "<p>A new jobcard has been created.</p>";
                    $notifyBody .= "<ul>";
                    $notifyBody .= "<li><strong>Client:</strong> {$clientUser->name}</li>";
                    $notifyBody .= "<li><strong>Technician:</strong> {$techNamePlain}</li>";
                    $notifyBody .= "</ul>";
                    $notifyBody .= "<p><strong>Instructions:</strong><br>" . nl2br(htmlspecialchars($data['instructions'])) . "</p>";

                    if (!empty($partnerEmail)) {
                        sendEmail($partnerEmail, "New Jobcard Logged: {$jobNumber}", $notifyBody);
                    } else {
                        $adminEmail = $settings['contact_email'] ?? 'info@christodev.co.za';
                        sendEmail($adminEmail, "Internal Jobcard Created: {$jobNumber}", $notifyBody);
                    }

                    // 3. Email Technician (if assigned immediately)
                    if (!empty($techEmail)) {
                        $techBody = "<h2>New Jobcard Assigned: {$jobNumber}</h2>";
                        $techBody .= "<p>Hello {$techNamePlain},</p>";
                        $techBody .= "<p>You have been assigned a new jobcard for <strong>{$clientUser->name}</strong>.</p>";
                        $techBody .= "<div style='background-color:#f8fafc; padding:15px; border-radius:8px; border:1px solid #e2e8f0;'>";
                        $techBody .= "<p style='margin-top:0;'><strong>Instructions:</strong></p>";
                        $techBody .= "<p style='margin-bottom:0;'>" . nl2br(htmlspecialchars($data['instructions'])) . "</p>";
                        $techBody .= "</div>";
                        sendEmail($techEmail, "New Job Assignment: {$jobNumber}", $techBody);
                        
                        systemLog('JOBCARD_CREATED_AND_ASSIGNED', "Admin created and instantly assigned jobcard {$jobNumber} to Technician ID {$data['technician_id']}");
                        flash('system_msg', "Jobcard {$jobNumber} created and assigned to the technician successfully.", 'success');
                    } else {
                        systemLog('JOBCARD_CREATED', "Admin created new unassigned jobcard: {$jobNumber}");
                        flash('system_msg', "Jobcard {$jobNumber} created successfully. You can assign a technician later.", 'success');
                    }

                    header('Location: ' . URLROOT . '/admin/jobcards');
                    exit;
                } else {
                    flash('system_msg', 'Something went wrong creating the jobcard.', 'error');
                }
            }
        } else {
            $data = [
                'client_id' => null,
                'partner_id' => null,
                'technician_id' => null,
                'instructions' => '',
                'client_err' => '',
                'instructions_err' => ''
            ];
        }
        
        $allUsers = $this->userModel->getUsers();
        $partners = $this->partnerModel->getPartners();

        $staffMembers = array_filter($allUsers, function($u) {
            return $u->role === 'staff' || $u->role === 'admin';
        });

        $data['users'] = $allUsers;
        $data['staff'] = $staffMembers;
        $data['partners'] = $partners;

        $this->view('admin/jobcards/create', $data);
    }

    public function viewJobcard($id = null): void {
        if (!$id) {
            header('Location: ' . URLROOT . '/admin/jobcards');
            exit;
        }

        $jobcard = $this->jobcardModel->getJobcardById((int)$id);

        if (!$jobcard) {
            header('Location: ' . URLROOT . '/admin/jobcards');
            exit;
        }

        $materials = $this->jobcardModel->getMaterialsByJobcard((int)$id);
        
        $allUsers = $this->userModel->getUsers();
        $staffMembers = array_filter($allUsers, function($u) {
            return $u->role === 'staff' || $u->role === 'admin'; 
        });

        $data = [
            'title' => 'Jobcard Details: ' . $jobcard->jobcard_number,
            'jobcard' => $jobcard,
            'materials' => $materials,
            'staff' => $staffMembers
        ];

        $this->view('admin/jobcards/view', $data);
    }

    public function assignTechnician(): void {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $jobcardId = (int)$_POST['jobcard_id'];
            $techId = (int)$_POST['technician_id'];

            if ($this->jobcardModel->assignTechnician($jobcardId, $techId)) {
                
                $jobcard = $this->jobcardModel->getJobcardById($jobcardId);
                $settings = getSettings();
                $providerName = $jobcard->partner_name ?: ($settings['app_name'] ?? SITENAME);
                
                // 1. Email Tech
                $techBody = "<h2>New Jobcard Assigned: {$jobcard->jobcard_number}</h2>";
                $techBody .= "<p>Hello {$jobcard->tech_name},</p>";
                $techBody .= "<p>You have been assigned a new jobcard for <strong>{$jobcard->client_name}</strong>.</p>";
                $techBody .= "<div style='background-color:#f8fafc; padding:15px; border-radius:8px; border:1px solid #e2e8f0;'>";
                $techBody .= "<p style='margin-top:0;'><strong>Instructions:</strong></p>";
                $techBody .= "<p style='margin-bottom:0;'>" . nl2br(htmlspecialchars($jobcard->instructions)) . "</p>";
                $techBody .= "</div>";
                sendEmail($jobcard->tech_email, "New Job Assignment: {$jobcard->jobcard_number}", $techBody);

                // 2. Email Client
                $clientBody = "<h2>Technician Assigned: {$jobcard->jobcard_number}</h2>";
                $clientBody .= "<p>Hello {$jobcard->client_name},</p>";
                $clientBody .= "<p>Technician <strong>{$jobcard->tech_name}</strong> has been assigned to your jobcard by <strong>{$providerName}</strong>.</p>";
                sendEmail($jobcard->client_email, "Technician Assigned: {$jobcard->jobcard_number}", $clientBody);

                // 3. Email Partner OR Admin
                $notifyBody = "<h2>Technician Assigned: {$jobcard->jobcard_number}</h2>";
                $notifyBody .= "<p>Technician <strong>{$jobcard->tech_name}</strong> has been assigned to client <strong>{$jobcard->client_name}</strong>.</p>";
                if (!empty($jobcard->partner_email)) {
                    sendEmail($jobcard->partner_email, "Technician Assigned: {$jobcard->jobcard_number}", $notifyBody);
                } else {
                    $adminEmail = $settings['contact_email'] ?? 'info@christodev.co.za';
                    sendEmail($adminEmail, "Technician Assigned: {$jobcard->jobcard_number}", $notifyBody);
                }

                systemLog('JOBCARD_ASSIGNED', "Admin assigned Technician ID {$techId} to Jobcard {$jobcard->jobcard_number}");
                flash('system_msg', 'Technician assigned successfully. Email notifications queued for all parties.', 'success');
            } else {
                flash('system_msg', 'Failed to assign technician.', 'error');
            }
            
            header('Location: ' . URLROOT . '/admin/viewJobcard/' . $jobcardId);
            exit;
        }
    }

    public function downloadPdf($id = null): void {
        if (!$id) {
            header('Location: ' . URLROOT . '/admin/jobcards');
            exit;
        }

        $jobcard = $this->jobcardModel->getJobcardById((int)$id);

        if (!$jobcard || $jobcard->status !== 'Signed Off') {
            flash('system_msg', 'Jobcard not found or not yet finalized.', 'error');
            header('Location: ' . URLROOT . '/admin/jobcards');
            exit;
        }

        $materials = $this->jobcardModel->getMaterialsByJobcard((int)$id);
        $settings = getSettings();

        if (class_exists('Dompdf\Dompdf')) {
            $options = new Options();
            $options->set('isHtml5ParserEnabled', true);
            $options->set('isRemoteEnabled', true);
            $options->set('defaultFont', 'Helvetica');
            
            $dompdf = new Dompdf($options);

            ob_start();
            $data = ['jobcard' => $jobcard, 'materials' => $materials, 'settings' => $settings];
            require APPROOT . '/app/Views/staff/jobcards/pdf.php';
            $html = ob_get_clean();

            $dompdf->loadHtml($html);
            $dompdf->setPaper('A4', 'portrait');
            $dompdf->render();

            systemLog('JOBCARD_PDF_DOWNLOADED', "Admin downloaded PDF for Jobcard: {$jobcard->jobcard_number}");

            $dompdf->stream('Jobcard_' . $jobcard->jobcard_number . '.pdf', ['Attachment' => true]);
            exit;
        } else {
            flash('system_msg', 'PDF Generation engine not found.', 'error');
            header('Location: ' . URLROOT . '/admin/viewJobcard/' . $id);
            exit;
        }
    }
}