<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
use Mike42\Escpos\Printer as EscposPrinter;
use Exception;

class Printer extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        // Basic Information
        'name',
        'alias',
        'description',
        
        // Connection Settings
        'connection_type',
        'ip_address',
        'port',
        'device_path',
        'bluetooth_address',
        'file_path',
        
        // Printer Configuration
        'printer_driver',
        'paper_size',
        'chars_per_line',
        'supports_graphics',
        'supports_barcode',
        'supports_qr_code',
        'encoding',
        
        // Print Settings
        'auto_cut',
        'auto_open_drawer',
        'print_density',
        'print_speed',
        'margin_top',
        'margin_bottom',
        'margin_left',
        'margin_right',
        
        // Receipt Configuration
        'header_template',
        'footer_template',
        'custom_css',
        'print_store_logo',
        'logo_path',
        'print_barcode_on_receipt',
        'print_qr_on_receipt',
        
        // Status & Settings
        'is_default',
        'is_active',
        'status',
        'last_error',
        'last_used_at',
        'last_maintenance_at',
        'print_count',
        'error_count',
        
        // Thermal Printer Specific
        'has_cutter',
        'has_drawer_kick',
        'drawer_pin',
        'drawer_pulse_time',
        'buzzer_pin',
        'has_buzzer',
        
        // Network Printer Settings
        'timeout',
        'retry_count',
        'use_ssl',
        'auth_type',
        'username',
        'password',
        
        // Print Job Settings
        'max_job_queue',
        'job_timeout',
        'enable_queue',
        'enable_retry',
        
        // Usage Statistics
        'total_prints',
        'successful_prints',
        'failed_prints',
        'success_rate',
        'paper_used',
        'paper_last_changed',
        'estimated_paper_remaining',
        
        // Printer Health
        'temperature',
        'head_status',
        'paper_status',
        'cover_status',
        'cutter_status',
        'last_health_check',
        
        // Location & Assignment
        'location',
        'department',
        'assigned_to',
        'terminal_id',
        
        // Maintenance
        'maintenance_interval',
        'next_maintenance_date',
        'maintenance_notes',
        'service_provider',
        'service_contact',
        
        // Cost & Warranty
        'purchase_cost',
        'purchase_date',
        'warranty_period',
        'warranty_expiry',
        'operational_cost_per_print',
        
        // Metadata
        'capabilities',
        'settings',
        'custom_commands',
        
        // Audit
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        // Booleans
        'supports_graphics' => 'boolean',
        'supports_barcode' => 'boolean',
        'supports_qr_code' => 'boolean',
        'auto_cut' => 'boolean',
        'auto_open_drawer' => 'boolean',
        'has_cutter' => 'boolean',
        'has_drawer_kick' => 'boolean',
        'has_buzzer' => 'boolean',
        'is_default' => 'boolean',
        'is_active' => 'boolean',
        'print_store_logo' => 'boolean',
        'print_barcode_on_receipt' => 'boolean',
        'print_qr_on_receipt' => 'boolean',
        'use_ssl' => 'boolean',
        'enable_queue' => 'boolean',
        'enable_retry' => 'boolean',
        
        // Numbers
        'port' => 'integer',
        'chars_per_line' => 'integer',
        'print_density' => 'integer',
        'print_speed' => 'integer',
        'margin_top' => 'integer',
        'margin_bottom' => 'integer',
        'margin_left' => 'integer',
        'margin_right' => 'integer',
        'drawer_pulse_time' => 'integer',
        'timeout' => 'integer',
        'retry_count' => 'integer',
        'max_job_queue' => 'integer',
        'job_timeout' => 'integer',
        'total_prints' => 'integer',
        'successful_prints' => 'integer',
        'failed_prints' => 'integer',
        'print_count' => 'integer',
        'error_count' => 'integer',
        'paper_used' => 'integer',
        'estimated_paper_remaining' => 'integer',
        'temperature' => 'integer',
        'maintenance_interval' => 'integer',
        
        // Decimals
        'success_rate' => 'decimal:2',
        'purchase_cost' => 'decimal:2',
        'operational_cost_per_print' => 'decimal:4',
        
        // JSON
        'capabilities' => 'array',
        'settings' => 'array',
        'custom_commands' => 'array',
        
        // Dates
        'last_used_at' => 'datetime',
        'last_maintenance_at' => 'datetime',
        'paper_last_changed' => 'datetime',
        'last_health_check' => 'datetime',
        'next_maintenance_date' => 'datetime',
        'purchase_date' => 'datetime',
        'warranty_expiry' => 'datetime',
    ];

    protected $appends = [
        'connection_string',
        'is_online',
        'health_status',
        'estimated_cost_to_date',
        'printer_type',
        'paper_width_mm',
        'needs_maintenance',
        'paper_status_icon',
        'head_status_icon',
        'cover_status_icon',
        'cutter_status_icon',
        'printer_status_icon',
        'queue_size',
        'average_print_time',
        'failure_rate',
    ];

    /**
     * Boot the model.
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($printer) {
            // Ensure only one default printer
            if ($printer->is_default) {
                static::where('is_default', true)->update(['is_default' => false]);
            }
            
            // Set created_by if not set
            if (auth()->check() && !$printer->created_by) {
                $printer->created_by = auth()->id();
            }
            
            // Initialize success rate
            if (!$printer->success_rate) {
                $printer->success_rate = 100.00;
            }
        });

        static::updating(function ($printer) {
            // Ensure only one default printer
            if ($printer->is_default) {
                static::where('is_default', true)
                    ->where('id', '!=', $printer->id)
                    ->update(['is_default' => false]);
            }
            
            // Set updated_by if not set
            if (auth()->check()) {
                $printer->updated_by = auth()->id();
            }
            
            // Update success rate
            if ($printer->total_prints > 0) {
                $printer->success_rate = ($printer->successful_prints / $printer->total_prints) * 100;
            }
        });

        static::saved(function ($printer) {
            // Update last maintenance date if maintenance interval is set
            if ($printer->maintenance_interval && !$printer->next_maintenance_date) {
                $printer->update([
                    'next_maintenance_date' => now()->addDays($printer->maintenance_interval)
                ]);
            }
        });
    }

    /**
     * Relationships
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updater(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    public function assignedUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'assigned_to');
    }

    public function terminal(): BelongsTo
    {
        return $this->belongsTo(Terminal::class);
    }

    public function jobs(): HasMany
    {
        return $this->hasMany(PrinterJob::class);
    }

    public function logs(): HasMany
    {
        return $this->hasMany(PrinterLog::class);
    }

    public function pendingJobs(): HasMany
    {
        return $this->jobs()->whereIn('job_status', ['pending', 'processing']);
    }

    public function completedJobs(): HasMany
    {
        return $this->jobs()->where('job_status', 'completed');
    }

    public function failedJobs(): HasMany
    {
        return $this->hasMany(PrinterJob::class)->where('job_status', 'failed');
    }

    /**
     * Accessors
     */
    public function getConnectionStringAttribute(): string
    {
        switch ($this->connection_type) {
            case 'network':
                return $this->ip_address . ':' . $this->port;
            case 'usb':
            case 'serial':
                return $this->device_path;
            case 'bluetooth':
                return $this->bluetooth_address;
            case 'file':
                return $this->file_path;
            default:
                return 'Unknown connection';
        }
    }

    public function getIsOnlineAttribute(): bool
    {
        return $this->status === 'online';
    }

    public function getHealthStatusAttribute(): string
    {
        if (!$this->is_active) {
            return 'inactive';
        }

        if ($this->status === 'error') {
            return 'error';
        }

        if ($this->paper_status === 'out' || $this->paper_status === 'jammed') {
            return 'paper_error';
        }

        if ($this->cover_status === 'open') {
            return 'cover_open';
        }

        if ($this->head_status === 'overheat') {
            return 'overheat';
        }

        if ($this->temperature && $this->temperature > 60) {
            return 'hot';
        }

        if ($this->success_rate < 90) {
            return 'poor_performance';
        }

        if ($this->needs_maintenance) {
            return 'needs_maintenance';
        }

        return 'healthy';
    }

    public function getEstimatedCostToDateAttribute(): float
    {
        if (!$this->operational_cost_per_print || !$this->total_prints) {
            return 0;
        }

        return round($this->operational_cost_per_print * $this->total_prints, 2);
    }

    public function getPrinterTypeAttribute(): string
    {
        if (str_contains(strtolower($this->name), 'thermal')) {
            return 'thermal';
        }

        if (str_contains(strtolower($this->name), 'laser')) {
            return 'laser';
        }

        if (str_contains(strtolower($this->name), 'inkjet')) {
            return 'inkjet';
        }

        if (str_contains(strtolower($this->name), 'dot matrix')) {
            return 'dot_matrix';
        }

        return 'unknown';
    }

    public function getPaperWidthMmAttribute(): int
    {
        switch ($this->paper_size) {
            case '80mm':
                return 80;
            case '58mm':
                return 58;
            case 'A4':
                return 210;
            case 'letter':
                return 216;
            default:
                return 80;
        }
    }

    public function getNeedsMaintenanceAttribute(): bool
    {
        if (!$this->next_maintenance_date) {
            return false;
        }

        if ($this->total_prints > 10000 && $this->print_count % 5000 === 0) {
            return true;
        }

        return now()->greaterThanOrEqualTo($this->next_maintenance_date);
    }

    public function getPaperStatusIconAttribute(): string
    {
        switch ($this->paper_status) {
            case 'ok':
                return '✅';
            case 'low':
                return '⚠️';
            case 'out':
                return '❌';
            case 'jammed':
                return '🔄';
            default:
                return '❓';
        }
    }

    public function getHeadStatusIconAttribute(): string
    {
        switch ($this->head_status) {
            case 'ok':
                return '✅';
            case 'hot':
                return '🌡️';
            case 'overheat':
                return '🔥';
            default:
                return '❓';
        }
    }

    public function getCoverStatusIconAttribute(): string
    {
        switch ($this->cover_status) {
            case 'closed':
                return '✅';
            case 'open':
                return '🚪';
            default:
                return '❓';
        }
    }

    public function getCutterStatusIconAttribute(): string
    {
        switch ($this->cutter_status) {
            case 'ok':
                return '✅';
            case 'error':
                return '✂️❌';
            default:
                return '❓';
        }
    }

    public function getPrinterStatusIconAttribute(): string
    {
        switch ($this->status) {
            case 'online':
                return '🟢';
            case 'offline':
                return '🔴';
            case 'printing':
                return '🖨️';
            case 'error':
                return '❌';
            default:
                return '❓';
        }
    }

    public function getQueueSizeAttribute(): int
    {
        return $this->pendingJobs()->count();
    }

    public function getAveragePrintTimeAttribute(): ?float
    {
        $completedJobs = $this->completedJobs()
            ->whereNotNull('processed_at')
            ->whereNotNull('completed_at')
            ->get();

        if ($completedJobs->isEmpty()) {
            return null;
        }

        $totalTime = $completedJobs->sum(function ($job) {
            return $job->processed_at->diffInSeconds($job->completed_at);
        });

        return round($totalTime / $completedJobs->count(), 2);
    }

    public function getFailureRateAttribute(): float
    {
        if ($this->total_prints === 0) {
            return 0;
        }

        return round(($this->failed_prints / $this->total_prints) * 100, 2);
    }

    /**
     * Scope for active printers.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope for default printer.
     */
    public function scopeDefault($query)
    {
        return $query->where('is_default', true);
    }

    /**
     * Scope for online printers.
     */
    public function scopeOnline($query)
    {
        return $query->where('status', 'online');
    }

    /**
     * Scope for printers that need maintenance.
     */
    public function scopeNeedsMaintenance($query)
    {
        return $query->where(function ($q) {
            $q->whereNotNull('next_maintenance_date')
              ->where('next_maintenance_date', '<=', now());
        })->orWhere(function ($q) {
            $q->where('total_prints', '>', 10000)
              ->whereRaw('total_prints % 5000 = 0');
        });
    }

    /**
     * Scope for printers by connection type.
     */
    public function scopeByConnectionType($query, $type)
    {
        return $query->where('connection_type', $type);
    }

    /**
     * Scope for printers by location.
     */
    public function scopeByLocation($query, $location)
    {
        return $query->where('location', $location);
    }

    /**
     * Scope for printers with paper issues.
     */
    public function scopeWithPaperIssues($query)
    {
        return $query->whereIn('paper_status', ['low', 'out', 'jammed']);
    }

    /**
     * Scope for printers with errors.
     */
    public function scopeWithErrors($query)
    {
        return $query->where('status', 'error')
            ->orWhere('error_count', '>', 0);
    }

    /**
     * Create a print connector based on printer configuration.
     */
    public function createConnector()
    {
        try {
            switch ($this->connection_type) {
                case 'network':
                    $connector = new NetworkPrintConnector(
                        $this->ip_address,
                        $this->port,
                        $this->timeout
                    );
                    break;

                case 'usb':
                case 'serial':
                    $connector = new FilePrintConnector($this->device_path);
                    break;

                case 'windows':
                    $connector = new WindowsPrintConnector($this->device_path);
                    break;

                case 'file':
                    $connector = new FilePrintConnector($this->file_path);
                    break;

                default:
                    throw new Exception("Unsupported connection type: {$this->connection_type}");
            }

            return $connector;
        } catch (Exception $e) {
            $this->logError('create_connector', $e->getMessage());
            throw $e;
        }
    }

    /**
     * Test printer connection.
     */
    public function testConnection(): array
    {
        try {
            $connector = $this->createConnector();
            $printer = new EscposPrinter($connector);
            
            // Send test command
            $printer->text("Printer Test\n");
            $printer->text("Connection: {$this->connection_string}\n");
            $printer->text("Time: " . now()->format('Y-m-d H:i:s') . "\n");
            $printer->cut();
            $printer->close();
            
            $this->updateStatus('online');
            
            return [
                'success' => true,
                'message' => 'Printer test successful',
                'printer' => $this->name,
                'connection' => $this->connection_string,
            ];
            
        } catch (Exception $e) {
            $this->updateStatus('error', $e->getMessage());
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'printer' => $this->name,
                'connection' => $this->connection_string,
            ];
        }
    }

    /**
     * Print a receipt.
     */
    public function printReceipt(array $receiptData): array
    {
        DB::beginTransaction();
        
        try {
            // Create print job
            $job = PrinterJob::create([
                'printer_id' => $this->id,
                'job_type' => 'receipt',
                'job_status' => 'pending',
                'content' => json_encode($receiptData),
                'priority' => 1, // High priority for receipts
                'metadata' => [
                    'invoice_no' => $receiptData['invoice_no'] ?? null,
                    'customer' => $receiptData['customer'] ?? null,
                    'total' => $receiptData['total'] ?? 0,
                ],
            ]);
            
            // Process the job
            $result = $this->processJob($job);
            
            if ($result['success']) {
                DB::commit();
                
                // Update printer statistics
                $this->incrementStats(true);
                
                return [
                    'success' => true,
                    'message' => 'Receipt printed successfully',
                    'job_id' => $job->id,
                    'invoice_no' => $receiptData['invoice_no'] ?? null,
                ];
            } else {
                DB::rollBack();
                
                // Update printer statistics
                $this->incrementStats(false);
                
                return [
                    'success' => false,
                    'error' => $result['error'],
                    'job_id' => $job->id,
                ];
            }
            
        } catch (Exception $e) {
            DB::rollBack();
            $this->logError('print_receipt', $e->getMessage());
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Process a print job.
     */
    private function processJob(PrinterJob $job): array
    {
        try {
            $job->update(['job_status' => 'processing', 'processed_at' => now()]);
            
            $connector = $this->createConnector();
            $printer = new EscposPrinter($connector);
            
            // Configure printer
            $this->configurePrinter($printer);
            
            // Parse job content
            $content = json_decode($job->content, true);
            
            // Print based on job type
            switch ($job->job_type) {
                case 'receipt':
                    $this->printReceiptContent($printer, $content);
                    break;
                case 'label':
                    $this->printLabel($printer, $content);
                    break;
                case 'report':
                    $this->printReport($printer, $content);
                    break;
                case 'test':
                    $this->printTestPage($printer);
                    break;
                default:
                    throw new Exception("Unknown job type: {$job->job_type}");
            }
            
            // Finalize print job
            $this->finalizePrint($printer);
            $printer->close();
            
            // Update job status
            $job->update([
                'job_status' => 'completed',
                'completed_at' => now(),
            ]);
            
            return ['success' => true];
            
        } catch (Exception $e) {
            $job->update([
                'job_status' => 'failed',
                'error_message' => $e->getMessage(),
                'attempts' => $job->attempts + 1,
            ]);
            
            $this->logError('process_job', $e->getMessage(), ['job_id' => $job->id]);
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Configure printer with settings.
     */
    private function configurePrinter(EscposPrinter $printer): void
    {
        // Set encoding
        $printer->setEncoding($this->encoding);
        
        // Set print density
        if ($this->print_density >= 0 && $this->print_density <= 15) {
            $printer->setPrintDensity($this->print_density);
        }
        
        // Set print speed
        if ($this->print_speed >= 1 && $this->print_speed <= 5) {
            // Note: Speed setting may vary by printer model
            $printer->setPrintSpeed($this->print_speed);
        }
        
        // Set margins
        if ($this->margin_top > 0) {
            $printer->setPrintTopMargin($this->margin_top);
        }
        
        if ($this->margin_bottom > 0) {
            $printer->setPrintBottomMargin($this->margin_bottom);
        }
        
        if ($this->margin_left > 0) {
            $printer->setPrintLeftMargin($this->margin_left);
        }
        
        if ($this->margin_right > 0) {
            $printer->setPrintRightMargin($this->margin_right);
        }
        
        // Apply custom commands if any
        if ($this->custom_commands) {
            foreach ($this->custom_commands as $command) {
                // Execute custom ESC/POS commands
                $printer->getPrintConnector()->write($command);
            }
        }
    }

    /**
     * Print receipt content.
     */
    private function printReceiptContent(EscposPrinter $printer, array $content): void
    {
        // Store header
        if ($this->print_store_logo && $this->logo_path && file_exists($this->logo_path)) {
            try {
                $logo = EscposImage::load($this->logo_path);
                $printer->graphics($logo);
                $printer->feed();
            } catch (Exception $e) {
                // Log but continue without logo
                $this->logError('print_logo', $e->getMessage());
            }
        }
        
        // Store name
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_HEIGHT | EscposPrinter::MODE_DOUBLE_WIDTH);
        $printer->text($content['store']['name'] . "\n");
        $printer->selectPrintMode();
        
        // Store details
        if (!empty($content['store']['address'])) {
            $printer->text($content['store']['address'] . "\n");
        }
        if (!empty($content['store']['phone'])) {
            $printer->text("Tel: " . $content['store']['phone'] . "\n");
        }
        if (!empty($content['store']['vat_number'])) {
            $printer->text("VAT: " . $content['store']['vat_number'] . "\n");
        }
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Sale information
        $printer->setJustification(EscposPrinter::JUSTIFY_LEFT);
        $printer->text("Invoice: " . $content['sale']['invoice_no'] . "\n");
        $printer->text("Date: " . $content['sale']['date'] . "\n");
        $printer->text("Cashier: " . $content['sale']['cashier'] . "\n");
        
        if ($content['customer']) {
            $printer->text("Customer: " . $content['customer']['name'] . "\n");
        }
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Items header
        $printer->text(str_pad("Item", 20) . str_pad("Qty", 6) . str_pad("Price", 8) . str_pad("Total", 10) . "\n");
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Items
        foreach ($content['items'] as $item) {
            $name = substr($item['name'], 0, 20);
            $qty = str_pad($item['quantity'], 5);
            $price = str_pad(number_format($item['unit_price'], 2), 7);
            $total = str_pad(number_format($item['total'], 2), 9);
            
            $printer->text(str_pad($name, 20) . $qty . $price . $total . "\n");
        }
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Totals
        $printer->setEmphasis(true);
        $printer->text(str_pad("Subtotal:", 30) . str_pad(number_format($content['totals']['subtotal'], 2), 10, ' ', STR_PAD_LEFT) . "\n");
        
        if ($content['totals']['vat'] > 0) {
            $printer->text(str_pad("VAT:", 30) . str_pad(number_format($content['totals']['vat'], 2), 10, ' ', STR_PAD_LEFT) . "\n");
        }
        
        if ($content['totals']['discount'] > 0) {
            $printer->text(str_pad("Discount:", 30) . str_pad(number_format($content['totals']['discount'], 2), 10, ' ', STR_PAD_LEFT) . "\n");
        }
        
        $printer->text(str_pad("TOTAL:", 30) . str_pad(number_format($content['totals']['total'], 2), 10, ' ', STR_PAD_LEFT) . "\n");
        $printer->setEmphasis(false);
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Payment
        $printer->text("Payment: " . strtoupper($content['payment']['method']) . "\n");
        $printer->text("Paid: " . number_format($content['totals']['paid'], 2) . "\n");
        
        if ($content['totals']['change'] > 0) {
            $printer->text("Change: " . number_format($content['totals']['change'], 2) . "\n");
        }
        
        $printer->text("Status: " . strtoupper($content['payment']['status']) . "\n");
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Footer
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        $printer->text($content['footer'] . "\n");
        
        // Print barcode if enabled
        if ($this->print_barcode_on_receipt && !empty($content['sale']['invoice_no'])) {
            $printer->feed();
            $printer->barcode($content['sale']['invoice_no'], EscposPrinter::BARCODE_CODE39);
            $printer->text("\n" . $content['sale']['invoice_no'] . "\n");
        }
        
        // Print QR code if enabled
        if ($this->print_qr_on_receipt) {
            $printer->feed();
            $qrContent = json_encode([
                'invoice' => $content['sale']['invoice_no'],
                'store' => $content['store']['name'],
                'total' => $content['totals']['total'],
                'date' => $content['sale']['date'],
            ]);
            $printer->qrCode($qrContent, EscposPrinter::QR_ECLEVEL_L, 8);
        }
        
        $printer->feed(2);
    }

    /**
     * Print label.
     */
    private function printLabel(EscposPrinter $printer, array $content): void
    {
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        
        if (!empty($content['title'])) {
            $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_HEIGHT);
            $printer->text($content['title'] . "\n");
            $printer->selectPrintMode();
        }
        
        if (!empty($content['product_name'])) {
            $printer->text($content['product_name'] . "\n");
        }
        
        if (!empty($content['price'])) {
            $printer->setEmphasis(true);
            $printer->text("KES " . number_format($content['price'], 2) . "\n");
            $printer->setEmphasis(false);
        }
        
        if (!empty($content['barcode'])) {
            $printer->feed();
            $printer->barcode($content['barcode'], EscposPrinter::BARCODE_CODE39);
            $printer->text("\n" . $content['barcode'] . "\n");
        }
        
        if (!empty($content['batch_number'])) {
            $printer->text("Batch: " . $content['batch_number'] . "\n");
        }
        
        if (!empty($content['expiry_date'])) {
            $printer->text("Exp: " . $content['expiry_date'] . "\n");
        }
        
        $printer->feed(2);
    }

    /**
     * Print report.
     */
    private function printReport(EscposPrinter $printer, array $content): void
    {
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_HEIGHT);
        $printer->text($content['title'] . "\n");
        $printer->selectPrintMode();
        
        $printer->text("Period: " . $content['period'] . "\n");
        $printer->text("Generated: " . now()->format('Y-m-d H:i:s') . "\n");
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        $printer->setJustification(EscposPrinter::JUSTIFY_LEFT);
        
        foreach ($content['sections'] as $section) {
            $printer->setEmphasis(true);
            $printer->text($section['title'] . "\n");
            $printer->setEmphasis(false);
            
            foreach ($section['rows'] as $row) {
                $printer->text($row . "\n");
            }
            
            $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        }
        
        $printer->feed(2);
    }

    /**
     * Print test page.
     */
    private function printTestPage(EscposPrinter $printer): void
    {
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        
        // Print test patterns
        $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_HEIGHT | EscposPrinter::MODE_DOUBLE_WIDTH);
        $printer->text("PRINTER TEST PAGE\n");
        $printer->selectPrintMode();
        
        $printer->text(str_repeat("=", $this->chars_per_line) . "\n");
        
        // Test different fonts and styles
        $printer->setJustification(EscposPrinter::JUSTIFY_LEFT);
        $printer->text("Normal text\n");
        $printer->setEmphasis(true);
        $printer->text("Emphasized text\n");
        $printer->setEmphasis(false);
        $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_HEIGHT);
        $printer->text("Double height text\n");
        $printer->selectPrintMode(EscposPrinter::MODE_DOUBLE_WIDTH);
        $printer->text("Double width text\n");
        $printer->selectPrintMode();
        
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        
        // Test barcode
        $printer->setJustification(EscposPrinter::JUSTIFY_CENTER);
        $printer->text("Barcode Test:\n");
        $printer->barcode("TEST123456", EscposPrinter::BARCODE_CODE39);
        $printer->feed();
        
        // Test QR code
        $printer->text("QR Code Test:\n");
        $printer->qrCode("https://example.com", EscposPrinter::QR_ECLEVEL_L, 8);
        $printer->feed();
        
        // Print configuration
        $printer->setJustification(EscposPrinter::JUSTIFY_LEFT);
        $printer->text(str_repeat("-", $this->chars_per_line) . "\n");
        $printer->text("Printer: " . $this->name . "\n");
        $printer->text("Connection: " . $this->connection_string . "\n");
        $printer->text("Paper: " . $this->paper_size . "\n");
        $printer->text("Chars per line: " . $this->chars_per_line . "\n");
        $printer->text("Test Time: " . now()->format('Y-m-d H:i:s') . "\n");
        
        $printer->feed(3);
    }

    /**
     * Finalize print job.
     */
    private function finalizePrint(EscposPrinter $printer): void
    {
        // Open cash drawer if enabled
        if ($this->auto_open_drawer && $this->has_drawer_kick) {
            $printer->pulse();
        }
        
        // Cut paper if enabled
        if ($this->auto_cut && $this->has_cutter) {
            $printer->cut();
        } else {
            $printer->feed(5);
        }
    }

    /**
     * Update printer status.
     */
    public function updateStatus(string $status, ?string $error = null): void
    {
        $this->update([
            'status' => $status,
            'last_error' => $error,
            'last_used_at' => now(),
        ]);
        
        if ($status === 'error') {
            $this->increment('error_count');
        }
        
        // Log status change
        $this->logAction('status_change', "Status changed to {$status}", [
            'previous_status' => $this->getOriginal('status'),
            'error' => $error,
        ]);
    }

    /**
     * Increment printer statistics.
     */
    public function incrementStats(bool $success): void
    {
        $updates = [
            'total_prints' => DB::raw('total_prints + 1'),
            'print_count' => DB::raw('print_count + 1'),
            'last_used_at' => now(),
        ];
        
        if ($success) {
            $updates['successful_prints'] = DB::raw('successful_prints + 1');
        } else {
            $updates['failed_prints'] = DB::raw('failed_prints + 1');
            $updates['error_count'] = DB::raw('error_count + 1');
        }
        
        $this->update($updates);
        
        // Update paper usage (estimate: 12cm per receipt)
        if ($success) {
            $this->increment('paper_used', 12); // in centimeters
        }
    }

    /**
     * Log printer action.
     */
    public function logAction(string $action, string $description = null, array $details = null): void
    {
        PrinterLog::create([
            'printer_id' => $this->id,
            'user_id' => auth()->id(),
            'action' => $action,
            'description' => $description,
            'details' => $details,
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
        ]);
    }

    /**
     * Log printer error.
     */
    public function logError(string $action, string $error, array $context = null): void
    {
        $this->logAction('error', $error, array_merge($context ?? [], ['action' => $action]));
        
        // Update last error
        $this->update(['last_error' => $error]);
    }

    /**
     * Check printer health.
     */
    public function checkHealth(): array
    {
        try {
            // Test connection
            $testResult = $this->testConnection();
            
            if (!$testResult['success']) {
                return [
                    'healthy' => false,
                    'status' => 'error',
                    'message' => 'Connection test failed',
                    'error' => $testResult['error'],
                ];
            }
            
            // Check paper status (simulated - in real implementation, read from printer)
            $paperStatus = $this->estimatePaperStatus();
            
            // Check head temperature (simulated)
            $temperature = rand(30, 50); // Simulated temperature
            
            // Update printer health metrics
            $this->update([
                'temperature' => $temperature,
                'paper_status' => $paperStatus['status'],
                'estimated_paper_remaining' => $paperStatus['remaining'],
                'head_status' => $temperature > 45 ? 'hot' : 'ok',
                'last_health_check' => now(),
            ]);
            
            return [
                'healthy' => true,
                'status' => 'online',
                'temperature' => $temperature,
                'paper_status' => $paperStatus,
                'success_rate' => $this->success_rate,
                'queue_size' => $this->queue_size,
            ];
            
        } catch (Exception $e) {
            $this->updateStatus('error', $e->getMessage());
            
            return [
                'healthy' => false,
                'status' => 'error',
                'message' => 'Health check failed',
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Estimate paper status.
     */
    private function estimatePaperStatus(): array
    {
        // Simulated paper estimation
        // In real implementation, this would read from printer sensors
        
        $paperUsed = $this->paper_used; // in centimeters
        $paperRollLength = 5000; // 50 meters typical thermal paper roll
        
        $remaining = max(0, $paperRollLength - $paperUsed);
        $percentage = ($remaining / $paperRollLength) * 100;
        
        if ($remaining <= 0) {
            $status = 'out';
        } elseif ($percentage <= 10) {
            $status = 'low';
        } elseif ($percentage <= 30) {
            $status = 'ok';
        } else {
            $status = 'good';
        }
        
        return [
            'status' => $status,
            'remaining' => $remaining,
            'percentage' => round($percentage, 2),
            'estimated_receipts' => floor($remaining / 12), // ~12cm per receipt
        ];
    }

    /**
     * Reset printer statistics.
     */
    public function resetStatistics(): void
    {
        $this->update([
            'total_prints' => 0,
            'successful_prints' => 0,
            'failed_prints' => 0,
            'error_count' => 0,
            'print_count' => 0,
            'paper_used' => 0,
            'success_rate' => 100.00,
            'paper_last_changed' => now(),
        ]);
        
        $this->logAction('statistics_reset', 'Printer statistics reset');
    }

    /**
     * Perform maintenance.
     */
    public function performMaintenance(string $notes = null): array
    {
        try {
            // Clean print head (simulated)
            // In real implementation, send cleaning commands
            
            // Update maintenance records
            $this->update([
                'last_maintenance_at' => now(),
                'next_maintenance_date' => now()->addDays($this->maintenance_interval),
                'maintenance_notes' => $notes,
                'print_count' => 0, // Reset print counter after maintenance
            ]);
            
            // Test print after maintenance
            $testResult = $this->testConnection();
            
            if (!$testResult['success']) {
                throw new Exception('Test print failed after maintenance');
            }
            
            $this->logAction('maintenance', 'Maintenance performed', ['notes' => $notes]);
            
            return [
                'success' => true,
                'message' => 'Maintenance completed successfully',
                'next_maintenance' => $this->next_maintenance_date,
            ];
            
        } catch (Exception $e) {
            $this->logError('maintenance', $e->getMessage());
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Change paper roll.
     */
    public function changePaper(): array
    {
        try {
            $this->update([
                'paper_used' => 0,
                'paper_last_changed' => now(),
                'paper_status' => 'good',
                'estimated_paper_remaining' => 5000, // 50 meters
            ]);
            
            $this->logAction('paper_change', 'Paper roll changed');
            
            return [
                'success' => true,
                'message' => 'Paper roll changed successfully',
                'paper_last_changed' => $this->paper_last_changed,
            ];
            
        } catch (Exception $e) {
            $this->logError('paper_change', $e->getMessage());
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Get printer statistics.
     */
    public function getStatistics($startDate = null, $endDate = null): array
    {
        $startDate = $startDate ? Carbon::parse($startDate) : now()->subMonth();
        $endDate = $endDate ? Carbon::parse($endDate) : now();
        
        $jobs = $this->jobs()
            ->whereBetween('created_at', [$startDate, $endDate])
            ->get();
        
        $logs = $this->logs()
            ->whereBetween('created_at', [$startDate, $endDate])
            ->get();
        
        $dailyStats = [];
        $currentDate = $startDate->copy();
        
        while ($currentDate <= $endDate) {
            $date = $currentDate->format('Y-m-d');
            
            $dailyJobs = $jobs->filter(function ($job) use ($date) {
                return $job->created_at->format('Y-m-d') === $date;
            });
            
            $dailyStats[] = [
                'date' => $date,
                'total_jobs' => $dailyJobs->count(),
                'completed_jobs' => $dailyJobs->where('job_status', 'completed')->count(),
                'failed_jobs' => $dailyJobs->where('job_status', 'failed')->count(),
                'avg_processing_time' => $this->calculateAverageProcessingTime($dailyJobs),
            ];
            
            $currentDate->addDay();
        }
        
        $jobTypes = $jobs->groupBy('job_type')->map(function ($typeJobs, $type) {
            return [
                'type' => $type,
                'count' => $count = $typeJobs->count(),
                'success_rate' => $count > 0 ? 
                    ($typeJobs->where('job_status', 'completed')->count() / $count) * 100 : 0,
            ];
        })->values();
        
        $errorTypes = $logs->where('action', 'error')
            ->groupBy('description')
            ->map(function ($errorLogs, $error) {
                return [
                    'error' => $error,
                    'count' => $errorLogs->count(),
                    'last_occurrence' => $errorLogs->max('created_at'),
                ];
            })->values();
        
        return [
            'period' => [
                'start' => $startDate->format('Y-m-d'),
                'end' => $endDate->format('Y-m-d'),
            ],
            'summary' => [
                'total_jobs' => $jobs->count(),
                'completed_jobs' => $jobs->where('job_status', 'completed')->count(),
                'failed_jobs' => $jobs->where('job_status', 'failed')->count(),
                'success_rate' => $jobs->count() > 0 ? 
                    ($jobs->where('job_status', 'completed')->count() / $jobs->count()) * 100 : 0,
                'total_prints' => $this->total_prints,
                'paper_used_meters' => round($this->paper_used / 100, 2),
                'estimated_cost' => $this->estimated_cost_to_date,
            ],
            'daily_stats' => $dailyStats,
            'job_types' => $jobTypes,
            'error_analysis' => $errorTypes,
            'peak_hours' => $this->calculatePeakHours($jobs),
            'busiest_days' => $this->calculateBusiestDays($jobs),
        ];
    }

    /**
     * Calculate average processing time.
     */
    private function calculateAverageProcessingTime($jobs): ?float
    {
        $completedJobs = $jobs->where('job_status', 'completed')
            ->whereNotNull('processed_at')
            ->whereNotNull('completed_at');
        
        if ($completedJobs->isEmpty()) {
            return null;
        }
        
        $totalTime = $completedJobs->sum(function ($job) {
            return $job->processed_at->diffInSeconds($job->completed_at);
        });
        
        return round($totalTime / $completedJobs->count(), 2);
    }

    /**
     * Calculate peak hours.
     */
    private function calculatePeakHours($jobs): array
    {
        $hourlyCounts = array_fill(0, 24, 0);
        
        $jobs->each(function ($job) use (&$hourlyCounts) {
            $hour = $job->created_at->hour;
            $hourlyCounts[$hour]++;
        });
        
        $peakHours = [];
        for ($hour = 0; $hour < 24; $hour++) {
            $peakHours[] = [
                'hour' => sprintf('%02d:00', $hour),
                'jobs' => $hourlyCounts[$hour],
                'percentage' => $jobs->count() > 0 ? 
                    ($hourlyCounts[$hour] / $jobs->count()) * 100 : 0,
            ];
        }
        
        return $peakHours;
    }

    /**
     * Calculate busiest days.
     */
    private function calculateBusiestDays($jobs): array
    {
        $dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        $dayCounts = array_fill(0, 7, 0);
        
        $jobs->each(function ($job) use (&$dayCounts) {
            $dayOfWeek = $job->created_at->dayOfWeek;
            $dayCounts[$dayOfWeek]++;
        });
        
        $busiestDays = [];
        for ($day = 0; $day < 7; $day++) {
            $busiestDays[] = [
                'day' => $dayNames[$day],
                'jobs' => $dayCounts[$day],
                'percentage' => $jobs->count() > 0 ? 
                    ($dayCounts[$day] / $jobs->count()) * 100 : 0,
            ];
        }
        
        return $busiestDays;
    }

    /**
     * Get printer queue.
     */
    public function getQueue(): array
    {
        $pendingJobs = $this->pendingJobs()
            ->orderBy('priority')
            ->orderBy('created_at')
            ->get();
        
        $recentJobs = $this->jobs()
            ->where('created_at', '>=', now()->subHours(24))
            ->orderBy('created_at', 'desc')
            ->limit(50)
            ->get();
        
        return [
            'pending_count' => $pendingJobs->count(),
            'pending_jobs' => $pendingJobs->map(function ($job) {
                return [
                    'id' => $job->id,
                    'type' => $job->job_type,
                    'priority' => $job->priority,
                    'created_at' => $job->created_at->format('H:i:s'),
                    'metadata' => $job->metadata,
                ];
            }),
            'recent_jobs' => $recentJobs->map(function ($job) {
                return [
                    'id' => $job->id,
                    'type' => $job->job_type,
                    'status' => $job->job_status,
                    'created_at' => $job->created_at->format('H:i:s'),
                    'processed_at' => $job->processed_at?->format('H:i:s'),
                    'completed_at' => $job->completed_at?->format('H:i:s'),
                    'error' => $job->error_message,
                    'metadata' => $job->metadata,
                ];
            }),
        ];
    }

    /**
     * Clear printer queue.
     */
    public function clearQueue(): array
    {
        try {
            $pendingCount = $this->pendingJobs()->count();
            
            $this->pendingJobs()->update([
                'job_status' => 'cancelled',
                'error_message' => 'Queue cleared by user',
            ]);
            
            $this->logAction('queue_clear', "Cleared {$pendingCount} pending jobs");
            
            return [
                'success' => true,
                'message' => "Cleared {$pendingCount} pending jobs",
                'cleared_count' => $pendingCount,
            ];
            
        } catch (Exception $e) {
            $this->logError('queue_clear', $e->getMessage());
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Get printer capabilities.
     */
    public function getCapabilities(): array
    {
        $capabilities = $this->capabilities ?? [];
        
        // Add dynamic capabilities based on printer type
        $dynamicCapabilities = [
            'connection_types' => ['network', 'usb', 'serial', 'bluetooth', 'file'],
            'paper_sizes' => ['80mm', '58mm', 'A4', 'letter'],
            'barcode_types' => ['CODE39', 'CODE128', 'EAN13', 'EAN8', 'UPC-A', 'UPC-E'],
            'qr_sizes' => [1, 2, 3, 4, 5, 6, 7, 8],
            'fonts' => ['Font A', 'Font B', 'Font C'],
            'character_encodings' => ['CP850', 'CP437', 'CP858', 'CP866', 'CP1252', 'UTF-8'],
        ];
        
        return array_merge($capabilities, $dynamicCapabilities);
    }

    /**
     * Validate printer configuration.
     */
    public function validateConfiguration(): array
    {
        $errors = [];
        
        // Validate connection settings
        switch ($this->connection_type) {
            case 'network':
                if (empty($this->ip_address)) {
                    $errors[] = 'IP address is required for network printers';
                }
                if (empty($this->port)) {
                    $errors[] = 'Port is required for network printers';
                }
                break;
                
            case 'usb':
            case 'serial':
                if (empty($this->device_path)) {
                    $errors[] = 'Device path is required for USB/Serial printers';
                }
                break;
                
            case 'bluetooth':
                if (empty($this->bluetooth_address)) {
                    $errors[] = 'Bluetooth address is required';
                }
                break;
                
            case 'file':
                if (empty($this->file_path)) {
                    $errors[] = 'File path is required';
                }
                break;
        }
        
        // Validate paper size
        $validPaperSizes = ['80mm', '58mm', 'A4', 'letter'];
        if (!in_array($this->paper_size, $validPaperSizes)) {
            $errors[] = "Invalid paper size. Must be one of: " . implode(', ', $validPaperSizes);
        }
        
        // Validate print density
        if ($this->print_density < 0 || $this->print_density > 15) {
            $errors[] = 'Print density must be between 0 and 15';
        }
        
        // Validate print speed
        if ($this->print_speed < 1 || $this->print_speed > 5) {
            $errors[] = 'Print speed must be between 1 and 5';
        }
        
        return [
            'valid' => empty($errors),
            'errors' => $errors,
        ];
    }

    /**
     * Export printer configuration.
     */
    public function exportConfiguration(): array
    {
        return [
            'basic' => [
                'name' => $this->name,
                'alias' => $this->alias,
                'description' => $this->description,
                'connection_type' => $this->connection_type,
                'connection_string' => $this->connection_string,
                'paper_size' => $this->paper_size,
                'chars_per_line' => $this->chars_per_line,
            ],
            'connection' => [
                'ip_address' => $this->ip_address,
                'port' => $this->port,
                'device_path' => $this->device_path,
                'bluetooth_address' => $this->bluetooth_address,
                'file_path' => $this->file_path,
                'timeout' => $this->timeout,
                'retry_count' => $this->retry_count,
            ],
            'settings' => [
                'auto_cut' => $this->auto_cut,
                'auto_open_drawer' => $this->auto_open_drawer,
                'print_density' => $this->print_density,
                'print_speed' => $this->print_speed,
                'encoding' => $this->encoding,
                'margins' => [
                    'top' => $this->margin_top,
                    'bottom' => $this->margin_bottom,
                    'left' => $this->margin_left,
                    'right' => $this->margin_right,
                ],
            ],
            'receipt' => [
                'header_template' => $this->header_template,
                'footer_template' => $this->footer_template,
                'print_store_logo' => $this->print_store_logo,
                'print_barcode_on_receipt' => $this->print_barcode_on_receipt,
                'print_qr_on_receipt' => $this->print_qr_on_receipt,
            ],
            'status' => [
                'is_active' => $this->is_active,
                'is_default' => $this->is_default,
                'status' => $this->status,
                'health_status' => $this->health_status,
                'last_used' => $this->last_used_at,
                'print_count' => $this->print_count,
                'success_rate' => $this->success_rate,
            ],
            'statistics' => [
                'total_prints' => $this->total_prints,
                'successful_prints' => $this->successful_prints,
                'failed_prints' => $this->failed_prints,
                'paper_used_meters' => round($this->paper_used / 100, 2),
                'estimated_cost' => $this->estimated_cost_to_date,
            ],
            'maintenance' => [
                'last_maintenance' => $this->last_maintenance_at,
                'next_maintenance' => $this->next_maintenance_date,
                'maintenance_interval' => $this->maintenance_interval,
                'needs_maintenance' => $this->needs_maintenance,
            ],
            'capabilities' => $this->getCapabilities(),
        ];
    }

    /**
     * Import printer configuration.
     */
    public static function importConfiguration(array $config): Printer
    {
        $printer = new self();
        
        // Basic information
        $printer->name = $config['basic']['name'] ?? 'Imported Printer';
        $printer->alias = $config['basic']['alias'] ?? null;
        $printer->description = $config['basic']['description'] ?? null;
        $printer->connection_type = $config['basic']['connection_type'] ?? 'network';
        $printer->paper_size = $config['basic']['paper_size'] ?? '80mm';
        $printer->chars_per_line = $config['basic']['chars_per_line'] ?? 42;
        
        // Connection settings
        $printer->ip_address = $config['connection']['ip_address'] ?? null;
        $printer->port = $config['connection']['port'] ?? 9100;
        $printer->device_path = $config['connection']['device_path'] ?? null;
        $printer->timeout = $config['connection']['timeout'] ?? 30;
        $printer->retry_count = $config['connection']['retry_count'] ?? 3;
        
        // Print settings
        $printer->auto_cut = $config['settings']['auto_cut'] ?? true;
        $printer->auto_open_drawer = $config['settings']['auto_open_drawer'] ?? false;
        $printer->print_density = $config['settings']['print_density'] ?? 15;
        $printer->print_speed = $config['settings']['print_speed'] ?? 3;
        $printer->encoding = $config['settings']['encoding'] ?? 'CP850';
        
        // Margins
        $margins = $config['settings']['margins'] ?? [];
        $printer->margin_top = $margins['top'] ?? 0;
        $printer->margin_bottom = $margins['bottom'] ?? 0;
        $printer->margin_left = $margins['left'] ?? 0;
        $printer->margin_right = $margins['right'] ?? 0;
        
        // Receipt settings
        $printer->header_template = $config['receipt']['header_template'] ?? null;
        $printer->footer_template = $config['receipt']['footer_template'] ?? null;
        $printer->print_store_logo = $config['receipt']['print_store_logo'] ?? false;
        $printer->print_barcode_on_receipt = $config['receipt']['print_barcode_on_receipt'] ?? true;
        $printer->print_qr_on_receipt = $config['receipt']['print_qr_on_receipt'] ?? true;
        
        // Status
        $printer->is_active = $config['status']['is_active'] ?? true;
        $printer->is_default = $config['status']['is_default'] ?? false;
        
        // Capabilities
        $printer->capabilities = $config['capabilities'] ?? [];
        
        return $printer;
    }

    /**
     * Get validation rules.
     */
    public static function getValidationRules($printerId = null): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'alias' => 'nullable|string|max:100',
            'description' => 'nullable|string|max:500',
            'connection_type' => 'required|in:network,usb,serial,bluetooth,file,windows',
            'paper_size' => 'required|in:80mm,58mm,A4,letter',
            'chars_per_line' => 'required|integer|min:20|max:100',
            
            // Connection validation
            'ip_address' => 'required_if:connection_type,network|nullable|ip',
            'port' => 'required_if:connection_type,network|nullable|integer|min:1|max:65535',
            'device_path' => 'required_if:connection_type,usb,serial,windows|nullable|string|max:255',
            'bluetooth_address' => 'required_if:connection_type,bluetooth|nullable|string|max:100',
            'file_path' => 'required_if:connection_type,file|nullable|string|max:255',
            
            // Settings validation
            'auto_cut' => 'boolean',
            'auto_open_drawer' => 'boolean',
            'print_density' => 'integer|min:0|max:15',
            'print_speed' => 'integer|min:1|max:5',
            'encoding' => 'required|string|max:50',
            
            // Margins
            'margin_top' => 'integer|min:0|max:100',
            'margin_bottom' => 'integer|min:0|max:100',
            'margin_left' => 'integer|min:0|max:100',
            'margin_right' => 'integer|min:0|max:100',
            
            // Status
            'is_active' => 'boolean',
            'is_default' => 'boolean',
            'location' => 'nullable|string|max:100',
            'department' => 'nullable|string|max:100',
            
            // Maintenance
            'maintenance_interval' => 'nullable|integer|min:1|max:365',
            
            // Cost
            'purchase_cost' => 'nullable|numeric|min:0',
            'operational_cost_per_print' => 'nullable|numeric|min:0',
        ];
        
        return $rules;
    }

    /**
     * Get validation messages.
     */
    public static function getValidationMessages(): array
    {
        return [
            'name.required' => 'Printer name is required',
            'connection_type.required' => 'Connection type is required',
            'connection_type.in' => 'Invalid connection type',
            'ip_address.required_if' => 'IP address is required for network printers',
            'ip_address.ip' => 'Invalid IP address format',
            'port.required_if' => 'Port is required for network printers',
            'device_path.required_if' => 'Device path is required for USB/Serial printers',
            'bluetooth_address.required_if' => 'Bluetooth address is required',
            'file_path.required_if' => 'File path is required',
            'paper_size.required' => 'Paper size is required',
            'paper_size.in' => 'Invalid paper size',
            'chars_per_line.required' => 'Characters per line is required',
            'encoding.required' => 'Character encoding is required',
        ];
    }
}