<?php

defined('ABSPATH') || exit;

class BundlePress_Bundle_API
{
    private $namespace;

    public function __construct($namespace = 'bundlepress/v1')
    {
        $this->namespace = $namespace;
        add_action('rest_api_init', [$this, 'register_routes']);
    }

    public function register_routes()
    {
        // Bundles (CRUD)
        register_rest_route($this->namespace, '/bundles', [
            [
                'methods' => 'GET',
                'callback' => [$this, 'get_bundles'],
                'permission_callback' => [$this, 'check_permission']
            ],
            [
                'methods' => 'POST',
                'callback' => [$this, 'create_bundle'],
                'permission_callback' => [$this, 'check_permission']
            ]
        ]);

        register_rest_route($this->namespace, '/bundles/(?P<id>\d+)', [
            [
                'methods' => 'GET',
                'callback' => [$this, 'get_bundle'],
                'permission_callback' => '__return_true'
            ],
            [
                'methods' => 'POST',
                'callback' => [$this, 'update_bundle'],
                'permission_callback' => [$this, 'check_permission']
            ],
            [
                'methods' => 'DELETE',
                'callback' => [$this, 'delete_bundle'],
                'permission_callback' => [$this, 'check_permission']
            ]
        ]);

        register_rest_route($this->namespace, '/bundles/search-products', [
            'methods' => 'GET',
            'callback' => [$this, 'search_products'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        register_rest_route($this->namespace, '/bundles/bulk-action', [
            'methods' => 'POST',
            'callback' => [$this, 'bulk_action_bundles'],
            'permission_callback' => [$this, 'check_permission']
        ]);
    }

    public function bulk_action_bundles($request)
    {
        $params = $request->get_json_params();
        $action = $params['action'] ?? '';
        $ids = $params['ids'] ?? [];

        if (empty($ids) || !is_array($ids)) {
            return new WP_Error('invalid_ids', 'No bundle IDs provided', ['status' => 400]);
        }

        if ($action === 'delete') {
            global $wpdb;
            $success_count = 0;
            $table = $wpdb->prefix . 'bundlepress_bundles';

            foreach ($ids as $id) {
                // Get the product_id if it's a fixed bundle so we can delete the WC product too
                $bundle = $wpdb->get_row($wpdb->prepare("SELECT product_id FROM $table WHERE id = %d", $id));
                
                if ($bundle) {
                    // 1. Delete associated WC product if it exists
                    if ($bundle->product_id) {
                        wp_delete_post($bundle->product_id, true);
                    }
                    
                    // 2. Cleanup custom table data
                    BundlePress_DB::cleanup_bundle_data($id);
                    $success_count++;
                }
            }

            return rest_ensure_response([
                'success' => true,
                'message' => sprintf('%d bundles deleted successfully', $success_count)
            ]);
        }

        return new WP_Error('invalid_action', 'Invalid action provided', ['status' => 400]);
    }

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

    public function get_bundles($request)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'bundlepress_bundles';
        
        $results = $wpdb->get_results("SELECT * FROM $table ORDER BY created_at DESC");
        $bundles = [];

        foreach ($results as $row) {
            // Calculate total revenue from WooCommerce orders
            $total_revenue = $wpdb->get_var($wpdb->prepare(
                "SELECT SUM(CAST(meta_v.meta_value AS DECIMAL(19,4))) 
                 FROM {$wpdb->prefix}woocommerce_order_itemmeta AS meta_k
                 JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS meta_v ON meta_k.order_item_id = meta_v.order_item_id
                 WHERE meta_k.meta_key = '_bundlepress_bundle' 
                 AND meta_k.meta_value = %d
                 AND meta_v.meta_key = '_line_total'",
                $row->id
            ));
            
            $bundles[] = [
                'id' => (int) $row->id,
                'name' => $row->name,
                'type' => $row->type,
                'status' => $row->status,
                'total_revenue' => (float)($total_revenue ?? 0),
                'image_url' => $row->image_url,
                'date' => $row->created_at,
                'product_url' => !empty($row->product_id) ? get_permalink($row->product_id) : '',
            ];
        }

        return rest_ensure_response([
            'success' => true,
            'data' => $bundles,
            'currency' => trim(html_entity_decode(get_woocommerce_currency_symbol(), ENT_QUOTES, 'UTF-8')),
        ]);
    }

    public function get_bundle($request)
    {
        $id = (int) $request['id'];
        $bundle_data = BundlePress_DB::get_bundle_data($id);

        if (!$bundle_data) {
            return new WP_Error('not_found', 'Bundle not found', ['status' => 404]);
        }

        $bundle_data['items'] = $this->get_bundle_items($bundle_data['id']);
        if (!empty($bundle_data['product_id'])) {
            $product = wc_get_product($bundle_data['product_id']);
            if ($product) {
                $bundle_data['category_ids'] = $product->get_category_ids();
            }
        }

        return rest_ensure_response([
            'success' => true,
            'data' => $bundle_data
        ]);
    }

    private function get_bundle_items($bundle_id)
    {
        global $wpdb;

        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}bundlepress_bundle_items WHERE bundle_id = %d ORDER BY position ASC",
            $bundle_id
        ), ARRAY_A);

        foreach ($items as &$item) {
            $product = wc_get_product($item['product_id']);
            if ($product) {
                $item['name']  = $product->get_name();
                $item['price'] = $product->get_price();
                $item['image'] = wp_get_attachment_thumb_url($product->get_image_id());
                $item['type']  = $product->get_type();
                $item['product_id']   = (int) $item['product_id'];
                $item['variation_id'] = $item['variation_id'] ? (int) $item['variation_id'] : null;

                if ($product instanceof WC_Product_Variable) {
                    $variations_data = $this->sort_variations_by_attribute_order($product->get_available_variations(), $product);
                    $item['variations'] = array_map(function ($var_data) {
                        return [
                            'id'    => $var_data['variation_id'],
                            'name'  => implode(', ', array_filter($var_data['attributes'])),
                            'price' => $var_data['display_price'],
                            'sku'   => $var_data['sku'],
                        ];
                    }, $variations_data);

                    // If admin selected a specific variation, use that variation's price
                    if ($item['variation_id']) {
                        $variation = wc_get_product($item['variation_id']);
                        if ($variation) {
                            $item['price'] = $variation->get_price();
                        }
                    }
                }
            }
        }

        return $items;
    }

    private function sort_variations_by_attribute_order(array $variations_data, $product): array
    {
        $attributes = $product->get_attributes();

        usort($attributes, function ($a, $b) {
            return $a->get_position() <=> $b->get_position();
        });

        $attr_value_order = [];
        foreach ($attributes as $attr) {
            $attr_name = $attr->get_name();
            $attr_key = strpos($attr_name, 'pa_') === 0
                ? 'attribute_' . $attr_name
                : 'attribute_' . strtolower(sanitize_title($attr_name));

            $options = $attr->get_options();
            $ordered_slugs = [];

            if ($attr->is_taxonomy()) {
                foreach ($options as $term_id) {
                    $term = get_term($term_id);
                    if ($term && !is_wp_error($term)) {
                        $ordered_slugs[] = $term->slug;
                    }
                }
            } else {
                $ordered_slugs = array_map(function ($val) {
                    return strtolower(sanitize_title($val));
                }, $options);
            }

            $attr_value_order[$attr_key] = array_flip($ordered_slugs);
        }

        usort($variations_data, function ($a, $b) use ($attr_value_order) {
            foreach ($attr_value_order as $attr_key => $value_order) {
                $val_a = $a['attributes'][$attr_key] ?? '';
                $val_b = $b['attributes'][$attr_key] ?? '';

                $pos_a = ($val_a !== '') ? ($value_order[$val_a] ?? PHP_INT_MAX) : PHP_INT_MAX;
                $pos_b = ($val_b !== '') ? ($value_order[$val_b] ?? PHP_INT_MAX) : PHP_INT_MAX;

                if ($pos_a !== $pos_b) {
                    return $pos_a <=> $pos_b;
                }
            }
            return 0;
        });

        return $variations_data;
    }

    public function create_bundle($request)
    {
        global $wpdb;
        $params = $request->get_json_params();
        $type = $params['type'] ?? 'fixed';

        $wpdb->insert($wpdb->prefix . 'bundlepress_bundles', [
            'name' => $params['name'],
            'type' => $type,
            'status' => $params['status'] ?? 'publish',
            'description' => $params['description'] ?? '',
            'short_description' => $params['short_description'] ?? '',
            'image_id' => !empty($params['image_id']) ? (int) $params['image_id'] : null,
            'image_url' => $params['image_url'] ?? '',
            'gallery' => json_encode(!empty($params['gallery']) ? $params['gallery'] : []),
        ]);

        $bundle_id = $wpdb->insert_id;

        if (!$bundle_id) {
            return new WP_Error('create_failed', 'Failed to create bundle: ' . $wpdb->last_error, ['status' => 500]);
        }

        // For fixed bundles, we still need a WooCommerce product for cart functionality
        if ($type === 'fixed') {
            $product = new WC_Product_Simple();
            $product->set_name($params['name']);
            $product->set_status($params['status'] ?? 'publish');
            if (isset($params['description']))       $product->set_description($params['description']);
            if (isset($params['short_description']))  $product->set_short_description($params['short_description']);
            if (isset($params['image_id']))          $product->set_image_id($params['image_id']);
            
            if (isset($params['gallery']) && is_array($params['gallery'])) {
                $main_image_id = isset($params['image_id']) ? (int) $params['image_id'] : 0;
                $gallery_ids = array_map(function($g) { return isset($g['id']) ? (int) $g['id'] : null; }, $params['gallery']);
                $gallery_ids = array_filter($gallery_ids, function($id) use ($main_image_id) {
                    return $id && $id !== $main_image_id;
                });
                $product->set_gallery_image_ids($gallery_ids);
            }
            if (isset($params['category_ids']) && is_array($params['category_ids'])) {
                $product->set_category_ids(array_map('intval', $params['category_ids']));
            }

            $product_id = $product->save();
            wp_set_object_terms($product_id, 'bundlepress', 'product_type');
            
            $wpdb->update($wpdb->prefix . 'bundlepress_bundles', ['product_id' => $product_id], ['id' => $bundle_id]);
        }

        $this->save_bundle_data($bundle_id, $params);

        return rest_ensure_response([
            'success' => true,
            'id' => $bundle_id,
            'message' => 'Bundle created successfully'
        ]);
    }

    public function update_bundle($request)
    {
        global $wpdb;
        $id = (int) $request['id'];
        $params = $request->get_json_params();
        $table = $wpdb->prefix . 'bundlepress_bundles';

        $bundle = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id));
        if (!$bundle) {
            return new WP_Error('not_found', 'Bundle not found', ['status' => 404]);
        }

        $update_data = [];
        if (isset($params['name']))              $update_data['name'] = $params['name'];
        if (isset($params['status']))            $update_data['status'] = $params['status'];
        if (isset($params['description']))       $update_data['description'] = $params['description'];
        if (isset($params['short_description']))  $update_data['short_description'] = $params['short_description'];
        if (isset($params['image_id']))          $update_data['image_id'] = $params['image_id'] !== '' ? (int) $params['image_id'] : null;
        if (isset($params['image_url']))         $update_data['image_url'] = $params['image_url'];
        if (isset($params['gallery']))           $update_data['gallery'] = json_encode(!empty($params['gallery']) ? $params['gallery'] : []);

        if (!empty($update_data)) {
            $update_data['updated_at'] = current_time('mysql', true);
            $wpdb->update($table, $update_data, ['id' => $id]);
        }

        // Sync with WooCommerce product if it exists (for fixed bundles)
        if ($bundle->product_id) {
            $product = wc_get_product($bundle->product_id);
            if ($product) {
                if (isset($params['name']))              $product->set_name($params['name']);
                if (isset($params['status']))            $product->set_status($params['status']);
                if (isset($params['description']))       $product->set_description($params['description']);
                if (isset($params['short_description']))  $product->set_short_description($params['short_description']);
                if (isset($params['image_id']))          $product->set_image_id($params['image_id']);
                
                if (isset($params['gallery']) && is_array($params['gallery'])) {
                    $main_image_id = isset($params['image_id']) ? (int) $params['image_id'] : (int) $product->get_image_id();
                    $gallery_ids = array_map(function($g) { return isset($g['id']) ? (int) $g['id'] : null; }, $params['gallery']);
                    $gallery_ids = array_filter($gallery_ids, function($id) use ($main_image_id) {
                        return $id && $id !== $main_image_id;
                    });
                    $product->set_gallery_image_ids($gallery_ids);
                }
                if (isset($params['category_ids']) && is_array($params['category_ids'])) {
                    $product->set_category_ids(array_map('intval', $params['category_ids']));
                }

                $product->save();
            }
        }

        $this->save_bundle_data($id, $params);

        return rest_ensure_response([
            'success' => true,
            'message' => 'Bundle updated successfully'
        ]);
    }

    private function save_bundle_data($bundle_id, $params)
    {
        global $wpdb;
        $type = $params['type'] ?? 'fixed';
        $settings = $params['settings'] ?? [];

        switch ($type) {
            case 'fixed':
                $discount_type = $params['discount_type'] ?? '';
                $discount_value = (float)($params['discount_value'] ?? 0);
                $regular_price = (float)($params['price'] ?? 0);
                $sale_price = (isset($params['sale_price']) && $params['sale_price'] !== '') ? (float)$params['sale_price'] : null;

                // Auto-calculate regular price for fixed bundles
                if ($discount_type === 'set_price') {
                    $regular_price = $discount_value;
                    $sale_price = null;
                } else {
                    $sum = 0;
                    if (!empty($params['items'])) {
                        foreach ($params['items'] as $item) {
                            $sum += ((float)($item['price'] ?? 0) * (int)($item['quantity'] ?? 1));
                        }
                    }
                    $regular_price = $sum;
                    if ($sale_price === null && !empty($discount_type)) {
                        if ($discount_type === 'percentage') $sale_price = $regular_price * (1 - $discount_value/100);
                        elseif ($discount_type === 'fixed')  $sale_price = max(0, $regular_price - $discount_value);
                    }
                }

                $wpdb->replace($wpdb->prefix . 'bundlepress_fixed_settings', [
                    'bundle_id' => $bundle_id,
                    'regular_price' => $regular_price,
                    'sale_price' => $sale_price,
                    'discount_type' => $discount_type,
                    'discount_value' => $discount_value,
                    'layout' => $settings['layout'] ?? 'list',
                    'show_thumbnails' => ($settings['show_thumbnails'] ?? true) ? 1 : 0,
                    'allow_quantity_change' => ($settings['allow_quantity_change'] ?? true) ? 1 : 0,
                ]);

                // Sync to WC product
                $row = $wpdb->get_row($wpdb->prepare("SELECT product_id FROM {$wpdb->prefix}bundlepress_bundles WHERE id = %d", $bundle_id));
                if ($row && $row->product_id) {
                    $product = wc_get_product($row->product_id);
                    if ($product) {
                        $product->set_regular_price($regular_price);
                        $product->set_sale_price($sale_price !== null ? (string)$sale_price : '');
                        $product->save();
                    }
                }
                break;

            case 'volume':
                $wpdb->replace($wpdb->prefix . 'bundlepress_volume_settings', [
                    'bundle_id' => $bundle_id,
                    'tiers' => json_encode($settings['tiers'] ?? []),
                    'target_type' => $settings['target_type'] ?? 'all',
                    'trigger_products' => json_encode($settings['trigger_products'] ?? []),
                ]);
                break;

            case 'bxgy':
                $wpdb->replace($wpdb->prefix . 'bundlepress_bxgy_settings', [
                    'bundle_id' => $bundle_id,
                    'buy_qty' => $settings['bxgy_buy_qty'] ?? 1,
                    'get_qty' => $settings['bxgy_get_qty'] ?? 1,
                    'offer_type' => $settings['bxgy_offer_type'] ?? 'free_gift',
                    'offer_products' => json_encode($settings['offer_product'] ?? []),
                    'discount_type' => $settings['bxgy_discount_type'] ?? 'percentage',
                    'discount_amount' => $settings['bxgy_discount_amount'] ?? 0,
                    'target_type' => $settings['target_type'] ?? 'all',
                    'trigger_products' => json_encode($settings['trigger_products'] ?? []),
                ]);
                break;

            case 'fbt':
                $wpdb->replace($wpdb->prefix . 'bundlepress_fbt_settings', [
                    'bundle_id' => $bundle_id,
                    'fbt_source' => $settings['fbt_source'] ?? 'manual',
                    'fbt_limit' => $settings['fbt_limit'] ?? 4,
                    'discount_type' => $params['discount_type'] ?? ($settings['discount_type'] ?? ''),
                    'discount_value' => $params['discount_value'] ?? ($settings['discount_value'] ?? 0),
                    'target_type' => $settings['target_type'] ?? 'all',
                    'trigger_products' => json_encode($settings['trigger_products'] ?? []),
                ]);
                break;

            case 'mixmatch':
                $wpdb->replace($wpdb->prefix . 'bundlepress_mixmatch_settings', [
                    'bundle_id' => $bundle_id,
                    'tiers' => json_encode($settings['tiers'] ?? []),
                    'min_items' => $settings['min_items'] ?? 1,
                    'max_items' => $settings['max_items'] ?? null,
                    'target_type' => $settings['target_type'] ?? 'specific',
                    'trigger_products' => json_encode($settings['trigger_products'] ?? []),
                ]);
                break;
        }

        if (isset($params['items'])) {
            $this->save_bundle_items($bundle_id, $params['items'], $type);
        }
    }

    private function save_bundle_items($bundle_id, $items, $type)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'bundlepress_bundle_items';

        $wpdb->delete($table, ['bundle_id' => $bundle_id]);

        foreach ($items as $index => $item) {
            $item_type = 'bundle_item';
            if ($type === 'bxgy' && isset($item['is_offer'])) $item_type = 'offer_item';
            
            $wpdb->insert($table, [
                'bundle_id' => $bundle_id,
                'product_id' => $item['product_id'],
                'variation_id' => $item['variation_id'] ?? null,
                'item_type' => $item_type,
                'quantity' => $item['quantity'] ?? 1,
                'min_quantity' => $item['min_quantity'] ?? 1,
                'max_quantity' => $item['max_quantity'] ?? null,
                'discount_type' => $item['discount_type'] ?? '',
                'discount_value' => $item['discount_value'] ?? 0,
                'position' => $index,
            ]);
        }
    }

    public function delete_bundle($request)
    {
        global $wpdb;
        $id = (int)$request['id'];
        $table = $wpdb->prefix . 'bundlepress_bundles';

        $bundle = $wpdb->get_row($wpdb->prepare("SELECT product_id FROM $table WHERE id = %d", $id));
        if ($bundle && $bundle->product_id) {
            wp_delete_post($bundle->product_id, true);
        }

        BundlePress_DB::cleanup_bundle_data($id);
        return rest_ensure_response([
            'success' => true,
            'message' => 'Bundle deleted successfully'
        ]);
    }

    public function search_products($request)
    {
        $search = $request['q'];

        $args = [
            'post_type' => 'product',
            'post_status' => 'publish',
            'posts_per_page' => 20,
            's' => $search,
            'tax_query' => [
                [
                    'taxonomy' => 'product_type',
                    'field' => 'slug',
                    'operator' => 'NOT IN',
                    'terms' => ['bundlepress'],
                ],
            ],
        ];

        $products = get_posts($args);
        $results = [];

        foreach ($products as $post) {
            $product = wc_get_product($post->ID);
            $results[] = [
                'id' => $post->ID,
                'name' => $post->post_title,
                'price' => $product->get_price(),
                'image' => wp_get_attachment_thumb_url($product->get_image_id()),
            ];
        }

        return rest_ensure_response([
            'success' => true,
            'data' => $results
        ]);
    }
}
