<?php

namespace AIPT\Api\AutomationJobs\Models;

/**
 * JobLog Model
 * 
 * Represents a job log entry with validation and data management
 * Following Single Responsibility Principle
 * 
 * @since 2.3.0
 */
class JobLog {
    
    /**
     * Log ID
     * @var int
     */
    public $id;
    
    /**
     * Job ID
     * @var int
     */
    public $job_id;
    
    /**
     * Log level (info, warning, error, debug)
     * @var string
     */
    public $level;
    
    /**
     * Log message
     * @var string
     */
    public $message;
    
    /**
     * Additional context data (JSON)
     * @var array
     */
    public $context;
    
    /**
     * Created datetime
     * @var string
     */
    public $created_at;
    
    /**
     * Valid log levels
     */
    const VALID_LEVELS = ['info', 'warning', 'error', 'debug'];
    
    /**
     * Log level priorities (for filtering)
     */
    const LEVEL_PRIORITIES = [
        'debug' => 0,
        'info' => 1,
        'warning' => 2,
        'error' => 3
    ];
    
    /**
     * Constructor
     * 
     * @param array $data Log data
     */
    public function __construct($data = []) {
        if (!empty($data)) {
            $this->populate($data);
        }
    }
    
    /**
     * Populate object with data
     * 
     * @param array $data Log data
     */
    public function populate($data) {
        $this->id = isset($data['id']) ? (int) $data['id'] : null;
        $this->job_id = isset($data['job_id']) ? (int) $data['job_id'] : null;
        $this->level = isset($data['level']) ? sanitize_text_field($data['level']) : 'info';
        $this->message = isset($data['message']) ? sanitize_textarea_field($data['message']) : '';
        $this->context = isset($data['context']) ? $this->parseJsonField($data['context']) : [];
        $this->created_at = isset($data['created_at']) ? $data['created_at'] : current_time('mysql');
    }
    
    /**
     * Parse JSON field
     * 
     * @param mixed $value Field value
     * @return array
     */
    private function parseJsonField($value) {
        if (is_string($value)) {
            $decoded = json_decode($value, true);
            return json_last_error() === JSON_ERROR_NONE ? $decoded : [];
        }
        return is_array($value) ? $value : [];
    }
    
    /**
     * Validate log data
     * 
     * @return array Validation errors
     */
    public function validate() {
        $errors = [];
        

        if (empty($this->job_id)) {
            $errors['job_id'] = 'Job ID is required';
        }
        
        if (empty($this->message)) {
            $errors['message'] = 'Log message is required';
        }
        
        if (!in_array($this->level, self::VALID_LEVELS)) {
            $errors['level'] = 'Invalid log level. Must be one of: ' . implode(', ', self::VALID_LEVELS);
        }
        
        return $errors;
    }
    
    /**
     * Convert to array for database storage
     * 
     * @return array
     */
    public function toArray() {
        return [
            'id' => $this->id,
            'job_id' => $this->job_id,
            'level' => $this->level,
            'message' => $this->message,
            'context' => !empty($this->context) ? wp_json_encode($this->context) : null,
            'created_at' => $this->created_at
        ];
    }
    
    /**
     * Get log level priority
     * 
     * @return int
     */
    public function getLevelPriority() {
        return self::LEVEL_PRIORITIES[$this->level] ?? 0;
    }
    
    /**
     * Check if log is error level
     * 
     * @return bool
     */
    public function isError() {
        return $this->level === 'error';
    }
    
    /**
     * Check if log is warning level
     * 
     * @return bool
     */
    public function isWarning() {
        return $this->level === 'warning';
    }
    
    /**
     * Check if log is info level
     * 
     * @return bool
     */
    public function isInfo() {
        return $this->level === 'info';
    }
    
    /**
     * Check if log is debug level
     * 
     * @return bool
     */
    public function isDebug() {
        return $this->level === 'debug';
    }
    
    /**
     * Format log message with context
     * 
     * @return string
     */
    public function getFormattedMessage() {
        $formatted = $this->message;
        
        if (!empty($this->context)) {
            $formatted .= ' | Context: ' . wp_json_encode($this->context);
        }
        
        return $formatted;
    }
    
    /**
     * Create info log
     * 
     * @param int $job_id Job ID
     * @param string $message Log message
     * @param array $context Additional context
     * @return JobLog
     */
    public static function info($job_id, $message, $context = []) {
        return new self([
            'job_id' => $job_id,
            'level' => 'info',
            'message' => $message,
            'context' => $context
        ]);
    }
    
    /**
     * Create warning log
     * 
     * @param int $job_id Job ID
     * @param string $message Log message
     * @param array $context Additional context
     * @return JobLog
     */
    public static function warning($job_id, $message, $context = []) {
        return new self([
            'job_id' => $job_id,
            'level' => 'warning',
            'message' => $message,
            'context' => $context
        ]);
    }
    
    /**
     * Create error log
     * 
     * @param int $job_id Job ID
     * @param string $message Log message
     * @param array $context Additional context
     * @return JobLog
     */
    public static function error($job_id, $message, $context = []) {
        return new self([
            'job_id' => $job_id,
            'level' => 'error',
            'message' => $message,
            'context' => $context
        ]);
    }
    
    /**
     * Create debug log
     * 
     * @param int $job_id Job ID
     * @param string $message Log message
     * @param array $context Additional context
     * @return JobLog
     */
    public static function debug($job_id, $message, $context = []) {
        return new self([
            'job_id' => $job_id,
            'level' => 'debug',
            'message' => $message,
            'context' => $context
        ]);
    }
}
