/* eslint-disable @typescript-eslint/no-explicit-any */
// #region Imports
import { ControllerBase } from '../../Controls/Controllers/Abstracts/ControllerBase';
import { createDropListRef } from '../Core/DropListRef';
// #endregion
// #region DropListController
/**
 * Lit Reactive Controller for drop list functionality.
 * Wraps DropListRef to integrate with Lit components.
 *
 * @public
 */
export class DropListController extends ControllerBase {
    // #region Fields
    _dropListRef = null;
    _config;
    _initialized = false;
    _listeners = [];
    _groupController = null;
    constructor(host, config) {
        super(host);
        this._config = config ?? {};
    }
    // #endregion
    // #region ControllerBase Lifecycle
    /**
     * Called when the host connects to the DOM.
     *
     * @public
     * @override
     */
    hostConnected() {
        super.hostConnected();
        if (!this._initialized) {
            this._initialize();
            this._initialized = true;
        }
    }
    /**
     * Called when the host disconnects from the DOM.
     *
     * @public
     * @override
     */
    hostDisconnected() {
        super.hostDisconnected();
        this._cleanup();
    }
    // #endregion
    // #region Properties
    /**
     * Get the underlying DropListRef.
     *
     * @public
     */
    get dropListRef() {
        return this._dropListRef;
    }
    /**
     * Get/set disabled state.
     *
     * @public
     */
    get disabled() {
        return this._dropListRef?.disabled ?? false;
    }
    set disabled(value) {
        if (this._dropListRef) {
            this._dropListRef.disabled = value;
        }
    }
    /**
     * Get/set orientation.
     *
     * @public
     */
    get orientation() {
        return this._dropListRef?.orientation ?? 'vertical';
    }
    set orientation(value) {
        if (this._dropListRef) {
            this._dropListRef.orientation = value;
        }
    }
    /**
     * Get/set associated data.
     *
     * @public
     */
    get data() {
        return this._dropListRef?.data;
    }
    set data(value) {
        if (this._dropListRef) {
            this._dropListRef.data = value;
        }
    }
    /**
     * Get items.
     *
     * @public
     */
    get items() {
        return this._dropListRef?.items ?? [];
    }
    /**
     * Get ID.
     *
     * @public
     */
    get id() {
        return this._dropListRef?.id ?? '';
    }
    // #endregion
    // #region Methods
    /**
     * Update configuration.
     *
     * @param config - New configuration.
     *
     * @public
     */
    updateConfig(config) {
        this._config = {
            ...this._config,
            ...config
        };
        if (this._dropListRef) {
            // Recreate DropListRef with new config
            this._cleanup();
            this._initialize();
        }
    }
    /**
     * Set items in the list.
     *
     * @param items - Drag items.
     *
     * @public
     */
    withItems(items) {
        this._dropListRef?.withItems(items);
    }
    /**
     * Connect to other drop lists.
     *
     * @param lists - Connected lists.
     *
     * @public
     */
    connectTo(lists) {
        this._dropListRef?.connectTo(lists);
    }
    /**
     * Connect to other drop list controllers.
     *
     * @param controllers - Connected controllers.
     *
     * @public
     */
    connectToControllers(controllers) {
        const refs = controllers
            .map((c) => c.dropListRef)
            .filter((ref) => ref !== null);
        this._dropListRef?.connectTo(refs);
    }
    // #region Private Methods
    /**
     * Initialize the controller.
     *
     * @private
     */
    _initialize() {
        // Create DropListRef
        this._dropListRef = createDropListRef(this.host, this._config);
        // Check for parent DropListGroup and register
        this._registerWithGroup();
        // Set up event forwarding
        this._setupEventForwarding();
    }
    /**
     * Register with parent drop list group (if any).
     *
     * @private
     */
    _registerWithGroup() {
        // Look for parent element with data-drop-list-group attribute
        let parent = this.host.parentElement;
        while (parent) {
            if (parent.hasAttribute('data-drop-list-group')) {
                // Found group - check for controller
                this._groupController = parent.__dropListGroupController;
                if (this._groupController && this._dropListRef) {
                    this._groupController.registerDropList(this._dropListRef);
                    break;
                }
            }
            parent = parent.parentElement;
        }
    }
    /**
     * Set up event forwarding from DropListRef to host.
     *
     * @private
     */
    _setupEventForwarding() {
        if (!this._dropListRef) {
            return;
        }
        // sort
        this._addListener('sort', (event) => {
            const sortEvent = event;
            this.host.dispatchEvent(new CustomEvent('sort', {
                bubbles: true,
                composed: true,
                cancelable: false,
                detail: {
                    ...sortEvent.detail,
                    container: this._dropListRef ?? null
                }
            }));
            this.host.requestUpdate();
        });
        // drop
        this._addListener('drop', (event) => {
            const dropEvent = event;
            this.host.dispatchEvent(new CustomEvent('drop', {
                bubbles: true,
                composed: true,
                cancelable: false,
                detail: {
                    ...dropEvent.detail,
                    container: this._dropListRef ?? null
                }
            }));
            this.host.requestUpdate();
        });
    }
    /**
     * Add an event listener and track it for cleanup.
     *
     * @param type - Event type.
     * @param handler - Event handler.
     *
     * @private
     */
    _addListener(type, handler) {
        this._dropListRef?.element.addEventListener(type, handler);
        this._listeners.push({
            type,
            handler
        });
    }
    /**
     * Cleanup resources.
     *
     * @private
     */
    _cleanup() {
        // Unregister from group
        if (this._groupController) {
            if (this._dropListRef) {
                this._groupController.unregisterDropList(this._dropListRef);
            }
            this._groupController = null;
        }
        // Remove listeners
        if (this._dropListRef) {
            this._listeners.forEach(({ type, handler }) => {
                this._dropListRef?.element.removeEventListener(type, handler);
            });
        }
        this._listeners.length = 0;
        // Dispose DropListRef
        this._dropListRef?.dispose();
        this._dropListRef = null;
        this._initialized = false;
    }
}
// #endregion
//# sourceMappingURL=DropListController.js.map