<?php

if (!defined('ABSPATH')) {
    exit;
}

class ShopCentral_Automation_Engine
{
    private $namespace;
    private $option_key = 'shopcentral_automation_rules';
    private $log_key = 'shopcentral_automation_logs';

    public function __construct($namespace = 'shopcentral/v1')
    {
        $this->namespace = $namespace;
        add_action('rest_api_init', [$this, 'register_routes']);
        
        // Hooks for reactive rules
        add_action('woocommerce_product_set_stock', [$this, 'handle_stock_change'], 20, 1);
        add_action('transition_post_status', [$this, 'handle_product_published'], 10, 3);

        // Schedule cron for scheduled rules (revenue)
        if (!wp_next_scheduled('shopcentral_daily_automation_cron')) {
            wp_schedule_event(time(), 'daily', 'shopcentral_daily_automation_cron');
        }
        add_action('shopcentral_daily_automation_cron', [$this, 'handle_daily_checks']);
    }

    public function register_routes()
    {
        register_rest_route($this->namespace, '/api/store-manager/automation/rules', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_rules'],
                'permission_callback' => [$this, 'check_permission'],
            ],
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'save_rules'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);

        register_rest_route($this->namespace, '/api/store-manager/automation/logs', [
            'methods' => WP_REST_Server::READABLE,
            'callback' => [$this, 'get_logs'],
            'permission_callback' => [$this, 'check_permission'],
        ]);
    }

    public function check_permission()
    {
        return current_user_can('manage_options');
    }

    public function get_rules($request)
    {
        $rules = get_option($this->option_key, []);
        return new WP_REST_Response(['rules' => $rules], 200);
    }

    public function save_rules($request)
    {
        $params = $request->get_json_params();
        if (isset($params['rules'])) {
            update_option($this->option_key, $params['rules']);
            return new WP_REST_Response(['message' => 'Rules saved successfully', 'rules' => $params['rules']], 200);
        }
        return new WP_Error('invalid_data', 'No rules provided', ['status' => 400]);
    }

    public function get_logs($request)
    {
        $logs = get_option($this->log_key, []);
        // Only keep last 50 logs
        if (count($logs) > 50) {
            $logs = array_slice($logs, 0, 50);
            update_option($this->log_key, $logs);
        }
        return new WP_REST_Response(['logs' => $logs], 200);
    }

    private function log_action($rule_name, $message)
    {
        $logs = get_option($this->log_key, []);
        array_unshift($logs, [
            'time' => current_time('mysql'),
            'rule' => $rule_name,
            'message' => $message
        ]);
        if (count($logs) > 50) {
            $logs = array_slice($logs, 0, 50);
        }
        update_option($this->log_key, $logs);
    }

    private function get_active_rules($trigger)
    {
        $rules = get_option($this->option_key, []);
        $filtered = array_filter($rules, function ($rule) use ($trigger) {
            return !empty($rule['is_active']) && $rule['trigger'] === $trigger;
        });
        
        // Sort by priority DESC
        usort($filtered, function($a, $b) {
            $pa = (int)($a['priority'] ?? 0);
            $pb = (int)($b['priority'] ?? 0);
            return $pb - $pa;
        });
        return $filtered;
    }

    private function is_product_in_target($product_id, $rule)
    {
        $type = $rule['target_type'] ?? 'global';
        if ($type === 'global') return true;

        $target_ids = array_map(function($i) { return (int) ($i['id'] ?? 0); }, $rule['target_items'] ?? []);
        if (empty($target_ids)) return false;

        if ($type === 'product') {
            return in_array($product_id, $target_ids);
        }

        if ($type === 'category') {
            $terms = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']);
            if (is_wp_error($terms)) return false;
            return count(array_intersect($terms, $target_ids)) > 0;
        }

        return false;
    }

    // TRIGGER: Stock Changed
    public function handle_stock_change($product)
    {
        if (!is_object($product)) {
            $product = wc_get_product($product);
        }
        if (!$product) return;
        
        $product_id = $product->get_id();
        $stock = $product->get_stock_quantity();
        if ($stock === null) return;

        $all_stock_rules = array_merge(
            $this->get_active_rules('stock_below'),
            $this->get_active_rules('stock_time_hybrid'),
            $this->get_active_rules('stock_tiers')
        );

        // Sort combined rules by priority DESC
        usort($all_stock_rules, function($a, $b) {
            return ((int)($b['priority'] ?? 0)) - ((int)($a['priority'] ?? 0));
        });

        foreach ($all_stock_rules as $rule) {
            if (!$this->is_product_in_target($product_id, $rule)) continue;

            $trigger = $rule['trigger'];
            $threshold = (int) ($rule['condition_value'] ?? 5);

            $apply_once = !empty($rule['apply_once']);
            $meta_key = '_sc_rule_applied_' . $rule['id'];
            if ($apply_once && get_post_meta($product_id, $meta_key, true)) {
                continue; // Skip if already applied
            }

            $should_execute = false;

            if ($trigger === 'stock_below') {
                if ($stock <= $threshold) $should_execute = true;
            } elseif ($trigger === 'stock_time_hybrid') {
                if ($stock <= $threshold) {
                    $days = (int) ($rule['time_value'] ?? 7);
                    
                    global $wpdb;
                    $order_items_table = $wpdb->prefix . 'woocommerce_order_items';
                    $order_itemmeta_table = $wpdb->prefix . 'woocommerce_order_itemmeta';
                    $posts_table = $wpdb->prefix . 'posts';
                    
                    $query = $wpdb->prepare("
                        SELECT p.post_date FROM {$posts_table} p
                        JOIN {$order_items_table} oi ON p.ID = oi.order_id
                        JOIN {$order_itemmeta_table} oim ON oi.order_item_id = oim.order_item_id
                        WHERE p.post_type = 'shop_order' AND p.post_status IN ('wc-completed', 'wc-processing')
                        AND oim.meta_key = '_product_id' AND oim.meta_value = %d
                        ORDER BY p.post_date DESC LIMIT 1
                    ", $product_id);
                    $last_sold_date = $wpdb->get_var($query);

                    if (!$last_sold_date) {
                        $created = strtotime($product->get_date_created() ? $product->get_date_created()->date('Y-m-d H:i:s') : 'now');
                        if (time() - $created > ($days * 86400)) {
                            $should_execute = true;
                        }
                    } else {
                        if (strtotime($last_sold_date) < time() - ($days * 86400)) {
                            $should_execute = true;
                        }
                    }
                }
            } elseif ($trigger === 'stock_tiers') {
                $should_execute = true;
            }

            if ($should_execute) {
                $this->execute_action($rule, [
                    'product_id' => $product_id,
                    'product_name' => $product->get_name(),
                    'stock' => $stock,
                    'threshold_start' => $threshold // passing initial limit to calculate steps
                ]);

                if ($apply_once) {
                    update_post_meta($product_id, $meta_key, time());
                }
            }
        }
    }

    // TRIGGER: Product transitioned to Published for the first time
    public function handle_product_published($new_status, $old_status, $post)
    {
        if ($post->post_type !== 'product') return;
        
        // Only trigger on the very first time it becomes published! 
        // Handles "Add New" clicks which start as auto-drafts and skip woocommerce_new_product hooks.
        if ($new_status === 'publish' && $old_status !== 'publish') {
            $this->handle_new_product($post->ID);
        }
    }

    private function handle_new_product($product_id)
    {
        $product = wc_get_product($product_id);
        if (!$product) return;

        $rules = $this->get_active_rules('new_product');
        foreach ($rules as $rule) {
            if (!$this->is_product_in_target($product_id, $rule)) continue;
            
            $this->execute_action($rule, [
                'product_id' => $product->get_id(),
                'product_name' => $product->get_name()
            ]);
        }
    }

    // TRIGGER: Daily Cron (Revenue Drops)
    public function handle_daily_checks()
    {
        $rules = $this->get_active_rules('revenue_drop');
        if (empty($rules)) return;

        // Calculate revenue for yesterday vs day before yesterday
        $yesterday_start = date('Y-m-d', strtotime('-1 days'));
        $day_before_start = date('Y-m-d', strtotime('-2 days'));

        $orders_yesterday = wc_get_orders(['date_created' => $yesterday_start . '...' . $yesterday_start, 'limit' => -1, 'status' => ['wc-completed']]);
        $orders_day_before = wc_get_orders(['date_created' => $day_before_start . '...' . $day_before_start, 'limit' => -1, 'status' => ['wc-completed']]);

        $rev_yesterday = array_reduce($orders_yesterday, function($carry, $order) { return $carry + (float)$order->get_total(); }, 0);
        $rev_day_before = array_reduce($orders_day_before, function($carry, $order) { return $carry + (float)$order->get_total(); }, 0);

        if ($rev_day_before > 0) {
            $drop_pct = (($rev_day_before - $rev_yesterday) / $rev_day_before) * 100;
        } else {
            $drop_pct = 0;
        }

        foreach ($rules as $rule) {
            $threshold = (float) ($rule['condition_value'] ?? 20);
            if ($drop_pct >= $threshold) {
                $this->execute_action($rule, [
                    'drop_pct' => round($drop_pct, 1),
                    'rev_yesterday' => $rev_yesterday,
                    'rev_day_before' => $rev_day_before
                ]);
            }
        }
    }

    private function execute_action($rule, $context)
    {
        $action = $rule['action'];
        $val = $rule['action_value'] ?? '';

        switch ($action) {
            case 'send_email':
                $to = !empty($val) ? $val : get_option('admin_email');
                $subject = "ShopCentral Alert: " . $rule['name'];
                
                // Build a human-readable message
                $msg = "Hello,\n\n";
                $msg .= "This is an automated alert from ShopCentral because the rule '{$rule['name']}' was triggered.\n\n";
                $msg .= "Details:\n";
                $msg .= "------------------------------------------------------\n";
                
                if (isset($context['product_name'])) {
                    $msg .= "Product: " . $context['product_name'] . " (ID: " . $context['product_id'] . ")\n";
                    if (isset($context['stock'])) {
                        $msg .= "Current Stock: " . $context['stock'] . "\n";
                    }
                } elseif (isset($context['drop_pct'])) {
                    $msg .= "Revenue Drop: " . $context['drop_pct'] . "%\n";
                    
                    // Format currency nicely
                    $currency = get_woocommerce_currency_symbol();
                    $msg .= "Yesterday's Revenue: " . html_entity_decode($currency) . number_format_i18n($context['rev_yesterday'], 2) . "\n";
                    $msg .= "Previous Day's Revenue: " . html_entity_decode($currency) . number_format_i18n($context['rev_day_before'], 2) . "\n";
                } else {
                    foreach ($context as $k => $v) {
                        $msg .= ucwords(str_replace('_', ' ', $k)) . ": " . $v . "\n";
                    }
                }
                
                $msg .= "------------------------------------------------------\n\n";
                $msg .= "Please review your store dashboard for more details.\n";
                $msg .= "\nBest,\nShopCentral Automation Engine";
                
                wp_mail($to, $subject, $msg);
                $this->log_action($rule['name'], "Emailed $to regarding trigger.");
                break;
            
            case 'notify':
                // For now, logging counts as internal notification system
                $this->log_action($rule['name'], "Notification triggered. Context: " . json_encode($context));
                break;

            case 'adjust_price':
            case 'adjust_price_flat':
            case 'apply_tiered_discount':
                if (isset($context['product_id'])) {
                    $product = wc_get_product($context['product_id']);
                    if ($product) {
                        // Use regular price to calculate discount
                        $current_price = (float) $product->get_regular_price();
                        if ($current_price <= 0) {
                            $current_price = (float) $product->get_price(); // Fallback if no specific regular price
                        }
                        
                        if ($current_price > 0) {
                            $discount_amount = 0;
                            
                            if ($action === 'apply_tiered_discount') {
                                $stock = $context['stock'] ?? 0;
                                $pct = 0;
                                if ($stock > 20) $pct = 0;
                                elseif ($stock >= 11 && $stock <= 20) $pct = 5;
                                elseif ($stock >= 6 && $stock <= 10) $pct = 10;
                                elseif ($stock >= 1 && $stock <= 5) $pct = 15;
                                
                                $discount_amount = $current_price * ($pct / 100);
                            } else {
                                // Baseline discount configured by rules
                                $base_val = (float) $val; 
                                
                                // Multiply by threshold steps if configured
                                $multiplier = 1;
                                $step = (int) ($rule['threshold_step'] ?? 0);
                                if ($step > 0 && isset($context['stock']) && isset($context['threshold_start'])) {
                                    $stock_diff = $context['threshold_start'] - $context['stock'];
                                    if ($stock_diff >= 0) {
                                        $multiplier = floor($stock_diff / $step) + 1; // +1 because we already hit the first threshold limit
                                    }
                                }
                                
                                if ($action === 'adjust_price') {
                                    // Percentage
                                    $pct = $base_val * $multiplier;
                                    $discount_amount = $current_price * ($pct / 100);
                                } elseif ($action === 'adjust_price_flat') {
                                    // Flat
                                    $discount_amount = $base_val * $multiplier;
                                }
                            }

                            if ($discount_amount > 0) {
                                $cap = (float) ($rule['max_discount_cap'] ?? 0);
                                if ($cap > 0 && $discount_amount > $cap) {
                                    $discount_amount = $cap;
                                }

                                $new_price = max(0, $current_price - $discount_amount);
                                
                                // Set sale price to showcase discount visually, ensure regular is intact
                                if (!$product->get_regular_price()) {
                                    $product->set_regular_price($current_price);
                                }
                                $product->set_sale_price(round($new_price, 2));
                                $product->set_price(round($new_price, 2));
                                $product->save();
                                $this->log_action($rule['name'], "Applied a \$" . round($discount_amount, 2) . " discount to Product ID {$context['product_id']}. New Sale Price: \$$new_price.");
                            }
                        }
                    }
                }
                break;

            case 'sync_product':
                if (isset($context['product_id'])) {
                    // Call the store API to sync the product network-wide
                    if (class_exists('ShopCentral_Store_API')) {
                        $api = new ShopCentral_Store_API($this->namespace);
                        $request = new WP_REST_Request('POST');
                        $request->set_param('product_id', $context['product_id']);
                        $api->sync_products($request);
                        $this->log_action($rule['name'], "Auto-synced Product ID {$context['product_id']} across the network.");
                    }
                }
                break;
        }
    }
}
