/** @odoo-module **/

import { registry } from "@web/core/registry";
import { Component, useState, onWillStart, onMounted, useRef } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";

class CustomDashboard extends Component {
    static template = "sos_dashboard.DashboardTemplate";

    setup() {
        this.orm = useService("orm");
        this.action = useService("action");

        this.state = useState({
            isLoading: true,
            pendingCount: 0,
            dept_in_charge_pendingCount: 0,
            top_management_name_pendingCount: 0,
            po_pendingCount: 0,
            po_dept_in_charge_pendingCount: 0,
            po_top_management_name_pendingCount: 0,
            wo_pendingCount: 0,
            wo_dept_in_charge_pendingCount: 0,
            wo_top_management_name_pendingCount: 0,
            indentData: {
                labels: [],
                planned: [],
                completed: [],
                pending: [],
            },
            inventoryData: {
                labels: [],
                quantities: [],
            },
            // Store URLs for each model
            quickLinkUrls: {
                sos_fg: "/web#action=&model=sos_fg&view_type=list&cids=1",
                sos_material: "/web#action=&model=sos_material&view_type=list&cids=1",
                sos_report: "/web#action=&model=sos.report&view_type=list&cids=1",
                res_config_settings: "/web#action=&model=res.config.settings&view_type=form&cids=1",
            },
        });

        this.chartRef = useRef("indentChart");
        this.inventoryChartRef = useRef("inventoryChart");

        onWillStart(async () => {
            // Fetch URLs for quick links
            await this.fetchQuickLinkUrls();

            // Fetch dashboard data
            await Promise.all([
                this.getMonData(),
                this.getPoData(),
                this.getWoData(),
                this.getIndentData(),
                this.getInventoryData(),
            ]);
            this.state.isLoading = false;
        });

        onMounted(() => {
            setTimeout(() => {
                if (this.chartRef.el) {
                    this.renderChart();
                } else {
                    console.error("Indent Chart canvas not found in DOM");
                }
                if (this.inventoryChartRef.el) {
                    this.renderInventoryChart();
                } else {
                    console.error("Inventory Chart canvas not found in DOM");
                }
            }, 0);
        });
    }

    // Fetch action and menu IDs to construct URLs for quick links
    async fetchQuickLinkUrls() {
        const models = [
            { key: "sos_material", model: "sos_material", viewType: "list" },
            { key: "sos_ir", model: "sos_ir", viewType: "list" },
            { key: "sos_iqi", model: "sos_iqi", viewType: "list" },
            { key: "sos_fir", model: "sos_fir", viewType: "list" },
            { key: "sos_dc", model: "sos_dc", viewType: "list" },
            { key: "sos_dock_audit", model: "sos_dock_audit", viewType: "list" },
            { key: "sos_grn", model: "sos_grn", viewType: "list" },
            { key: "sos_ncmr", model: "sos_ncmr", viewType: "list" },
        ];
    
        try {
            // Step 1: Batch fetch all actions for the models in one ORM call
            const actions = await this.orm.searchRead(
                "ir.actions.act_window",
                [["res_model", "in", models.map(m => m.model)]],
                ["id", "res_model"]
            );
    
            // Create a map of model to action ID
            const actionMap = {};
            actions.forEach(action => {
                actionMap[action.res_model] = action.id;
            });
    
            // Step 2: Batch fetch all menus for the actions in one ORM call
            const actionIds = Object.values(actionMap);
            const menus = actionIds.length > 0
                ? await this.orm.searchRead(
                      "ir.ui.menu",
                      [["action", "in", actionIds.map(id => `ir.actions.act_window,${id}`)]],
                      ["id", "action"],
                      { limit: 1 } // Limit 1 per action
                  )
                : [];
    
            // Create a map of action ID to menu ID
            const menuMap = {};
            menus.forEach(menu => {
                const actionId = parseInt(menu.action.split(",")[1]);
                menuMap[actionId] = menu.id;
            });
    
            // Step 3: Construct URLs for all models
            models.forEach(({ key, model, viewType }) => {
                const actionId = actionMap[model];
                if (!actionId) {
                    this.state.quickLinkUrls[key] = `/web#action=&model=${model}&view_type=${viewType}&cids=1`;
                    return;
                }
                const menuId = menuMap[actionId];
                if (!menuId) {
                    this.state.quickLinkUrls[key] = `/web#action=${actionId}&model=${model}&view_type=${viewType}&cids=1`;
                    return;
                }
                const url = `/web#action=${actionId}&model=${model}&view_type=${viewType}&menu_id=${menuId}&cids=1`;
                this.state.quickLinkUrls[key] = url;
            });
            console.log("Generated URLs:", this.state.quickLinkUrls);
        } catch (error) {
            // Fallback URLs for all models in case of error
            models.forEach(({ key, model, viewType }) => {
                this.state.quickLinkUrls[key] = `/web#action=&model=${model}&view_type=${viewType}&cids=1`;
            });
            console.error("Error fetching quick link URLs:", error);
        }
    }

    async getMonData() {
        try {
            const [pendingCount, deptInChargePendingCount, topManagementPendingCount] = await Promise.all([
                this.orm.searchCount("sos_mon", [['status', '=', 'open']]),
                this.orm.searchCount("sos_mon", [['dept_in_charge_name', '=', false]]),
                this.orm.searchCount("sos_mon", [['top_management_name', '=', false]]),
            ]);
            this.state.pendingCount = pendingCount;
            this.state.dept_in_charge_pendingCount = deptInChargePendingCount;
            this.state.top_management_name_pendingCount = topManagementPendingCount;
        } catch (error) {
            console.error("Error loading sos_mon data:", error);
        }
    }

    async getPoData() {
        try {
            const [poPendingCount, poDeptInChargePendingCount, poTopManagementPendingCount] = await Promise.all([
                this.orm.searchCount("sos_po", [['po_status', '=', 'open']]),
                this.orm.searchCount("sos_po", [['stores_manager_approved_by', '=', false]]),
                this.orm.searchCount("sos_po", [['top_management_approved_by', '=', false]]),
            ]);
            this.state.po_pendingCount = poPendingCount;
            this.state.po_dept_in_charge_pendingCount = poDeptInChargePendingCount;
            this.state.po_top_management_name_pendingCount = poTopManagementPendingCount;
        } catch (error) {
            console.error("Error loading sos_po data:", error);
        }
    }

    async getWoData() {
        try {
            const [woPendingCount, woDeptInChargePendingCount, woTopManagementPendingCount] = await Promise.all([
                this.orm.searchCount("sos_wo", [['wo_status', '=', 'open']]),
                this.orm.searchCount("sos_wo", [['stores_manager_approved_by', '=', false]]),
                this.orm.searchCount("sos_wo", [['top_management_approved_by', '=', false]]),
            ]);
            this.state.wo_pendingCount = woPendingCount;
            this.state.wo_dept_in_charge_pendingCount = woDeptInChargePendingCount;
            this.state.wo_top_management_name_pendingCount = woTopManagementPendingCount;
        } catch (error) {
            console.error("Error loading sos_wo data:", error);
        }
    }

    async getIndentData() {
        try {
            const [totalRecords, completedRecords] = await Promise.all([
                this.orm.readGroup("sos_production_plan", [], ["plan_ref_no"], ["plan_ref_no"]),
                this.orm.readGroup("sos_production_plan", [["status", "=", "completed"]], ["plan_ref_no"], ["plan_ref_no"]),
            ]);

            const indentMap = {};
            totalRecords.forEach(record => {
                const indent = record.plan_ref_no;
                indentMap[indent] = { planned: record.plan_ref_no_count, completed: 0, pending: 0 };
            });

            completedRecords.forEach(record => {
                const indent = record.plan_ref_no;
                if (indentMap[indent]) {
                    indentMap[indent].completed = record.plan_ref_no_count;
                    indentMap[indent].pending = indentMap[indent].planned - indentMap[indent].completed;
                }
            });

            const indentKeys = Object.keys(indentMap).sort().slice(-5); 
            this.state.indentData.labels = indentKeys;
            this.state.indentData.planned = indentKeys.map(key => indentMap[key].planned);
            this.state.indentData.completed = indentKeys.map(key => indentMap[key].completed);
            this.state.indentData.pending = indentKeys.map(key => indentMap[key].pending);
        } catch (error) {
            console.error("Error loading indent data:", error);
        }
    }

    async getInventoryData() {
        try {
            const [materialQty, sfgQty, fgQty] = await Promise.all([
                this.orm.readGroup("sos_material", [], ["inhand_stock_qty:sum"], []),
                this.orm.readGroup("sos_sfg", [], ["inhand_stock_qty:sum"], []),
                this.orm.readGroup("sos_fg", [], ["inhand_stock_qty:sum"], []),
            ]);

            this.state.inventoryData.labels = ["Materials", "Semi-Finished Goods", "Finished Goods"];
            this.state.inventoryData.quantities = [
                materialQty[0]?.inhand_stock_qty || 0,
                sfgQty[0]?.inhand_stock_qty || 0,
                fgQty[0]?.inhand_stock_qty || 0,
            ];

            
        } catch (error) {
            console.error("Error loading inventory data:", error);
        }
    }

    renderChart() {
        const ctx = this.chartRef.el.getContext("2d");
        new Chart(ctx, {
            type: "bar",
            data: {
                labels: this.state.indentData.labels,
                datasets: [
                    {
                        label: "Planned FG",
                        data: this.state.indentData.planned,
                        backgroundColor: "rgba(255, 193, 7, 0.7)",
                        borderColor: "rgba(255, 193, 7, 1)",
                        borderWidth: 1,
                    },
                    {
                        label: "Completed FG",
                        data: this.state.indentData.completed,
                        backgroundColor: "rgba(40, 167, 69, 0.7)",
                        borderColor: "rgba(40, 167, 69, 1)",
                        borderWidth: 1,
                    },
                    {
                        label: "Pending FG",
                        data: this.state.indentData.pending,
                        backgroundColor: "rgba(255, 99, 132, 0.7)",
                        borderColor: "rgba(255, 99, 132, 1)",
                        borderWidth: 1,
                    },
                ],
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    x: { title: { display: true, text: "Indents" } },
                    y: { beginAtZero: true, title: { display: true, text: "Quantity" } },
                },
                plugins: {
                    legend: { position: "top" },
                    title: { display: true, text: "Indent Progress" },
                },
            },
        });
    }

    renderInventoryChart() {
        const ctx = this.inventoryChartRef.el.getContext("2d");
        new Chart(ctx, {
            type: "pie",
            data: {
                labels: this.state.inventoryData.labels,
                datasets: [
                    {
                        label: "In-Hand Quantity",
                        data: this.state.inventoryData.quantities,
                        backgroundColor: [
                            "rgba(255, 99, 132, 0.7)",
                            "rgba(54, 162, 235, 0.7)",
                            "rgba(75, 192, 192, 0.7)",
                        ],
                        borderColor: [
                            "rgba(255, 99, 132, 1)",
                            "rgba(54, 162, 235, 1)",
                            "rgba(75, 192, 192, 1)",
                        ],
                        borderWidth: 1,
                    },
                ],
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: { position: "top" },
                    title: { display: true, text: "Inventory In-Hand Quantity" },
                },
            },
        });
    }

    async openRecords() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Status - Open Records",
            res_model: "sos_mon",
            views: [[false, "list"], [false, "form"]],
            domain: [['status', '=', 'open']],
            target: "current",
        });
    }

    async po_openRecords() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Status - Open Records",
            res_model: "sos_po",
            views: [[false, "list"], [false, "form"]],
            domain: [['po_status', '=', 'open']],
            target: "current",
        });
    }

    async wo_openRecords() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Status - Open Records",
            res_model: "sos_wo",
            views: [[false, "list"], [false, "form"]],
            domain: [['wo_status', '=', 'open']],
            target: "current",
        });
    }

    async dept_incharge_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Dept Incharge approval pending MON Records",
            res_model: "sos_mon",
            views: [[false, "list"], [false, "form"]],
            domain: [['dept_in_charge_name', '=', false]],
            target: "current",
        });
    }

    async po_dept_incharge_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Dept Incharge approval pending PO Records",
            res_model: "sos_po",
            views: [[false, "list"], [false, "form"]],
            domain: [['stores_manager_approved_by', '=', false]],
            target: "current",
        });
    }

    async wo_dept_incharge_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Dept Incharge approval pending WO Records",
            res_model: "sos_wo",
            views: [[false, "list"], [false, "form"]],
            domain: [['stores_manager_approved_by', '=', false]],
            target: "current",
        });
    }

    async top_managment_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Top Management approval pending MON Records",
            res_model: "sos_mon",
            views: [[false, "list"], [false, "form"]],
            domain: [['top_management_name', '=', false]],
            target: "current",
        });
    }

    async po_top_managment_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Top Management approval pending PO Records",
            res_model: "sos_po",
            views: [[false, "list"], [false, "form"]],
            domain: [['top_management_approved_by', '=', false]],
            target: "current",
        });
    }

    async wo_top_managment_pending_Records() {
        await this.action.doAction({
            type: "ir.actions.act_window",
            name: "Top Management approval pending WO Records",
            res_model: "sos_wo",
            views: [[false, "list"], [false, "form"]],
            domain: [['top_management_approved_by', '=', false]],
            target: "current",
        });
    }
}

registry.category("actions").add("custom_dashboard_action", CustomDashboard);