<?php

class ChainPay_License {
    
    private $table_name;
    
    public function __construct() {
        global $wpdb;
        $this->table_name = $wpdb->prefix . 'chainpay_licenses';
    }
    
    public function generate_license_key($prefix = 'CPL') {
        $key = $prefix . '-' . strtoupper(wp_generate_uuid4());
        return $key;
    }
    
    public function create($data) {
        global $wpdb;
        
        $defaults = array(
            'license_key' => $this->generate_license_key(),
            'user_id' => null,
            'user_email' => '',
            'user_domain' => '',
            'plan_id' => null,
            'status' => 'active',
            'activation_date' => current_time('mysql'),
            'expiration_date' => null,
            'max_domains' => 1,
            'max_users' => 1,
            'metadata' => ''
        );
        
        $data = wp_parse_args($data, $defaults);
        
        $result = $wpdb->insert(
            $this->table_name,
            $data,
            array('%s', '%d', '%s', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%s')
        );
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to create license');
        }
        
        return $wpdb->insert_id;
    }
    
    public function get($license_id) {
        global $wpdb;
        return $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$this->table_name} WHERE id = %d",
            $license_id
        ));
    }
    
    public function get_by_key($license_key) {
        global $wpdb;
        return $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$this->table_name} WHERE license_key = %s",
            $license_key
        ));
    }
    
    public function update($license_id, $data) {
        global $wpdb;
        return $wpdb->update(
            $this->table_name,
            $data,
            array('id' => $license_id),
            $this->get_format($data),
            array('%d')
        );
    }
    
    public function delete($license_id) {
        global $wpdb;
        return $wpdb->delete(
            $this->table_name,
            array('id' => $license_id),
            array('%d')
        );
    }
    
    public function validate($license_key, $domain = '') {
        $license = $this->get_by_key($license_key);
        
        if (!$license) {
            return new WP_Error('invalid_license', 'License key not found');
        }
        
        if ($license->status !== 'active') {
            return new WP_Error('inactive_license', 'License is not active');
        }
        
        if ($license->expiration_date && strtotime($license->expiration_date) < time()) {
            return new WP_Error('expired_license', 'License has expired');
        }
        
        if ($domain && $license->user_domain && $license->user_domain !== $domain) {
            $registered_domains = maybe_unserialize($license->metadata);
            if (!is_array($registered_domains) || !in_array($domain, $registered_domains['domains'] ?? array())) {
                return new WP_Error('domain_mismatch', 'License not valid for this domain');
            }
        }
        
        return $license;
    }
    
    public function activate($license_key, $domain, $user_email) {
        $license = $this->get_by_key($license_key);
        
        if (!$license) {
            return new WP_Error('invalid_license', 'License key not found');
        }
        
        if ($license->status === 'active') {
            return new WP_Error('already_active', 'License is already active');
        }
        
        $metadata = maybe_unserialize($license->metadata);
        if (!is_array($metadata)) {
            $metadata = array();
        }
        
        if (empty($metadata['domains'])) {
            $metadata['domains'] = array();
        }
        
        if ($domain && !in_array($domain, $metadata['domains'])) {
            if (count($metadata['domains']) >= $license->max_domains) {
                return new WP_Error('domain_limit', 'Maximum domain limit reached');
            }
            $metadata['domains'][] = $domain;
        }
        
        $this->update($license->id, array(
            'status' => 'active',
            'user_email' => $user_email,
            'user_domain' => $domain ?: $license->user_domain,
            'activation_date' => current_time('mysql'),
            'metadata' => maybe_serialize($metadata)
        ));
        
        return $this->get($license->id);
    }
    
    public function deactivate($license_key, $domain = '') {
        $license = $this->get_by_key($license_key);
        
        if (!$license) {
            return new WP_Error('invalid_license', 'License key not found');
        }
        
        $metadata = maybe_unserialize($license->metadata);
        if (is_array($metadata) && !empty($metadata['domains']) && $domain) {
            $metadata['domains'] = array_filter($metadata['domains'], function($d) use ($domain) {
                return $d !== $domain;
            });
        }
        
        $this->update($license->id, array(
            'status' => 'inactive',
            'metadata' => maybe_serialize($metadata)
        ));
        
        return true;
    }
    
    public function get_all($args = array()) {
        global $wpdb;
        
        $defaults = array(
            'status' => '',
            'plan_id' => null,
            'user_id' => null,
            'orderby' => 'created_at',
            'order' => 'DESC',
            'limit' => 20,
            'offset' => 0
        );
        
        $args = wp_parse_args($args, $defaults);
        
        $where = array('1=1');
        $values = array();
        
        if (!empty($args['status'])) {
            $where[] = 'status = %s';
            $values[] = $args['status'];
        }
        
        if ($args['plan_id']) {
            $where[] = 'plan_id = %d';
            $values[] = $args['plan_id'];
        }
        
        if ($args['user_id']) {
            $where[] = 'user_id = %d';
            $values[] = $args['user_id'];
        }
        
        $where_clause = implode(' AND ', $where);
        $orderby = sanitize_sql_orderby($args['orderby'] . ' ' . $args['order']);
        
        $sql = "SELECT * FROM {$this->table_name} WHERE {$where_clause} ORDER BY {$orderby} LIMIT %d OFFSET %d";
        $values[] = $args['limit'];
        $values[] = $args['offset'];
        
        return $wpdb->get_results($wpdb->prepare($sql, $values));
    }
    
    public function count($args = array()) {
        global $wpdb;
        
        $defaults = array('status' => '');
        $args = wp_parse_args($args, $defaults);
        
        $where = '1=1';
        $values = array();
        
        if (!empty($args['status'])) {
            $where .= ' AND status = %s';
            $values[] = $args['status'];
        }
        
        $sql = "SELECT COUNT(*) FROM {$this->table_name} WHERE {$where}";
        
        if (!empty($values)) {
            return $wpdb->get_var($wpdb->prepare($sql, $values));
        }
        
        return $wpdb->get_var($sql);
    }
    
    private function get_format($data) {
        $format = array();
        foreach ($data as $key => $value) {
            if (is_int($value)) {
                $format[] = '%d';
            } elseif (is_float($value)) {
                $format[] = '%f';
            } else {
                $format[] = '%s';
            }
        }
        return $format;
    }
}
