var app = angular.module('budgetApp', []);
console.log("budget.js loaded");
app.controller('BudgetController', function ($scope, $http) {
    $scope.budget = null;
    $scope.loading = false;
    $scope.error = null;
    $scope.menuOpen = false;

    const today = new Date();
    $scope.selectedYear = today.getFullYear();
    $scope.selectedMonth = today.getMonth() + 1;
    $scope.tempMonth = $scope.monthNames?.[today.getMonth()] || "";
    $scope.tempYear = $scope.selectedYear;

    $scope.monthNames = ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"];

    $scope.getMonthName = function (month) {
        return $scope.monthNames[month - 1] || "";
    };

    $scope.selectedMonthName = $scope.getMonthName($scope.selectedMonth);

    $scope.toggleMenu = function (e) {
        e.stopPropagation();
        $scope.menuOpen = !$scope.menuOpen;
    };
    $scope.menuVisible = false;
    $scope.menuItem = null;
    $scope.menuStyle = {};

    $scope.openItemMenu = function ($event, item) {
        const rect = $event.currentTarget.getBoundingClientRect();
        console.log("Menu position:", rect);

        $scope.menuItem = item;
        $scope.menuItem.category = $scope.budget.categories.find(c => c.items.includes(item));

        $scope.menuStyle = {
            top: `${rect.bottom + 4}px`,
            left: `${rect.left}px`
        };
        $scope.menuVisible = true;
    };

    $scope.setItemType = function (item, type) {
        if (type === 'expense') {
            item.isExpense = true;
            item.includeInSummary = true;
        } else if (type === 'income') {
            item.isExpense = false;
            item.includeInSummary = true;
        } else if (type === 'saving') {
            item.isExpense = false;
            item.includeInSummary = false;
        }
        $scope.menuVisible = false;
    };

    // Klick utanför stänger popup
    document.addEventListener('click', function (e) {
        const menu = document.querySelector('.item-floating-menu');
        if (menu && !$scope.menuVisible) return;

        const isInside = menu?.contains(e.target);
        const isButton = e.target.closest('.icon-button');

        if (!isInside && !isButton) {
            $scope.$apply(() => $scope.menuVisible = false);
        }
    });

    document.addEventListener('click', function () {
        $scope.$apply(() => {
            $scope.menuOpen = false;
        });
    });

    $scope.showToast = function (message, isError = false) {
        const toast = document.createElement("div");
        toast.className = "toast" + (isError ? " error" : "") + " show";
        toast.innerText = message;
        document.body.appendChild(toast);

        setTimeout(() => {
            toast.classList.remove("show");
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    };

    $scope.loadBudget = function () {
        $scope.loading = true;
        $scope.error = null;
        $scope.budget = null;

        $http.get(`/api/budget/${$scope.selectedYear}/${$scope.selectedMonth}`)
            .then(function (response) {
                const raw = response.data;
                if (raw && raw.Categories) {
                    const categories = raw.Categories.map(cat => ({
                        id: cat.Id,
                        name: cat.Name,
                        color: cat.Color,
                        editing: false,
                        allowDrag: false,
                        items: (cat.Items || []).map((item, index) => {
                            const definition = $scope.itemDefinitions.find(d => d.id === item.BudgetItemDefinitionId || d.Id === item.BudgetItemDefinitionId);
                            return {
                                id: item.Id,
                                name: item.Name,
                                amount: parseFloat(item.Amount),
                                isExpense: item.IsExpense === true,
                                includeInSummary: item.IncludeInSummary === true,
                                order: item.Order ?? index,
                                budgetItemDefinitionId: item.BudgetItemDefinitionId,
                                definitionName: definition?.Name || null
                            };
                        }).sort((a, b) => a.order - b.order)

                    }));

                    $scope.budget = {
                        id: raw.Id,
                        year: raw.Year,
                        month: raw.Month,
                        categories: categories.sort((a, b) => a.order - b.order)
                    };
                } else {
                    $scope.budget = { categories: [] };
                }
                $scope.selectedMonthName = $scope.getMonthName($scope.selectedMonth);
            })
            .catch(function (error) {
                if (error.status === 404) {
                    $scope.budget = { categories: [] };
                } else {
                    $scope.error = "Kunde inte ladda budgetdata.";
                    $scope.showToast("Fel vid laddning av budgetdata", true);
                    console.error("Budget API error:", error);
                }
            })
            .finally(function () {
                $scope.loading = false;
            });
    };

    $scope.saveCategory = function (category) {
        if (category.newItemName && category.newItemAmount) {
            const newItem = {
                name: category.newItemName,
                amount: parseFloat(category.newItemAmount),
                isExpense: true,
                includeInSummary: true,
                budgetCategoryId: category.id,
            };

            $http.post("/api/budget/item", newItem)
                .then(res => {
                    if (res.data && res.data.id) {
                        newItem.id = res.data.id;
                        category.items.push(newItem);
                        category.newItemName = "";
                        category.newItemAmount = "";
                        $scope.showToast("Post sparad!");
                    } else {
                        $scope.showToast("Fel vid sparande av ny post", true);
                    }
                });
        }

        const payload = {
            id: category.id,
            name: category.name,
            color: category.color,
            budgetCategoryDefinitionId: category.budgetCategoryDefinitionId || null,
            items: category.items.map((item, index) => ({
                id: item.id,
                name: item.name,
                amount: item.amount,
                isExpense: item.isExpense,
                includeInSummary: item.includeInSummary,
                budgetCategoryId: category.id,
                order: index
            }))
        };

        $http.put(`/api/budget/category/${category.id}`, payload)
            .then(() => {
                $scope.showToast("Kategori sparad!");
                category.editing = false; // ✅ flytta hit
            })
            .catch(() => {
                $scope.showToast("Fel vid sparande av kategori", true);
            });
    };

    $scope.deleteCategory = function (category) {
        if (!confirm("Vill du verkligen ta bort kategorin och alla dess poster?")) return;

        $http.delete(`/api/budget/category/${category.id}`)
            .then(() => {
                $scope.budget.categories = $scope.budget.categories.filter(c => c.id !== category.id);
                $scope.showToast("Kategori borttagen!");
            })
            .catch(err => {
                console.error("Fel vid borttagning av kategori:", err);
                $scope.showToast("Kunde inte ta bort kategori", true);
            });
    };
    $scope.copyPreviousMonthSafe = function () {
        console.log("click OK");

        $scope.menuOpen = false;
        setTimeout(function () {
            $scope.copyPreviousMonth();
        }, 10);
    };
    $scope.deleteMonth = function () {
        if (!confirm("Vill du verkligen ta bort alla data för denna månad?")) return;

        const year = $scope.selectedYear;
        const month = $scope.selectedMonth;

        $http.delete(`/api/budget/${year}/${month}`)
            .then(() => {
                $scope.showToast("Månad borttagen!");
                $scope.loadBudget(); // tömmer sidan
            })
            .catch(err => {
                console.error("Kunde inte ta bort månad:", err);
                $scope.showToast("Fel vid borttagning av månad", true);
            });
    };

    $scope.copyPreviousMonth = function () {
        if (!confirm("Vill du kopiera föregående månad till den aktuella?")) {
            return;
        }

        console.log("Försöker kopiera föregående månad...");

        const year = $scope.selectedYear;
        const month = $scope.selectedMonth;

        $http.post(`/api/budget/copy/${year}/${month}`)
            .then(() => {
                $scope.showToast("Föregående månad kopierad!");
                $scope.loadBudget();
            })
            .catch(err => {
                console.error("Kunde inte kopiera föregående månad:", err);
                if (err.status === 404) {
                    $scope.showToast("Ingen föregående månad att kopiera från", true);
                } else if (err.status === 400) {
                    $scope.showToast("Data finns redan för denna månad", true);
                } else {
                    $scope.showToast("Kunde inte kopiera", true);
                }
            });
    };

    $scope.cancelCategoryEdit = function (category) {
        category.editing = false;
    };

    function getItemsFlat() {
        if (!$scope.budget || !$scope.budget.categories) return [];
        return $scope.budget.categories.flatMap(c => c.items || []);
    }

    $scope.getCategorySum = function (category) {
        return (category.items || []).reduce((sum, i) => sum + i.amount, 0);
    };

    $scope.getTotalIncome = function () {
        return getItemsFlat().filter(i => !i.isExpense && i.includeInSummary).reduce((sum, i) => sum + i.amount, 0);
    };

    $scope.getTotalExpense = function () {
        return getItemsFlat().filter(i => i.isExpense && i.includeInSummary).reduce((sum, i) => sum + i.amount, 0);
    };

    $scope.getTotalSaving = function () {
        return getItemsFlat().filter(i => !i.isExpense && !i.includeInSummary).reduce((sum, i) => sum + i.amount, 0);
    };

    $scope.getLeftover = function () {
        return $scope.getTotalIncome() - $scope.getTotalExpense();
    };

    function positionAddItemPopup(popup, triggerButton) {
        const rect = popup.getBoundingClientRect();
        const bottomSpace = window.innerHeight - rect.bottom;

        // Om popupen sticker utanför skärmen, placera den ovanför
        if (bottomSpace < 50) {
            popup.classList.add('above');
        } else {
            popup.classList.remove('above');
        }
    }


    $scope.applyMonthSelection = function () {
        const monthIndex = $scope.monthNames.indexOf($scope.tempMonth);
        if (monthIndex >= 0 && $scope.tempYear) {
            $scope.selectedMonth = monthIndex + 1;
            $scope.selectedYear = parseInt($scope.tempYear);
            $scope.selectedMonthName = $scope.getMonthName($scope.selectedMonth);
            $scope.showMonthPicker = false;
            $scope.loadBudget();
        }
    };

    $scope.previousMonth = function () {
        if ($scope.selectedMonth === 1) {
            $scope.selectedMonth = 12;
            $scope.selectedYear--;
        } else {
            $scope.selectedMonth--;
        }
        $scope.tempMonth = $scope.getMonthName($scope.selectedMonth);
        $scope.tempYear = $scope.selectedYear;
        $scope.selectedMonthName = $scope.getMonthName($scope.selectedMonth);
        $scope.loadBudget();
    };

    $scope.nextMonth = function () {
        if ($scope.selectedMonth === 12) {
            $scope.selectedMonth = 1;
            $scope.selectedYear++;
        } else {
            $scope.selectedMonth++;
        }
        $scope.tempMonth = $scope.getMonthName($scope.selectedMonth);
        $scope.tempYear = $scope.selectedYear;
        $scope.selectedMonthName = $scope.getMonthName($scope.selectedMonth);
        $scope.loadBudget();
    };

    $scope.handleCategoryDrop = function (data, targetCategory) {
        if (data.type !== 'category') return; // ⛔ stoppa om det är ett item-drag

        const categories = $scope.budget.categories;
        const draggedIndex = categories.findIndex(c => c.id === data.categoryId);
        const targetIndex = categories.findIndex(c => c.id === targetCategory.id);

        if (draggedIndex === -1 || targetIndex === -1 || draggedIndex === targetIndex) return;

        const moved = categories.splice(draggedIndex, 1)[0];
        categories.splice(targetIndex, 0, moved);

        categories.forEach((cat, i) => {
            cat.order = i;
        });

        const payload = $scope.budget.categories.map(cat => ({
            id: cat.id,
            name: cat.name,
            color: cat.color,
            order: cat.order,
            year: $scope.selectedYear,
            month: $scope.selectedMonth,
            items: [] // tom lista – backend kräver den, men vi använder den inte här
        }));


        $http.put("/api/budget/category/order", payload)
            .then(() => $scope.showToast("Kategorier omordnade!"))
            .catch(() => $scope.showToast("Fel vid uppdatering av ordning", true));
    };

    $scope.handleItemDrop = function ({ data, targetCategory, targetIndex }) {
        const sourceCategory = $scope.budget.categories.find(c => c.id === data.fromCategoryId);
        const draggedItem = sourceCategory?.items.find(i => i.id === data.itemId);

        if (!draggedItem || !targetCategory) return;

        // Ta bort från ursprung
        const draggedIndex = sourceCategory.items.findIndex(i => i.id === draggedItem.id);
        if (draggedIndex !== -1) {
            sourceCategory.items.splice(draggedIndex, 1);
        }

        // Uppdatera värden
        draggedItem.budgetCategoryId = targetCategory.id;
        const indexToInsert = typeof targetIndex === 'number' ? targetIndex : targetCategory.items.length;
        targetCategory.items.splice(indexToInsert, 0, draggedItem);

        // Uppdatera ordning
        targetCategory.items.forEach((item, i) => {
            item.order = i;
        });

        // ✅ Skicka PUT för det flyttade itemet
        const payload = {
            id: draggedItem.id,
            name: draggedItem.name,
            amount: draggedItem.amount,
            isExpense: draggedItem.isExpense,
            includeInSummary: draggedItem.includeInSummary,
            order: draggedItem.order,
            budgetCategoryId: draggedItem.budgetCategoryId
        };

        $http.put(`/api/budget/item/${draggedItem.id}`, payload)
            .then(() => {
                console.log(">>> Sparad!");
                $scope.showToast("Post omplacerad!");
            })
            .catch(err => {
                console.error("Kunde inte uppdatera post:", err);
                $scope.showToast("Fel vid omplacering", true);
            });
    };

    $scope.handleItemPreciseDrop = function (data, targetCategory, targetIndex) {
        if (data.type !== 'item') return;

        const sourceCategory = $scope.budget.categories.find(c => c.id === data.fromCategoryId);
        const draggedItem = sourceCategory?.items.find(i => i.id === data.itemId);

        if (!draggedItem || !targetCategory) return;

        // Ta bort från ursprung
        const draggedIndex = sourceCategory.items.findIndex(i => i.id === draggedItem.id);
        if (draggedIndex !== -1) {
            sourceCategory.items.splice(draggedIndex, 1);
        }

        // Uppdatera kategori och lägg till på exakt plats
        draggedItem.budgetCategoryId = targetCategory.id;
        targetCategory.items.splice(targetIndex, 0, draggedItem);

        // Uppdatera ordning
        targetCategory.items.forEach((item, i) => {
            item.order = i;
        });

        // ✅ PUT för det flyttade itemet
        const payload = {
            id: draggedItem.id,
            name: draggedItem.name,
            amount: draggedItem.amount,
            isExpense: draggedItem.isExpense,
            includeInSummary: draggedItem.includeInSummary,
            order: draggedItem.order,
            budgetCategoryId: draggedItem.budgetCategoryId
        };

        $http.put(`/api/budget/item/${draggedItem.id}`, payload)
            .then(() => {
                console.log(">>> Sparad!");
                $scope.showToast("Post omplacerad!");
            })
            .catch(err => {
                console.error("Kunde inte uppdatera post:", err);
                $scope.showToast("Fel vid omplacering", true);
            });
    };
    $scope.updateItemType = function (item) {
        if (item.type === 'income') {
            item.isExpense = false;
            item.includeInSummary = true;
        } else if (item.type === 'expense') {
            item.isExpense = true;
            item.includeInSummary = true;
        } else if (item.type === 'saving') {
            item.isExpense = false;
            item.includeInSummary = false;
        }
    };
    $scope.setItemType = function (item, type) {
        if (type === 'income') {
            item.isExpense = false;
            item.includeInSummary = true;
        } else if (type === 'expense') {
            item.isExpense = true;
            item.includeInSummary = true;
        } else if (type === 'saving') {
            item.isExpense = false;
            item.includeInSummary = false;
        }
    };
    $scope.createNewCategory = function () {
        const defaultName = "Ny kategori";
        const newOrder = $scope.budget.categories.length; // sist i listan

        const newCategory = {
            name: defaultName,
            color: "#666666",
            year: $scope.selectedYear,
            month: $scope.selectedMonth,
            order: newOrder
        };

        $http.post("/api/budget/category", newCategory)
            .then(res => {
                if (res.data && res.data.id) {
                    $scope.budget.categories.push({
                        id: res.data.id,
                        name: defaultName,
                        color: "#666666",
                        order: newOrder,
                        items: [],
                        editing: true,
                        allowDrag: false
                    });
                    $scope.showToast("Kategori skapad!");
                } else {
                    $scope.showToast("Misslyckades med att skapa kategori", true);
                }
            })
            .catch(err => {
                console.error("Fel vid skapande av kategori:", err);
                $scope.showToast("Fel vid skapande av kategori", true);
            });
    };
    $scope.addItem = function (category) {
        if (!category.newItemName || !category.newItemAmount) return;

        const tempId = `temp-${Date.now()}-${Math.random()}`; // temporärt ID

        const newItem = {
            id: tempId,
            name: category.newItemName,
            amount: parseFloat(category.newItemAmount),
            isExpense: true,
            includeInSummary: true,
            budgetCategoryId: category.id
        };

        category.items.push(newItem);
        category.newItemName = "";
        category.newItemAmount = "";
    };
    $scope.deleteItem = function (category, item) {
        console.log("Försöker ta bort:", item);

        if (!item.id || item.id.toString().startsWith("temp-")) {
            // Ta bort direkt om det är ett nytt (osparat) item
            category.items = category.items.filter(i => i !== item);
            $scope.showToast("Ospard post togs bort");
            return;
        }

        if (!confirm("Vill du ta bort denna post?")) return;

        $http.delete(`/api/budget/item/${item.id}`)
            .then(() => {
                category.items = category.items.filter(i => i.id !== item.id);
                $scope.showToast("Post borttagen!");
            })
            .catch(err => {
                console.error("Fel vid borttagning av item:", err);
                $scope.showToast("Kunde inte ta bort posten", true);
            });
    };

    $scope.handleItemDrop = function (event, data, targetCategory) {
        console.log("Item drop received:", data, "to", targetCategory);
        // Hitta källkategorin
        const sourceCat = $scope.budget.categories.find(c => c.id === data.fromCategoryId);
        if (!sourceCat) return;
        const itemIndex = sourceCat.items.findIndex(i => i.id === data.itemId);
        if (itemIndex === -1) return;
        const [movedItem] = sourceCat.items.splice(itemIndex, 1);
        targetCategory.items.push(movedItem);
        $scope.$applyAsync();
    };
    $scope.handleItemPreciseDrop = function (data, targetCategory, targetIndex) {
        console.log("Precise drop at index", targetIndex);
        const sourceCat = $scope.budget.categories.find(c => c.id === data.fromCategoryId);
        if (!sourceCat) return;
        const itemIndex = sourceCat.items.findIndex(i => i.id === data.itemId);
        if (itemIndex === -1) return;
        const [movedItem] = sourceCat.items.splice(itemIndex, 1);
        targetCategory.items.splice(targetIndex, 0, movedItem);
        $scope.$applyAsync();
    };

    $scope.itemDefinitions = [];

    $scope.loadItemDefinitions = function () {
        return $http.get("/api/budget/definitions/items")
            .then(res => {
                console.log("Definitioner laddade:", res.data);
                $scope.itemDefinitions = res.data || [];
            });
    };
    $scope.getDefinitionName = function (item) {
        if (!item || !item.budgetItemDefinitionId) return null;
        const def = $scope.itemDefinitions.find(d => d.id === item.budgetItemDefinitionId);
        return def?.name || null;
    };
    $scope.addPopupAbove = false;
    $scope.openItemPopup = function ($event, category) {
        const trigger = $event.currentTarget;
        const rect = trigger.getBoundingClientRect();

        $scope.addPopupData = {
            category: category,
            newItemType: "expense",
            newItemDefinition: "",
            newItemLabel: "",
            newItemAmount: null
        };

        $scope.filteredDefinitions = [];
        $scope.addPopupVisible = true;

        // Vänta tills popup finns i DOM
        setTimeout(() => {
            const popup = document.querySelector('.add-item-popup');
            if (!popup) return;

            const popupHeight = popup.offsetHeight;
            const margin = 6;
            const spaceBelow = window.innerHeight - rect.bottom - margin;
            const spaceAbove = rect.top - margin;

            let top;
            let showAbove = false;

            if (spaceBelow >= popupHeight) {
                top = rect.bottom + margin;
            } else if (spaceAbove >= popupHeight) {
                top = rect.top - popupHeight - margin;
                showAbove = true;
            } else {
                // Får inte plats helt – välj bästa plats och justera top
                showAbove = spaceAbove > spaceBelow;
                top = showAbove
                    ? Math.max(0, rect.top - popupHeight - margin)
                    : rect.bottom + margin;
            }

            $scope.$apply(() => {
                $scope.addPopupStyle = {
                    position: "fixed",
                    top: `${top}px`,
                    left: `${rect.left}px`
                };
                $scope.addPopupAbove = showAbove;
            });
        }, 0);

        if (!$scope.itemDefinitions || $scope.itemDefinitions.length === 0) {
            $scope.loadItemDefinitions();
        }
    };


    $scope.addPopupVisible = false;
    $scope.addPopupStyle = {};
    $scope.addPopupData = {};
  
    $scope.filteredDefinitions = [];
    $scope.showDefinitionSuggestions = false;

    $scope.updateDefinitionSuggestions = function () {
        const term = $scope.addPopupData.newItemDefinition?.toLowerCase() || '';
        console.log("Sökterm:", term);

        $scope.filteredDefinitions = $scope.itemDefinitions.filter(d =>
            d.Name && d.Name.toLowerCase().includes(term)
        );

        $scope.showDefinitionSuggestions = true;
    };



    $scope.selectDefinitionSuggestion = function (name) {
        $scope.addPopupData.newItemDefinition = name;
        $scope.filteredDefinitions = [];
        $scope.showDefinitionSuggestions = false;
    };

    // För att inte stänga direkt vid klick
    let suggestionBlurTimeout;
    $scope.hideSuggestionsDelayed = function () {
        suggestionBlurTimeout = setTimeout(() => {
            $scope.$apply(() => {
                $scope.showDefinitionSuggestions = false;
            });
        }, 200);
    };
    document.addEventListener('click', function (e) {
        const popup = document.querySelector('.add-item-popup');
        const isInsidePopup = popup?.contains(e.target);
        const isButton = e.target.closest('.add-post-btn');

        if (!isInsidePopup && !isButton) {
            $scope.$apply(() => {
                $scope.addPopupVisible = false;
                $scope.filteredDefinitions = [];
            });
        }
    });

$scope.addItemFromDefinition = function (cat) {
    const definitionName = cat.newItemDefinition?.trim();
    const label = cat.newItemLabel?.trim();
    const amount = parseFloat(cat.newItemAmount);

    if (!definitionName || isNaN(amount)) return;

    const matched = $scope.itemDefinitions.find(d => d.name.toLowerCase() === definitionName.toLowerCase());

    const isExpense = cat.newItemType === "expense";
    const includeInSummary = cat.newItemType !== "saving";

    const item = {
        name: label || definitionName,
        amount: amount,
        isExpense: isExpense,
        includeInSummary: includeInSummary,
        budgetCategoryId: cat.id,
        budgetItemDefinitionId: matched?.id || null

    };

    $http.post("/api/budget/item", item).then(res => {
        item.id = res.data.id;
        cat.items.push(item);
        $scope.showToast("Post tillagd!");
        cat.addingItem = false;

        // Om det var ny definition – hämta listan på nytt
        if (!matched) $scope.loadItemDefinitions();
    });
    };

    $scope.addItemFromPopup = function () {
        const cat = $scope.addPopupData.category;
        const def = $scope.addPopupData.newItemDefinition?.trim();
        const label = $scope.addPopupData.newItemLabel?.trim();
        const amount = parseFloat($scope.addPopupData.newItemAmount);
        const type = $scope.addPopupData.newItemType;

        if (!def || isNaN(amount)) return;

        const matched = $scope.itemDefinitions.find(d => d.Name && d.Name.toLowerCase() === def.toLowerCase());

        const item = {
            name: label || def,
            amount: amount,
            isExpense: type === "expense",
            includeInSummary: type !== "saving",
            budgetCategoryId: cat.id,
            budgetItemDefinitionId: matched?.Id || null 
        };

        $http.post("/api/budget/item", item).then(res => {
            item.id = res.data.id;
            cat.items.push(item);
            $scope.showToast("Post tillagd!");
            $scope.addPopupVisible = false;
            if (!matched) $scope.loadItemDefinitions(); 
        });
    };


    $scope.loadItemDefinitions().then(() => {
        $scope.loadBudget();
    });
});
