'use strict';

const llmApp = angular.module('agenthub.module', []);

llmApp.constant('PLUGIN_PATHS', {
    WEBAPP: '/plugins/agent-hub/resource/custom-ui-settings/'
});

// -------------  Parent Controller & Its helper directive --------------------


llmApp.controller('LLMConfigController', ['$scope', '$timeout', 'PythonService', 'DataikuAPI', 'DescParamsService', '$q', '$window', '$stateParams', '$http', 'PLUGIN_PATHS', function ($scope, $timeout, PythonService, DataikuAPI, DescParamsService, $q, $window, $stateParams, $http, PLUGIN_PATHS) {

    // Initialize sections array
    $scope.sections = [];
    $scope.selectedSection = null;

    // Function to convert displayName to camelCase
    function toCamelCase(str) {
        return str
            .split(' ')
            .map((word, index) =>
                index === 0
                    ? word.toLowerCase()
                    : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
            )
            .join('');
    }

    // Function to process sections from JSON
    function processSections(sections) {
        return sections.map(section => {
            const id = toCamelCase(section.displayName);
            return {
                id: id,
                displayName: section.displayName,
                formName: id + 'SubForm'
            };
        });
    }

    // Load sections from JSON file
    $http.get(PLUGIN_PATHS.WEBAPP + 'sections.json')
        .then(function (response) {
            $scope.sections = processSections(response.data);
            $scope.selectedSection = $scope.sections[0].id;
        })
        .catch(function (error) {
            console.error('Error loading sections:', error);
        });


    $scope.navigateToSectionAndError = function (sectionWithError) {

        $location.hash(sectionWithError.id);

        // 2. Use $timeout to wait for the DOM to update after ng-show takes effect
        $timeout(function () {
            // At this point, the section should be visible
            let targetElement = null;

            if (sectionWithError.firstErrorId) {
                targetElement = document.getElementById(sectionWithError.firstErrorId);
            }
            // Assuming your section divs look like this: <div id="section-llmConfig" ng-show="selectedSection === 'llmConfig'">
            const sectionContainerId = 'section-' + sectionWithError.id;
            const sectionContainer = document.getElementById(sectionContainerId);

            if (sectionContainer) {
                sectionContainer.scrollIntoView({behavior: 'smooth', block: 'start'});
            } else {

                // Absolute fallback: scroll to the top of the page or the main form.
                const mainFormElement = document.getElementsByName('configForm')[0];
                if (mainFormElement) {
                    mainFormElement.scrollIntoView({behavior: 'smooth', block: 'start'});
                } else {
                    window.scrollTo({top: 0, behavior: 'smooth'});
                }
            }

        }, 100);
    };

    $scope.$watch(function () {
        return $location.hash();
    }, function (newHash) {
        if (newHash) {
            // Remove the # symbol and update selectedSection
            $scope.selectedSection = newHash.replace('#', '');
        } else {
            // Default to llmConfig when no hash is present
            $scope.selectedSection = 'baseModels';
        }
    });

    $scope.config = $scope.config || {};

    if (typeof $scope.callPythonDo === 'function') {
        //Register the callPython method that will allow us to call the script `params_helper.py`
        PythonService.registerCallPythonDoFunction($scope.callPythonDo);
    } else {

        // Fallback to a dummy to avoid breaking PythonService if it's called before a proper registration
        PythonService.registerCallPythonDoFunction(function () {

            return $q.reject("callPythonDo was not properly initialized in LLMConfigController for PythonService.");
        });
    }

    // Register the desc params once in the parent
    DescParamsService.registerDescParams($scope);
    $scope.descParams = DescParamsService.getDescParams();

    $scope.showScrollToTop = false;

    // Function to scroll to top
    $scope.scrollToTop = function () {
        var controllerElement = document.querySelector('[ng-controller="LLMConfigController"]');
        if (controllerElement) {
            controllerElement.scrollIntoView({behavior: 'smooth'});
        } else {
            // Fallback to window scroll
            window.scrollTo({top: 0, behavior: 'smooth'});
        }
    };

    // Function to check scroll position and show/hide button
    function checkScrollPosition() {
        // Target the actual scrollable element
        var scrollableElement = document.querySelector('[ng-controller="CustomWebAppEditController"]');

        if (!scrollableElement) {
            return;
        }

        var scrollTop = scrollableElement.scrollTop;
        var elementHeight = scrollableElement.clientHeight;
        var scrollHeight = scrollableElement.scrollHeight;

        // Show button when user has scrolled down more than 300px
        var scrollPercent = (scrollTop + elementHeight) / scrollHeight;

        $scope.$apply(function () {
            $scope.showScrollToTop = scrollTop > 300 && scrollPercent > 0.3;
        });
    }

    // Add scroll event listener to the correct element
    var scrollableElement = document.querySelector('[ng-controller="CustomWebAppEditController"]');
    if (scrollableElement) {
        angular.element(scrollableElement).on('scroll', checkScrollPosition);

    } else {

    }

    // Clean up event listener when scope is destroyed
    $scope.$on('$destroy', function () {
        if (scrollableElement) {
            angular.element(scrollableElement).off('scroll', checkScrollPosition);
        }
    });


}])

llmApp.directive('listenForSaveAndView', function () {
    return {
        restrict: 'A',
        link: function (scope) {
            function handleClick(event) {
                var target = event.target;

                while (target && target !== document) {
                    if (target.tagName === 'BUTTON' || target.tagName === 'A') {
                        var elementText = target.textContent.trim().toLowerCase();

                        if (
                            elementText.includes('save and view webapp') ||
                            elementText.includes('save and view app') ||
                            elementText.includes('save & view') ||
                            elementText.includes('save')
                        ) {
                            // Check for our own bypassed clicks to avoid infinite loops
                            if (target.hasAttribute('data-bypassed')) {
                                target.removeAttribute('data-bypassed');
                                return;
                            }

                            // Temporarily stop the event
                            event.stopPropagation();
                            event.preventDefault();

                            // Apply to ensure we're in Angular context
                            scope.$apply(function () {
                                // 1. Mark the form as submitted to trigger validations
                                if (scope.configForm) {
                                    scope.configForm.$submitted = true;
                                }

                                // 2. Run validation logic
                                var isValid = validateForm(scope);

                                if (!isValid) {
                                    // Show error message but don't block the save
                                    scope.showValidationError = true;

                                    // Scroll to the LLMConfigController div when validation fails
                                    $timeout(function () {
                                        var controllerElement = document.querySelector('[ng-controller="LLMConfigController"]');
                                        if (controllerElement) {
                                            controllerElement.scrollIntoView({behavior: 'smooth'});
                                        }
                                    });
                                }

                                // Always proceed with the save action (valid or not)
                                $timeout(function () {
                                    target.setAttribute('data-bypassed', 'true');
                                    target.click();
                                });
                            });

                            return false;
                        }
                    }
                    target = target.parentElement;
                }
            }

            // Function to validate the form
            function validateForm(scope) {
                scope.invalidSections = [];
                scope.showGlobalError = false;
                let isOverallFormInvalid = false;

                // Access your form object
                var form = scope.configForm;

                if (!form) {
                    return false;
                }

                angular.forEach(scope.sections, function (section) {
                    // Check if the sub-form for this section exists and is invalid
                    const sectionForm = scope.configForm[section.formName];
                    if (sectionForm && sectionForm.$invalid) {
                        scope.invalidSections.push(section);
                        isOverallFormInvalid = true;
                    }
                });

                if (isOverallFormInvalid) {
                    scope.showGlobalError = true;
                    return false; // Indicates validation failed
                }

                // Check if the form is valid
                if (form.$valid) {
                    // Reset form state after successful validation
                    form.$setPristine();
                    form.$setUntouched(); // Also reset touched state for better UX
                    return true;
                }

                return false;
            }

            function clickHandler(event) {
                handleClick(event);
            }

            function keydownHandler(event) {
                if ((event.ctrlKey || event.metaKey) && event.key === 's') {
                    event.preventDefault(); // Prevent browser save dialog

                    scope.$apply(function () {
                        if (scope.configForm) {
                            scope.configForm.$submitted = true;
                        }

                        var isValid = validateForm(scope);

                        if (!isValid) {
                            // Show validation warning
                            scope.showValidationError = true;
                            $timeout(function () {
                                var controllerElement = document.querySelector(
                                    '[ng-controller="LLMConfigController"]'
                                );
                                if (controllerElement) {
                                    controllerElement.scrollIntoView({behavior: 'smooth'});
                                }
                            });
                        }

                        // Don't stop propagation - let the save happen regardless
                        // The event will continue to propagate to the parent's save handler
                    });
                }
            }

            // Add global listener
            document.addEventListener('click', clickHandler, true);
            document.addEventListener('keydown', keydownHandler, {capture: true, passive: false});

            // Clean up
            scope.$on('$destroy', function () {
                document.removeEventListener('click', clickHandler, true);
                document.removeEventListener('keydown', keydownHandler, true);
            });
        },
    }
});