<?php

namespace Miladmodaresi\Taamito\Admin;

use Miladmodaresi\Taamito\Base\BaseController;
use Miladmodaresi\Taamito\Api\ShopApi;
use Miladmodaresi\Taamito\Model\TaamSync;

class WizardController extends BaseController
{
    public function admin_ajax_init()
    {
        taamitoApp()->ajax('get_categories', [$this, 'getCategories']);
        taamitoApp()->ajax('get_category_tree', [$this, 'getCategoryTree']);
        taamitoApp()->ajax('get_features', [$this, 'getFeatures']);
        taamitoApp()->ajax('get_feature_values', [$this, 'getFeatureValues']);
        taamitoApp()->ajax('get_products', [$this, 'getProducts']);
        taamitoApp()->ajax('wizard_sync_category', [$this, 'syncCategory']);
        taamitoApp()->ajax('wizard_sync_category_tree', [$this, 'syncCategoryTree']);
        taamitoApp()->ajax('wizard_sync_feature', [$this, 'syncFeature']);
        taamitoApp()->ajax('wizard_sync_feature_value', [$this, 'syncFeatureValue']);
        taamitoApp()->ajax('wizard_sync_product', [$this, 'syncProduct']);
        taamitoApp()->ajax('wizard_check_completion', [$this, 'checkCompletion']);
        taamitoApp()->ajax('wizard_mark_completed', [$this, 'markCompleted']);
    }

    public function checkCompletion()
    {
        $completed = taamitoApp()->getOption('wizard_completed', false);
        wp_send_json_success(['completed' => (bool)$completed]);
    }

    public function markCompleted()
    {
        taamitoApp()->saveOption('wizard_completed', true);
        wp_send_json_success(['message' => 'Wizard marked as completed']);
    }

    protected function getShopApi()
    {
        $taamitoUser = taamitoApp()->getOption('user') ?? [];
        $token = is_array($taamitoUser) && isset($taamitoUser['token']) ? $taamitoUser['token'] : null;
        $domain = taamitoApp()->getOption('domain') ?? null;

        if (!$token || !$domain) {
            wp_send_json_error(['message' => 'Missing token or domain']);
        }

        return (new ShopApi())->setSubDomain($domain)->setAuth($token);
    }

    public function syncCategory()
    {
        $request = $this->request->get_attributes();
        $categoryId = $request['category_id'] ?? null;

        if (!$categoryId) {
            wp_send_json_error(['message' => 'Category ID is required']);
        }

        $term = get_term($categoryId, 'product_cat');
        if (!$term || is_wp_error($term)) {
            wp_send_json_error(['message' => 'Category not found']);
        }

        $taxId = get_term_meta($categoryId, 'taamito_tax_id', true) ?: 7;

        $data = [
            'name' => $term->name,
            'description' => $term->description ?: '<p class="ql-align-right">' . $term->name . '</p>',
            'tax_id' => (int)$taxId,
        ];

        try {
            $api = $this->getShopApi();
            $response = $api->createCategory($data);

            if (isset($response->entity->id)) {
                $sync = (new TaamSync())->where('name', 'category')->where('local_id', $categoryId)->first();
                if ($sync && $sync->exists()) {
                    $sync->update(['remote_id' => $response->entity->id]);
                } else {
                    (new TaamSync([
                        'name' => 'category',
                        'local_id' => $categoryId,
                        'remote_id' => $response->entity->id,
                        'status' => 2,
                        'data' => ['category' => $response->entity]
                    ]))->create();
                }

                wp_send_json_success([
                    'message' => 'Category synced successfully',
                    'remote_id' => $response->entity->id
                ]);
            }

            wp_send_json_error(['message' => 'Invalid response from API']);
        } catch (\Throwable $th) {
            wp_send_json_error(['message' => $th->getMessage()]);
        }
    }

    public function syncCategoryTree()
    {
        $request = $this->request->get_attributes();
        $categoryId = $request['category_id'] ?? null;
        $parentId = $request['parent_id'] ?? null;

        if (!$categoryId) {
            wp_send_json_error(['message' => 'Category ID is required']);
        }

        $term = get_term($categoryId, 'product_cat');
        if (!$term || is_wp_error($term)) {
            wp_send_json_error(['message' => 'Category not found']);
        }

        $parentSync = null;
        if ($parentId) {
            $parentSync = (new TaamSync())->where('name', 'category')->where('local_id', $parentId)->first();
            if (!$parentSync || !$parentSync->exists()) {
                wp_send_json_error(['message' => 'Parent category not synced yet']);
            }
        }

        $data = [
            'name' => $term->name,
            'description' => $term->description ?: '<p class="ql-align-right">' . $term->name . '</p>',
        ];

        if ($parentSync) {
            $data['parent_id'] = $parentSync->remote_id;
        }

        try {
            $api = $this->getShopApi();
            $response = $api->createCategory($data);

            if (isset($response->entity->id)) {
                $sync = (new TaamSync())->where('name', 'category')->where('local_id', $categoryId)->first();
                if ($sync && $sync->exists()) {
                    $sync->update(['remote_id' => $response->entity->id]);
                } else {
                    (new TaamSync([
                        'name' => 'category',
                        'local_id' => $categoryId,
                        'remote_id' => $response->entity->id,
                        'status' => 2,
                        'data' => ['category' => $response->entity]
                    ]))->create();
                }

                wp_send_json_success([
                    'message' => 'Category synced successfully',
                    'remote_id' => $response->entity->id
                ]);
            }

            wp_send_json_error(['message' => 'Invalid response from API']);
        } catch (\Throwable $th) {
            wp_send_json_error(['message' => $th->getMessage()]);
        }
    }

    public function syncFeature()
    {
        $request = $this->request->get_attributes();
        $attributeId = $request['attribute_id'] ?? null;

        if (!$attributeId) {
            wp_send_json_error(['message' => 'Attribute ID is required']);
        }

        $attribute = wc_get_attribute($attributeId);
        if (!$attribute) {
            wp_send_json_error(['message' => 'Attribute not found']);
        }

        $type = get_term_meta($attributeId, 'taamito_feature_type', true) ?: 1;

        $data = [
            'name' => $attribute->name,
            'slug' => null,
            'type' => (int)$type,
        ];

        try {
            $api = $this->getShopApi();
            $response = $api->createFeature($data);

            if (isset($response->entity->id)) {
                $sync = (new TaamSync())->where('name', 'feature')->where('local_id', $attributeId)->first();
                if ($sync && $sync->exists() && isset($sync->data['id'])) {
                    // Update existing record - ensure data is set before update
                    $syncId = $sync->data['id'];
                    $sync->data['remote_id'] = $response->entity->id;
                    $sync->data['status'] = 2;
                    $sync->data['data'] = json_encode(['feature' => $response->entity]);
                    // Use find to reload with ID, then update
                    $syncToUpdate = (new TaamSync())->find($syncId);
                    if ($syncToUpdate && $syncToUpdate->exists()) {
                        $syncToUpdate->update([
                            'remote_id' => $response->entity->id,
                            'status' => 2,
                            'data' => json_encode(['feature' => $response->entity])
                        ]);
                    }
                } else {
                    // Create new record
                    (new TaamSync([
                        'name' => 'feature',
                        'local_id' => $attributeId,
                        'remote_id' => $response->entity->id,
                        'status' => 2,
                        'data' => ['feature' => $response->entity]
                    ]))->create();
                }

                wp_send_json_success([
                    'message' => 'Feature synced successfully',
                    'remote_id' => $response->entity->id
                ]);
            }

            wp_send_json_error(['message' => 'Invalid response from API']);
        } catch (\Throwable $th) {
            wp_send_json_error(['message' => $th->getMessage()]);
        }
    }

    public function syncFeatureValue()
    {
        $request = $this->request->get_attributes();
        $featureId = $request['feature_id'] ?? null;
        $termId = $request['term_id'] ?? null;

        if (!$featureId || !$termId) {
            wp_send_json_error(['message' => 'Feature ID and Term ID are required']);
        }

        $featureSync = (new TaamSync())->where('name', 'feature')->where('local_id', $featureId)->first();
        if (!$featureSync || !$featureSync->exists()) {
            wp_send_json_error(['message' => 'Feature not synced yet. Please sync the feature first.']);
        }
        
        // Check remote_id - try multiple sources
        $remoteId = null;
        
        // First, try the remote_id column directly
        if (isset($featureSync->data['remote_id']) && !empty($featureSync->data['remote_id'])) {
            $remoteId = $featureSync->data['remote_id'];
        } elseif (isset($featureSync->remote_id) && !empty($featureSync->remote_id)) {
            $remoteId = $featureSync->remote_id;
        }
        
        // If remote_id column is empty, try to extract it from the data field
        // The data structure can be: data['feature']['id'] or data['data']['feature']['id']
        if (($remoteId === null || $remoteId === '' || $remoteId === 0)) {
            $syncData = $featureSync->data;
            
            // Try direct path: data['feature']['id']
            if (isset($syncData['feature']['id'])) {
                $remoteId = (int)$syncData['feature']['id'];
            }
            // Try nested path: data['data']['feature']['id']
            elseif (isset($syncData['data'])) {
                $nestedData = is_string($syncData['data']) ? json_decode($syncData['data'], true) : $syncData['data'];
                if (isset($nestedData['feature']['id'])) {
                    $remoteId = (int)$nestedData['feature']['id'];
                }
            }
            
            // If we found remote_id in data, repair the sync record
            if ($remoteId && isset($featureSync->data['id'])) {
                $syncToRepair = (new TaamSync())->find($featureSync->data['id']);
                if ($syncToRepair && $syncToRepair->exists()) {
                    $syncToRepair->update(['remote_id' => $remoteId]);
                }
            }
        }
        
        // Ensure remote_id is an integer
        $remoteId = $remoteId ? (int)$remoteId : null;
        
        if ($remoteId === null || $remoteId === '' || $remoteId === 0) {
            wp_send_json_error([
                'message' => 'Feature remote ID is missing. Please sync the feature again.',
                'debug' => [
                    'feature_id' => $featureId,
                    'remote_id' => $remoteId,
                    'has_sync' => $featureSync->exists(),
                    'sync_data' => $featureSync->data ?? []
                ]
            ]);
        }

        $term = get_term($termId);
        if (!$term || is_wp_error($term)) {
            wp_send_json_error(['message' => 'Term not found']);
        }

        $color = get_term_meta($termId, 'pa_color', true) ?: null;
        $image = get_term_meta($termId, 'pa_image', true) ?: null;
        $imageUrl = $image ? wp_get_attachment_url($image) : null;

        $data = [
            'name' => $term->name,
            'slug' => '',
            'color' => $color,
            'image' => null,
            'image_url' => $imageUrl,
            'local_id' => (int)$termId, // Include local_id so API can return it
        ];

        try {
            $api = $this->getShopApi();
            
            // Log the request for debugging
            \Sentry\captureMessage("Taamito Wizard: Creating feature value - feature_id: {$remoteId}, term_id: {$termId}, term_name: {$term->name}");
            
            $response = $api->createFeatureValue($remoteId, $data);
            
            // Check if response is an error
            if (isset($response->is_success) && $response->is_success === false) {
                $errorMessage = $response->message ?? 'Failed to create feature value';
                
                // Provide more helpful error message for 404
                if (strpos($errorMessage, 'یافت نشد') !== false || strpos($errorMessage, 'not found') !== false) {
                    $errorMessage = "Feature with ID {$remoteId} not found in Taamito. Please verify the feature exists or re-sync the feature first.";
                }
                
                wp_send_json_error([
                    'message' => $errorMessage,
                    'debug' => [
                        'feature_remote_id' => $remoteId,
                        'term_id' => $termId,
                        'term_name' => $term->name,
                        'api_response' => $response,
                        'suggestion' => 'The feature may not exist in Taamito. Try re-syncing the feature first.'
                    ]
                ]);
                return;
            }
            
            // Also check if response is null or doesn't have expected structure
            if (!$response || (!isset($response->entity) && !isset($response->is_success))) {
                wp_send_json_error([
                    'message' => 'Invalid API response. The feature may not exist in Taamito.',
                    'debug' => [
                        'feature_remote_id' => $remoteId,
                        'term_id' => $termId,
                        'response' => $response
                    ]
                ]);
                return;
            }

            // Handle response where entity is a single object (new API structure)
            $createdValue = null;
            if (isset($response->entity)) {
                if (is_object($response->entity) && isset($response->entity->id)) {
                    // Entity is a single object (new structure)
                    $createdValue = $response->entity;
                } elseif (is_array($response->entity)) {
                    // Fallback: Handle array structure (old structure)
                    foreach ($response->entity as $item) {
                        $itemObj = is_array($item) ? (object)$item : $item;
                        if (isset($itemObj->local_id) && (int)$itemObj->local_id === (int)$termId) {
                            $createdValue = $itemObj;
                            break;
                        }
                    }
                    
                    // If not found by local_id, use the last item in the array
                    if (!$createdValue && count($response->entity) > 0) {
                        $lastItem = end($response->entity);
                        $createdValue = is_array($lastItem) ? (object)$lastItem : $lastItem;
                    }
                }
            }

            if ($createdValue && isset($createdValue->id)) {
                $sync = (new TaamSync())->where('name', 'feature_value')->where('local_id', $termId)->first();
                if ($sync && $sync->exists() && isset($sync->data['id'])) {
                    $syncToUpdate = (new TaamSync())->find($sync->data['id']);
                    if ($syncToUpdate && $syncToUpdate->exists()) {
                        $syncToUpdate->update(['remote_id' => $createdValue->id]);
                    }
                } else {
                    (new TaamSync([
                        'name' => 'feature_value',
                        'local_id' => $termId,
                        'remote_id' => $createdValue->id,
                        'status' => 2,
                        'data' => ['feature_value' => $createdValue]
                    ]))->create();
                }

                wp_send_json_success([
                    'message' => 'Feature value synced successfully',
                    'remote_id' => $createdValue->id
                ]);
            }

            wp_send_json_error(['message' => 'Invalid response from API: Could not find created feature value']);
        } catch (\Throwable $th) {
            // HttpException sends response directly, so we might not catch it here
            // But if we do, extract the error message
            $errorMessage = $th->getMessage();
            
            // Try to extract message from JSON string
            if (is_string($errorMessage)) {
                $decoded = json_decode($errorMessage, true);
                if ($decoded && isset($decoded['message'])) {
                    $errorMessage = $decoded['message'];
                } elseif ($decoded && isset($decoded['data']['message'])) {
                    $errorMessage = $decoded['data']['message'];
                }
            }
            
            wp_send_json_error([
                'message' => $errorMessage ?: 'Failed to sync feature value',
                'debug' => [
                    'feature_remote_id' => $remoteId,
                    'term_id' => $termId,
                    'error' => $th->getMessage()
                ]
            ]);
        }
    }

    public function syncProduct()
    {
        $request = $this->request->get_attributes();
        $productId = $request['product_id'] ?? null;

        if (!$productId) {
            wp_send_json_error(['message' => 'Product ID is required']);
        }

        $product = wc_get_product($productId);
        if (!$product) {
            wp_send_json_error(['message' => 'Product not found']);
        }

        try {
            $data = $this->buildProductPayload($product);
            $api = $this->getShopApi();
            $response = $api->createProduct($data);

            if (isset($response->entity->id)) {
                $sync = (new TaamSync())->where('name', 'product')->where('local_id', $productId)->first();
                if ($sync && $sync->exists()) {
                    $sync->update(['remote_id' => $response->entity->id]);
                } else {
                    (new TaamSync([
                        'name' => 'product',
                        'local_id' => $productId,
                        'remote_id' => $response->entity->id,
                        'status' => 2,
                        'data' => ['product' => $response->entity]
                    ]))->create();
                }

                wp_send_json_success([
                    'message' => 'Product synced successfully',
                    'remote_id' => $response->entity->id
                ]);
            }

            wp_send_json_error(['message' => 'Invalid response from API']);
        } catch (\Throwable $th) {
            wp_send_json_error(['message' => $th->getMessage()]);
        }
    }

    protected function buildProductPayload($product)
    {
        $categoryIds = [];
        $terms = wp_get_post_terms($product->get_id(), 'product_cat');
        foreach ($terms as $term) {
            $sync = (new TaamSync())->where('name', 'category')->where('local_id', $term->term_id)->first();
            if ($sync && $sync->exists()) {
                $categoryIds[] = $sync->remote_id;
            }
        }

        $taxId = get_post_meta($product->get_id(), 'taamito_tax_id', true) ?: 7;
        $channelIds = [1, 2];

        $thumbnailId = $product->get_image_id();
        $imageIds = $product->get_gallery_image_ids();
        if ($thumbnailId) {
            array_unshift($imageIds, $thumbnailId);
        }

        $prices = [];
        if ($product->is_type('variable')) {
            foreach ($product->get_children() as $variationId) {
                $variation = wc_get_product($variationId);
                if (!$variation) continue;

                $priceData = $this->buildVariationPricePayload($variation, $product);
                if ($priceData) {
                    $prices[] = $priceData;
                }
            }
        } else {
            $priceData = $this->buildSimplePricePayload($product);
            if ($priceData) {
                $prices[] = $priceData;
            }
        }

        $features = $this->buildProductFeatures($product);

        return [
            'barcode_taamito' => '',
            'brand_id' => null,
            'category_id' => !empty($categoryIds) ? $categoryIds[0] : null,
            'channel_id' => $channelIds,
            'collection_ids' => [],
            'continue_sell' => 1,
            'description' => $product->get_description() ?: '<p class="ql-align-right"><br></p>',
            'details' => [],
            'features' => $features,
            'formula' => '',
            'has_formula' => false,
            'has_multi_price' => count($prices) > 1 ? 1 : 0,
            'height' => $product->get_height() ?: null,
            'image_ids' => $imageIds,
            'is_decimal_stock_allowed' => 0,
            'is_preview' => false,
            'length' => $product->get_length() ?: null,
            'local_id' => (string)$product->get_id(),
            'max_order_quantity' => 10,
            'min_order_quantity' => 1,
            'name' => $product->get_name(),
            'order' => null,
            'price' => 0,
            'prices' => $prices,
            'purchase_price' => null,
            'result' => 0,
            'short_description' => $product->get_short_description() ?: '<p class="ql-align-right"><br></p>',
            'status' => 1,
            'stock' => 0,
            'tags' => [],
            'tax_id' => (int)$taxId,
            'thumbnail_id' => $thumbnailId ?: null,
            'type_id' => 1,
            'unit_id' => 1,
            'weight' => $product->get_weight() ?: null,
            'width' => $product->get_width() ?: null,
        ];
    }

    protected function buildVariationPricePayload($variation, $parent)
    {
        $combinations = [];
        $combinationText = [];

        foreach ($variation->get_attributes() as $attrName => $attrValue) {
            $taxonomy = str_replace('attribute_', '', $attrName);
            $term = get_term_by('slug', $attrValue, $taxonomy);
            if (!$term) continue;

            $featureSync = (new TaamSync())->where('name', 'feature')->where('local_id', wc_attribute_taxonomy_id_by_name(str_replace('pa_', '', $taxonomy)))->first();
            if (!$featureSync || !$featureSync->exists()) continue;

            $valueSync = (new TaamSync())->where('name', 'feature_value')->where('local_id', $term->term_id)->first();
            if (!$valueSync || !$valueSync->exists()) continue;

            $combinations[$featureSync->remote_id] = $valueSync->remote_id;
            $combinationText[] = $term->name;
        }

        return [
            'id' => 0,
            'product_id' => 0,
            'code' => $variation->get_sku() ?: null,
            'barcode' => null,
            'stock' => $variation->get_stock_quantity() ?: 0,
            'price' => (float)$variation->get_price() ?: 0,
            'purchase_price' => null,
            'barcode_file_id' => null,
            'barcode_taamito' => null,
            'combination_text' => implode(' ', $combinationText),
            'combinations' => $combinations,
            'continue_sell' => $variation->get_backorders() !== 'no' ? 1 : 0,
            'created_at' => '',
            'discount' => 0,
            'file_id' => null,
            'formula' => null,
            'has_formula' => false,
            'id' => 0,
            'is_decimal_stock_allowed' => 0,
            'old_id' => 0,
            'parent_id' => null,
            'product_id' => 0,
            'stock_incoming' => 0,
            'stock_reserve' => 0,
            'stock_unavailable' => 0,
            'tenant_id' => '',
            'unit_id' => 1,
        ];
    }

    protected function buildSimplePricePayload($product)
    {
        return [
            'id' => 0,
            'product_id' => 0,
            'code' => $product->get_sku() ?: null,
            'barcode' => null,
            'stock' => $product->get_stock_quantity() ?: 0,
            'price' => (float)$product->get_price() ?: 0,
            'purchase_price' => null,
            'barcode_file_id' => null,
            'barcode_taamito' => null,
            'combination_text' => '',
            'combinations' => [],
            'continue_sell' => 1,
            'created_at' => '',
            'discount' => 0,
            'file_id' => null,
            'formula' => null,
            'has_formula' => false,
            'id' => 0,
            'is_decimal_stock_allowed' => 0,
            'old_id' => 0,
            'parent_id' => null,
            'product_id' => 0,
            'stock_incoming' => 0,
            'stock_reserve' => 0,
            'stock_unavailable' => 0,
            'tenant_id' => '',
            'unit_id' => 1,
        ];
    }

    protected function buildProductFeatures($product)
    {
        $features = [];
        if ($product->is_type('variable')) {
            $attributes = $product->get_attributes();
            foreach ($attributes as $attribute) {
                if (!$attribute->get_variation()) continue;

                $attributeId = wc_attribute_taxonomy_id_by_name($attribute->get_name());
                $featureSync = (new TaamSync())->where('name', 'feature')->where('local_id', $attributeId)->first();
                if ($featureSync && $featureSync->exists()) {
                    $features[] = $featureSync->remote_id;
                }
            }
        }
        return $features;
    }

    public function getCategories()
    {
        $terms = get_terms([
            'taxonomy' => 'product_cat',
            'hide_empty' => false,
            'parent' => 0,
        ]);

        if (is_wp_error($terms)) {
            wp_send_json_error(['message' => $terms->get_error_message()]);
        }

        $categories = [];
        foreach ($terms as $term) {
            $categories[] = [
                'id' => $term->term_id,
                'name' => $term->name,
            ];
        }

        wp_send_json_success($categories);
    }

    public function getCategoryTree()
    {
        $terms = get_terms([
            'taxonomy' => 'product_cat',
            'hide_empty' => false,
        ]);

        if (is_wp_error($terms)) {
            wp_send_json_error(['message' => $terms->get_error_message()]);
        }

        $tree = [];
        foreach ($terms as $term) {
            // Only include child categories (categories with a parent)
            if ($term->parent > 0) {
                $parentTerm = get_term($term->parent);
                $tree[] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'parent' => $term->parent,
                    'parent_name' => $parentTerm && !is_wp_error($parentTerm) ? $parentTerm->name : '',
                ];
            }
        }

        wp_send_json_success($tree);
    }

    public function getFeatures()
    {
        $attributes = wc_get_attribute_taxonomies();
        $features = [];

        foreach ($attributes as $attribute) {
            $type = 1;
            if (strpos($attribute->attribute_name, 'color') !== false) {
                $type = 2;
            } elseif (strpos($attribute->attribute_name, 'image') !== false) {
                $type = 3;
            }

            $features[] = [
                'id' => $attribute->attribute_id,
                'name' => $attribute->attribute_label,
                'type' => $type,
                'type_name' => $type === 1 ? 'List' : ($type === 2 ? 'Color' : 'Image'),
            ];
        }

        wp_send_json_success($features);
    }

    public function getFeatureValues()
    {
        $attributes = wc_get_attribute_taxonomies();
        $featureValues = [];

        foreach ($attributes as $attribute) {
            $taxonomy = wc_attribute_taxonomy_name($attribute->attribute_name);
            $terms = get_terms([
                'taxonomy' => $taxonomy,
                'hide_empty' => false,
            ]);

            if (is_wp_error($terms)) {
                continue;
            }

            foreach ($terms as $term) {
                $featureValues[] = [
                    'feature_id' => $attribute->attribute_id,
                    'feature_name' => $attribute->attribute_label,
                    'term_id' => $term->term_id,
                    'name' => $term->name,
                ];
            }
        }

        wp_send_json_success($featureValues);
    }

    public function getProducts()
    {
        $args = [
            'post_type' => 'product',
            'posts_per_page' => -1,
            'post_status' => 'publish',
        ];

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

        foreach ($products as $product) {
            $result[] = [
                'id' => $product->ID,
                'name' => $product->post_title,
            ];
        }

        wp_send_json_success($result);
    }
}

