/** @odoo-module **/

import { Component, useState, onWillStart } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { rpc } from "@web/core/network/rpc";
import { AjaxSearch } from "./ajax_search";

/**
 * ProductMapping — OWL client action for the WooCommerce product mapping UI.
 *
 * Three tabs:
 *   1. Mapped Products     — searchable table, bulk actions
 *   2. Unmatched Products  — split view Odoo | WC, map/create/ignore actions
 *   3. Conflicts           — table with Use Odoo / Use WC buttons
 */
export class ProductMapping extends Component {
    static template = "fusion_woocommerce.ProductMapping";
    static components = { AjaxSearch };
    static props = ["action", "*"];

    setup() {
        this.actionService = useService("action");
        this.notification = useService("notification");

        this.state = useState({
            // UI state
            activeTab: "mapped",
            loading: false,

            // Instance selector
            instances: [],
            instanceId: false,

            // Stats
            mappedCount: 0,
            unmappedCount: 0,
            conflictCount: 0,

            // Mapped tab
            mappedProducts: [],
            selectedMapped: [],
            mappedPage: 1,
            mappedTotal: 0,

            // Inline price editing
            editingCell: null,  // { mapId: int, field: 'woo_regular'|'woo_sale'|'odoo_price' }
            editValue: '',

            // Unmatched tab
            odooProducts: [],
            wooProducts: [],
            selectedOdooId: false,
            selectedWooId: false,
            unmatchedOdooPage: 1,
            unmatchedOdooTotal: 0,
            unmatchedWooPage: 1,
            unmatchedWooTotal: 0,

            // Pagination
            pageSize: 50,

            // Category filters
            categoryFilterActive: true,
            excludedCategoryCount: 0,

            // Conflicts tab
            conflicts: [],
        });

        onWillStart(async () => {
            await this._loadInstances();
            await this._loadExcludedCategoryCount();
            await this._refreshAll();
        });
    }

    // -------------------------------------------------------------------------
    // Data loaders
    // -------------------------------------------------------------------------

    async _loadInstances() {
        try {
            const result = await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "search_read",
                args: [[]],
                kwargs: { fields: ["id", "name", "state"], limit: 50 },
            });
            this.state.instances = result || [];
            if (result && result.length === 1) {
                this.state.instanceId = result[0].id;
            }
        } catch (err) {
            console.error("[ProductMapping] _loadInstances error:", err);
        }
    }

    async _refreshAll() {
        this.state.loading = true;
        try {
            await Promise.all([
                this._loadMapped(),
                this._loadOdooProducts(""),
                this._loadWooProducts(""),
                this._loadConflicts(),
                this._loadStats(),
            ]);
        } finally {
            this.state.loading = false;
        }
    }

    async _loadMapped(query = "") {
        try {
            const params = {
                query,
                limit: this.state.pageSize,
                offset: (this.state.mappedPage - 1) * this.state.pageSize,
            };
            if (this.state.instanceId) {
                params.instance_id = this.state.instanceId;
            }
            const result = await rpc("/woo/search/mapped", params);
            this.state.mappedProducts = (result && result.results) || [];
            this.state.mappedTotal = (result && result.total) || 0;
            this.state.selectedMapped = [];
        } catch (err) {
            console.error("[ProductMapping] _loadMapped error:", err);
        }
    }

    async _loadExcludedCategoryCount() {
        if (!this.state.instanceId) {
            this.state.excludedCategoryCount = 0;
            return;
        }
        try {
            const result = await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "read",
                args: [[this.state.instanceId], ["excluded_category_ids"]],
                kwargs: {},
            });
            if (result && result[0]) {
                this.state.excludedCategoryCount = (result[0].excluded_category_ids || []).length;
            }
        } catch (err) {
            console.error("[ProductMapping] _loadExcludedCategoryCount error:", err);
        }
    }

    async _loadOdooProducts(query = "") {
        try {
            const params = {
                query,
                limit: this.state.pageSize,
                offset: (this.state.unmatchedOdooPage - 1) * this.state.pageSize,
            };
            if (this.state.instanceId) {
                params.instance_id = this.state.instanceId;
            }
            // Pass excluded categories if filter is active
            if (this.state.categoryFilterActive && this.state.instanceId) {
                params.apply_excluded = true;
            }
            const result = await rpc("/woo/search/odoo_products", params);
            this.state.odooProducts = (result && result.results) || [];
            this.state.unmatchedOdooTotal = (result && result.total) || 0;
        } catch (err) {
            console.error("[ProductMapping] _loadOdooProducts error:", err);
        }
    }

    async _loadWooProducts(query = "") {
        try {
            const params = {
                query,
                limit: this.state.pageSize,
                offset: (this.state.unmatchedWooPage - 1) * this.state.pageSize,
            };
            if (this.state.instanceId) {
                params.instance_id = this.state.instanceId;
            }
            const result = await rpc("/woo/search/woo_products", params);
            this.state.wooProducts = (result && result.results) || [];
            this.state.unmatchedWooTotal = (result && result.total) || 0;
        } catch (err) {
            console.error("[ProductMapping] _loadWooProducts error:", err);
        }
    }

    async _loadConflicts() {
        try {
            const domain = [["resolution", "=", "pending"]];
            if (this.state.instanceId) {
                domain.push(["instance_id", "=", this.state.instanceId]);
            }
            const result = await rpc("/web/dataset/call_kw", {
                model: "woo.conflict",
                method: "search_read",
                args: [domain],
                kwargs: {
                    fields: [
                        "id", "conflict_type", "field_name",
                        "odoo_value", "woo_value", "resolution",
                        "instance_id",
                    ],
                    limit: 100,
                },
            });
            this.state.conflicts = result || [];
            this.state.conflictCount = this.state.conflicts.length;
        } catch (err) {
            console.error("[ProductMapping] _loadConflicts error:", err);
        }
    }

    async _loadStats() {
        try {
            const base = this.state.instanceId
                ? [["instance_id", "=", this.state.instanceId]]
                : [];

            const [mapped, unmapped] = await Promise.all([
                rpc("/web/dataset/call_kw", {
                    model: "woo.product.map",
                    method: "search_count",
                    args: [[...base, ["state", "=", "mapped"]]],
                    kwargs: {},
                }),
                rpc("/web/dataset/call_kw", {
                    model: "woo.product.map",
                    method: "search_count",
                    args: [[...base, ["state", "=", "unmapped"]]],
                    kwargs: {},
                }),
            ]);

            this.state.mappedCount = mapped || 0;
            this.state.unmappedCount = unmapped || 0;
        } catch (err) {
            console.error("[ProductMapping] _loadStats error:", err);
        }
    }

    // -------------------------------------------------------------------------
    // Helpers
    // -------------------------------------------------------------------------

    formatPrice(val) {
        if (val === null || val === undefined || val === false) return "—";
        const n = parseFloat(val);
        if (isNaN(n)) return "—";
        return "$" + n.toFixed(2);
    }

    calcMargin(cost, price) {
        const c = parseFloat(cost) || 0;
        const p = parseFloat(price) || 0;
        if (p <= 0 || c <= 0) return null;
        return ((p - c) / p) * 100;
    }

    formatMargin(cost, price) {
        const m = this.calcMargin(cost, price);
        if (m === null) return "—";
        return Math.round(m) + "%";
    }

    // -------------------------------------------------------------------------
    // Tab handlers
    // -------------------------------------------------------------------------

    setTab(tab) {
        this.state.activeTab = tab;
    }

    // -------------------------------------------------------------------------
    // Instance selector
    // -------------------------------------------------------------------------

    async onInstanceChange(ev) {
        const val = ev.target.value;
        this.state.instanceId = val ? parseInt(val, 10) : false;
        this.state.mappedPage = 1;
        this.state.unmatchedOdooPage = 1;
        this.state.unmatchedWooPage = 1;
        await this._refreshAll();
    }

    // -------------------------------------------------------------------------
    // Category filter
    // -------------------------------------------------------------------------

    async openCategoryFilter() {
        if (!this.state.instanceId) {
            this.notification.add("Select an instance first.", { type: "warning" });
            return;
        }
        this.actionService.doAction({
            type: 'ir.actions.act_window',
            res_model: 'woo.category.filter',
            views: [[false, 'form']],
            target: 'new',
            context: {
                default_instance_id: this.state.instanceId,
            },
        }, {
            onClose: async () => {
                await this._loadExcludedCategoryCount();
                this.state.unmatchedOdooPage = 1;
                await this._loadOdooProducts("");
            },
        });
    }

    async toggleCategoryFilter() {
        this.state.categoryFilterActive = !this.state.categoryFilterActive;
        this.state.unmatchedOdooPage = 1;
        await this._loadOdooProducts("");
    }

    // -------------------------------------------------------------------------
    // Mapped tab
    // -------------------------------------------------------------------------

    onMappedResults(results) {
        if (results && results.results) {
            this.state.mappedProducts = results.results;
            this.state.mappedTotal = results.total || 0;
        } else {
            this.state.mappedProducts = results || [];
        }
    }

    toggleSelectMapped(id) {
        const idx = this.state.selectedMapped.indexOf(id);
        if (idx >= 0) {
            this.state.selectedMapped.splice(idx, 1);
        } else {
            this.state.selectedMapped.push(id);
        }
    }

    toggleSelectAllMapped(ev) {
        if (ev.target.checked) {
            this.state.selectedMapped = this.state.mappedProducts.map((p) => p.id);
        } else {
            this.state.selectedMapped = [];
        }
    }

    isMappedSelected(id) {
        return this.state.selectedMapped.includes(id);
    }

    async unmapSelected() {
        if (!this.state.selectedMapped.length) return;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "write",
                args: [this.state.selectedMapped, { state: "unmapped", product_id: false }],
                kwargs: {},
            });
            this.notification.add("Products unmapped successfully.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] unmapSelected error:", err);
            this.notification.add("Failed to unmap products.", { type: "danger" });
        }
    }

    async syncSelected() {
        if (!this.state.selectedMapped.length) return;
        this.notification.add("Sync queued for selected products.", { type: "info" });
    }

    async togglePriceSync(mapId, current) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "write",
                args: [[mapId], { sync_price: !current }],
                kwargs: {},
            });
            await this._loadMapped();
        } catch (err) {
            console.error("[ProductMapping] togglePriceSync error:", err);
        }
    }

    async toggleInventorySync(mapId, current) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "write",
                args: [[mapId], { sync_inventory: !current }],
                kwargs: {},
            });
            await this._loadMapped();
        } catch (err) {
            console.error("[ProductMapping] toggleInventorySync error:", err);
        }
    }

    // -------------------------------------------------------------------------
    // Unmatched tab
    // -------------------------------------------------------------------------

    onOdooResults(results) {
        let items = results;
        if (results && results.results) {
            items = results.results;
            this.state.unmatchedOdooTotal = results.total || 0;
        }
        this.state.odooProducts = items || [];
        if (!this.state.odooProducts.find((r) => r.id === this.state.selectedOdooId)) {
            this.state.selectedOdooId = false;
        }
    }

    onWooResults(results) {
        let items = results;
        if (results && results.results) {
            items = results.results;
            this.state.unmatchedWooTotal = results.total || 0;
        }
        this.state.wooProducts = items || [];
        if (!this.state.wooProducts.find((r) => r.id === this.state.selectedWooId)) {
            this.state.selectedWooId = false;
        }
    }

    selectOdoo(id) {
        this.state.selectedOdooId = this.state.selectedOdooId === id ? false : id;
    }

    selectWoo(id) {
        this.state.selectedWooId = this.state.selectedWooId === id ? false : id;
    }

    get canMap() {
        return this.state.selectedOdooId && this.state.selectedWooId;
    }

    async mapSelected() {
        if (!this.canMap) return;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "write",
                args: [
                    [this.state.selectedWooId],
                    {
                        product_id: this.state.selectedOdooId,
                        state: "mapped",
                    },
                ],
                kwargs: {},
            });
            this.notification.add("Products mapped successfully.", { type: "success" });
            this.state.selectedOdooId = false;
            this.state.selectedWooId = false;
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] mapSelected error:", err);
            this.notification.add("Failed to map products.", { type: "danger" });
        }
    }

    async createInWC(odooProductId) {
        if (!this.state.instanceId) {
            this.notification.add("Please select an instance first.", { type: "warning" });
            return;
        }
        this.actionService.doAction({
            type: 'ir.actions.act_window',
            res_model: 'woo.product.create.wizard',
            views: [[false, 'form']],
            target: 'new',
            context: {
                default_instance_id: this.state.instanceId,
                default_odoo_product_id: odooProductId,
            },
        }, {
            onClose: async () => {
                await this._refreshAll();
            },
        });
    }

    async createInOdoo(wooMapId) {
        this.notification.add("Create in Odoo queued.", { type: "info" });
    }

    async ignoreWoo(wooMapId) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "write",
                args: [[wooMapId], { state: "error" }],
                kwargs: {},
            });
            this.notification.add("WooCommerce product ignored.", { type: "warning" });
            await this._loadWooProducts("");
        } catch (err) {
            console.error("[ProductMapping] ignoreWoo error:", err);
        }
    }

    // -------------------------------------------------------------------------
    // Conflicts tab
    // -------------------------------------------------------------------------

    async resolveConflict(conflictId, resolution) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.conflict",
                method: "write",
                args: [[conflictId], { resolution }],
                kwargs: {},
            });
            this.notification.add("Conflict resolved.", { type: "success" });
            await this._loadConflicts();
        } catch (err) {
            console.error("[ProductMapping] resolveConflict error:", err);
            this.notification.add("Failed to resolve conflict.", { type: "danger" });
        }
    }

    async resolveAllConflicts(resolution) {
        const ids = this.state.conflicts.map((c) => c.id);
        if (!ids.length) return;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.conflict",
                method: "write",
                args: [ids, { resolution }],
                kwargs: {},
            });
            this.notification.add(`All conflicts resolved using ${resolution === "use_odoo" ? "Odoo" : "WooCommerce"} values.`, { type: "success" });
            await this._loadConflicts();
        } catch (err) {
            console.error("[ProductMapping] resolveAllConflicts error:", err);
        }
    }

    // -------------------------------------------------------------------------
    // Pagination — Mapped
    // -------------------------------------------------------------------------

    _calcTotalPages(total) {
        return Math.max(1, Math.ceil(total / this.state.pageSize));
    }

    get mappedTotalPages() {
        return this._calcTotalPages(this.state.mappedTotal);
    }

    async mappedNextPage() {
        if (this.state.mappedPage < this.mappedTotalPages) {
            this.state.mappedPage++;
            await this._loadMapped();
        }
    }

    async mappedPrevPage() {
        if (this.state.mappedPage > 1) {
            this.state.mappedPage--;
            await this._loadMapped();
        }
    }

    // -------------------------------------------------------------------------
    // Pagination — Unmatched Odoo
    // -------------------------------------------------------------------------

    get unmatchedOdooTotalPages() {
        return this._calcTotalPages(this.state.unmatchedOdooTotal);
    }

    async unmatchedOdooNextPage() {
        if (this.state.unmatchedOdooPage < this.unmatchedOdooTotalPages) {
            this.state.unmatchedOdooPage++;
            await this._loadOdooProducts("");
        }
    }

    async unmatchedOdooPrevPage() {
        if (this.state.unmatchedOdooPage > 1) {
            this.state.unmatchedOdooPage--;
            await this._loadOdooProducts("");
        }
    }

    // -------------------------------------------------------------------------
    // Pagination — Unmatched WC
    // -------------------------------------------------------------------------

    get unmatchedWooTotalPages() {
        return this._calcTotalPages(this.state.unmatchedWooTotal);
    }

    async unmatchedWooNextPage() {
        if (this.state.unmatchedWooPage < this.unmatchedWooTotalPages) {
            this.state.unmatchedWooPage++;
            await this._loadWooProducts("");
        }
    }

    async unmatchedWooPrevPage() {
        if (this.state.unmatchedWooPage > 1) {
            this.state.unmatchedWooPage--;
            await this._loadWooProducts("");
        }
    }

    // -------------------------------------------------------------------------
    // Inline price editing
    // -------------------------------------------------------------------------

    startEdit(mapId, field, currentValue) {
        this.state.editingCell = { mapId, field };
        let val = currentValue !== null && currentValue !== undefined ? currentValue : '';
        const isSkuField = field === 'wc_sku' || field === 'odoo_sku';
        if (!isSkuField) {
            if (val !== '' && field === 'margin') {
                val = String(Math.round(parseFloat(val)));
            } else if (val !== '') {
                val = String(parseFloat(parseFloat(val).toFixed(2)));
            }
        }
        this.state.editValue = String(val);
        // Focus the input after OWL re-renders
        setTimeout(() => {
            const input = document.querySelector('.woo-edit-input');
            if (input) { input.focus(); input.select(); }
        }, 50);
    }

    cancelEdit() {
        this.state.editingCell = null;
        this.state.editValue = '';
    }

    onEditInput(ev) {
        this.state.editValue = ev.target.value;
    }

    async onEditKeydown(ev) {
        if (ev.key === 'Enter') {
            await this.saveEdit();
        } else if (ev.key === 'Escape') {
            this.cancelEdit();
        }
    }

    async onEditBlur() {
        await this.saveEdit();
    }

    isEditing(mapId, field) {
        return this.state.editingCell &&
               this.state.editingCell.mapId === mapId &&
               this.state.editingCell.field === field;
    }

    async saveEdit() {
        const cell = this.state.editingCell;
        if (!cell) return;

        const rawValue = this.state.editValue;
        const isSkuField = cell.field === 'wc_sku' || cell.field === 'odoo_sku';

        if (!isSkuField) {
            const value = parseFloat(rawValue);
            if (isNaN(value) || value < 0) {
                this.notification.add("Invalid price value.", { type: "danger" });
                this.cancelEdit();
                return;
            }
        }

        // Cancel first so blur doesn't fire a second save after Enter
        this.cancelEdit();

        try {
            if (isSkuField) {
                const skuValue = String(rawValue || '');
                if (cell.field === 'wc_sku') {
                    await rpc("/web/dataset/call_kw", {
                        model: "woo.product.map",
                        method: "action_set_wc_sku",
                        args: [[cell.mapId], skuValue],
                        kwargs: {},
                    });
                } else if (cell.field === 'odoo_sku') {
                    const product = this.state.mappedProducts.find(p => p.id === cell.mapId);
                    if (product && product.odoo_product_id) {
                        await rpc("/web/dataset/call_kw", {
                            model: "product.product",
                            method: "write",
                            args: [[product.odoo_product_id], { default_code: skuValue }],
                            kwargs: {},
                        });
                    }
                }
                this.notification.add("SKU updated.", { type: "success" });
                await this._loadMapped();
                return;
            }

            const value = parseFloat(rawValue);
            if (cell.field === 'woo_regular') {
                await rpc("/web/dataset/call_kw", {
                    model: "woo.product.map",
                    method: "action_set_regular_price",
                    args: [[cell.mapId], value],
                    kwargs: {},
                });
            } else if (cell.field === 'woo_sale') {
                await rpc("/web/dataset/call_kw", {
                    model: "woo.product.map",
                    method: "action_set_sale_price",
                    args: [[cell.mapId], value],
                    kwargs: {},
                });
            } else if (cell.field === 'odoo_price') {
                const product = this.state.mappedProducts.find(p => p.id === cell.mapId);
                if (product && product.odoo_product_id) {
                    await rpc("/web/dataset/call_kw", {
                        model: "product.product",
                        method: "write",
                        args: [[product.odoo_product_id], { list_price: value }],
                        kwargs: {},
                    });
                }
            } else if (cell.field === 'odoo_cost') {
                const product = this.state.mappedProducts.find(p => p.id === cell.mapId);
                if (product && product.odoo_product_id) {
                    await rpc("/web/dataset/call_kw", {
                        model: "product.product",
                        method: "write",
                        args: [[product.odoo_product_id], { standard_price: value }],
                        kwargs: {},
                    });
                }
            } else if (cell.field === 'margin') {
                // Margin edit: calculate new sale price from cost and desired margin
                const product = this.state.mappedProducts.find(p => p.id === cell.mapId);
                if (product && product.odoo_product_id) {
                    const cost = parseFloat(product.odoo_cost) || 0;
                    if (cost <= 0) {
                        this.notification.add("Cannot calculate price: cost is zero.", { type: "danger" });
                        await this._loadMapped();
                        return;
                    }
                    if (value >= 100) {
                        this.notification.add("Margin cannot be 100% or more.", { type: "danger" });
                        await this._loadMapped();
                        return;
                    }
                    // price = cost / (1 - margin/100)
                    const newPrice = cost / (1 - value / 100);
                    const rounded = Math.round(newPrice * 100) / 100;
                    await rpc("/web/dataset/call_kw", {
                        model: "product.product",
                        method: "write",
                        args: [[product.odoo_product_id], { list_price: rounded }],
                        kwargs: {},
                    });
                    this.notification.add("Sale price set to $" + rounded.toFixed(2) + " (" + Math.round(value) + "% margin).", { type: "success" });
                    await this._loadMapped();
                    return;
                }
            }
            this.notification.add("Price updated.", { type: "success" });
        } catch (err) {
            console.error("[ProductMapping] saveEdit error:", err);
            this.notification.add(err.message || "Failed to update price.", { type: "danger" });
        }

        await this._loadMapped();
    }

    // -------------------------------------------------------------------------
    // Individual price sync
    // -------------------------------------------------------------------------

    async pushPriceToOdoo(mapId) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "action_push_price_to_odoo",
                args: [[mapId]],
                kwargs: {},
            });
            this.notification.add("WC price pushed to Odoo.", { type: "success" });
            await this._loadMapped();
        } catch (err) {
            console.error("[ProductMapping] pushPriceToOdoo error:", err);
            this.notification.add("Failed to push price to Odoo.", { type: "danger" });
        }
    }

    async pushPriceToWC(mapId) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "action_push_price_to_wc",
                args: [[mapId]],
                kwargs: {},
            });
            this.notification.add("Odoo price pushed to WC.", { type: "success" });
            await this._loadMapped();
        } catch (err) {
            console.error("[ProductMapping] pushPriceToWC error:", err);
            this.notification.add("Failed to push price to WC.", { type: "danger" });
        }
    }

    // -------------------------------------------------------------------------
    // Individual SKU sync
    // -------------------------------------------------------------------------

    async pushSkuToOdoo(mapId) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "action_push_sku_to_odoo",
                args: [[mapId]],
                kwargs: {},
            });
            this.notification.add("WC SKU pushed to Odoo.", { type: "success" });
            await this._loadMapped();
        } catch (err) {
            this.notification.add(err.message || "Failed.", { type: "danger" });
        }
    }

    async pushSkuToWC(mapId) {
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.product.map",
                method: "action_push_sku_to_wc",
                args: [[mapId]],
                kwargs: {},
            });
            this.notification.add("Odoo SKU pushed to WC.", { type: "success" });
            await this._loadMapped();
        } catch (err) {
            this.notification.add(err.message || "Failed.", { type: "danger" });
        }
    }

    // -------------------------------------------------------------------------
    // Bulk price sync
    // -------------------------------------------------------------------------

    async bulkPriceOdooToWC() {
        if (!this.state.instanceId) {
            this.notification.add("Select an instance.", { type: "warning" });
            return;
        }
        this.state.loading = true;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_bulk_price_odoo_to_wc",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("All Odoo prices pushed to WooCommerce.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] bulkPriceOdooToWC error:", err);
            this.notification.add("Bulk price sync failed.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    async bulkPriceWCToOdoo() {
        if (!this.state.instanceId) {
            this.notification.add("Select an instance.", { type: "warning" });
            return;
        }
        this.state.loading = true;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_bulk_price_wc_to_odoo",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("All WC prices pulled to Odoo.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] bulkPriceWCToOdoo error:", err);
            this.notification.add("Bulk price sync failed.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    // -------------------------------------------------------------------------
    // Bulk SKU sync
    // -------------------------------------------------------------------------

    async bulkSkuOdooToWC() {
        if (!this.state.instanceId) { this.notification.add("Select an instance.", { type: "warning" }); return; }
        this.state.loading = true;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_bulk_sku_odoo_to_wc",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("All Odoo SKUs pushed to WooCommerce.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            this.notification.add("Bulk SKU sync failed.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    async bulkSkuWCToOdoo() {
        if (!this.state.instanceId) { this.notification.add("Select an instance.", { type: "warning" }); return; }
        this.state.loading = true;
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_bulk_sku_wc_to_odoo",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("All WC SKUs pulled to Odoo.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            this.notification.add("Bulk SKU sync failed.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    // -------------------------------------------------------------------------
    // Top bar actions
    // -------------------------------------------------------------------------

    async fetchProducts() {
        if (!this.state.instanceId) {
            this.notification.add("Please select an instance first.", { type: "warning" });
            return;
        }
        try {
            this.state.loading = true;
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_fetch_products",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("Product fetch started.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] fetchProducts error:", err);
            this.notification.add("Failed to fetch products.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    async refreshPrices() {
        if (!this.state.instanceId) {
            this.notification.add("Please select an instance first.", { type: "warning" });
            return;
        }
        try {
            this.state.loading = true;
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_refresh_prices",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("Prices refreshed from WooCommerce.", { type: "success" });
            await this._refreshAll();
        } catch (err) {
            console.error("[ProductMapping] refreshPrices error:", err);
            this.notification.add("Failed to refresh prices.", { type: "danger" });
        } finally {
            this.state.loading = false;
        }
    }

    async syncNow() {
        if (!this.state.instanceId) {
            this.notification.add("Please select an instance first.", { type: "warning" });
            return;
        }
        try {
            await rpc("/web/dataset/call_kw", {
                model: "woo.instance",
                method: "action_sync",
                args: [[this.state.instanceId]],
                kwargs: {},
            });
            this.notification.add("Sync started.", { type: "success" });
        } catch (err) {
            console.error("[ProductMapping] syncNow error:", err);
            this.notification.add("Failed to start sync.", { type: "danger" });
        }
    }
}

registry.category("actions").add("fusion_woocommerce.product_mapping", ProductMapping);
