<?php
/**
 * Quote Log Model
 *
 * @package     EasyInvoice
 * @author      Your Name
 * @copyright   Copyright (c) 2023, Your Company
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.0.0
 */

namespace EasyInvoice\Models;

/**
 * Quote Log Model
 *
 * Represents a log entry for quote activities.
 *
 * @since 1.0.0
 */
class QuoteLog {
    /**
     * Log ID
     *
     * @var int
     */
    private $id;

    /**
     * Dynamic data storage for all fields
     *
     * @var array
     */
    private $data = [];

    /**
     * Modified flag
     *
     * @var bool
     */
    private $is_modified = false;

    /**
     * Constructor
     *
     * @since 1.0.0
     * @param array $data Log data
     */
    public function __construct(array $data = []) {
        $this->id = $data['id'] ?? 0;
        $this->data = $data;
    }

    /**
     * Magic getter for dynamic properties
     *
     * @since 1.0.0
     * @param string $name Property name
     * @return mixed Property value or null if not found
     */
    public function __get($name) {
        return $this->data[$name] ?? null;
    }

    /**
     * Magic setter for dynamic properties
     *
     * @since 1.0.0
     * @param string $name Property name
     * @param mixed $value Property value
     */
    public function __set($name, $value) {
        $this->data[$name] = $value;
        $this->is_modified = true;
    }

    /**
     * Magic isset for dynamic properties
     *
     * @since 1.0.0
     * @param string $name Property name
     * @return bool True if property exists, false otherwise
     */
    public function __isset($name) {
        return isset($this->data[$name]);
    }

    /**
     * Magic unset for dynamic properties
     *
     * @since 1.0.0
     * @param string $name Property name
     */
    public function __unset($name) {
        unset($this->data[$name]);
        $this->is_modified = true;
    }

    /**
     * Dynamic getter method
     *
     * @since 1.0.0
     * @param string $name Method name
     * @param array $arguments Method arguments
     * @return mixed
     */
    public function __call($name, $arguments) {
        // Handle getter methods (getFieldName)
        if (strpos($name, 'get') === 0) {
            $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'get' prefix
            return $this->__get($field_name);
    }

        // Handle setter methods (setFieldName)
        if (strpos($name, 'set') === 0) {
            $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'set' prefix
            $value = $arguments[0] ?? null;
            $this->__set($field_name, $value);
            return null;
    }

        // Handle isset methods (isFieldName)
        if (strpos($name, 'is') === 0) {
            $field_name = $this->camelCaseToSnakeCase(substr($name, 2)); // Remove 'is' prefix
            return (bool) $this->__get($field_name);
    }

        // Handle has methods (hasFieldName)
        if (strpos($name, 'has') === 0) {
            $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'has' prefix
            return !empty($this->__get($field_name));
        }
        
        throw new \BadMethodCallException("Method $name does not exist");
    }

    /**
     * Convert camelCase to snake_case
     *
     * @since 1.0.0
     * @param string $camelCase
     * @return string
     */
    private function camelCaseToSnakeCase($camelCase) {
        return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $camelCase));
    }

    /**
     * Get log ID
     *
     * @since 1.0.0
     * @return int
     */
    public function getId(): int {
        return $this->id;
    }

    /**
     * Set log ID
     *
     * @since 1.0.0
     * @param int $id
     */
    public function setId(int $id): void {
        $this->id = $id;
        $this->is_modified = true;
    }

    /**
     * Convert to array
     *
     * @since 1.0.0
     * @return array
     */
    public function toArray(): array {
        return $this->data;
    }

    /**
     * Get formatted date
     *
     * @since 1.0.0
     * @return string
     */
    public function getFormattedDate(): string {
        if (empty($this->created_date)) {
            return '';
        }
        return date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($this->created_date));
    }

    /**
     * Get action label
     *
     * @since 1.0.0
     * @return string
     */
    public function getActionLabel(): string {
        $labels = [
            'created' => __('Created', 'easy-invoice'),
            'updated' => __('Updated', 'easy-invoice'),
            'accepted' => __('Accepted', 'easy-invoice'),
            'declined' => __('Declined', 'easy-invoice'),
            'sent' => __('Sent', 'easy-invoice'),
            'viewed' => __('Viewed', 'easy-invoice'),
            'status_changed' => __('Status Changed', 'easy-invoice'),
            'converted_to_invoice' => __('Converted to Invoice', 'easy-invoice'),
            'duplicated_to_invoice' => __('Duplicated to Invoice', 'easy-invoice'),
            'deleted' => __('Deleted', 'easy-invoice'),
            'restored' => __('Restored', 'easy-invoice'),
        ];

        return $labels[$this->action] ?? ucfirst($this->action);
    }

    /**
     * Get additional data as array
     *
     * @since 1.0.0
     * @return array
     */
    public function getAdditionalDataArray(): array {
        if (empty($this->additional_data)) {
            return [];
        }
        
        $data = json_decode($this->additional_data, true);
        return is_array($data) ? $data : [];
    }
} 