import { composeDataTable } from './data-table.js';
import { posPost } from '../lib/http.js';

/**
 * Alpine factory for the Terminals LIST page.
 *
 * The add/edit editor moved to its own full-width page ({@see terminalForm})
 * — the config outgrew a side panel. This component now owns only the list
 * interactions: the searchable/paged table, the per-row active toggle,
 * binding this workstation to a terminal, and delete. Edit/create are plain
 * links to the dedicated page.
 */
export function terminalsPage({
    updateUrlTemplate,
    deleteUrlTemplate,
    selectUrlTemplate,
    clearSelectionUrl,
    activeTerminalId = null,
    rows = [],
} = {}) {
    return composeDataTable(
        {
            rowsSelector:       'li[data-dt-row]',
            searchableSelector: '.term-row-name',
            initialPageSize:    25,
        },
        {
            rowsById:    {},
            togglingIds: [],

            // Which terminal THIS browser is bound to (pos_terminal_id cookie).
            activeTerminalId,
            selectingId: null,

            _rootEl: null,

            get isTable() { return true; },

            init() {
                this._rootEl  = this.$el;
                this.rowsById = Object.fromEntries(rows.map((r) => [r.id, r]));
                this.initDataTable();
            },

            async toggleActive(id) {
                const row = this.rowsById[id];
                if (!row || this.togglingIds.includes(id)) return;
                const next = !row.is_active;

                row.is_active    = next;
                this.togglingIds = [...this.togglingIds, id];

                const fd = new FormData();
                fd.append('_token',     document.querySelector('meta[name="csrf-token"]')?.content || '');
                fd.append('_method',    'PATCH');
                fd.append('name',       row.name ?? '');
                // Resend the existing code so the server doesn't regenerate
                // a fresh one (a blank code auto-derives on persist).
                fd.append('code',       row.code ?? '');
                fd.append('is_active',  next ? '1' : '0');
                fd.append('editing_id', id);

                const data = await this._send(updateUrlTemplate.replace('__ID__', id), fd);
                this.togglingIds = this.togglingIds.filter((x) => x !== id);

                if (!data) { row.is_active = !next; return; }

                this._applyServerResponse(data);
                if (data.message) {
                    this.$store.toasts.push({ type: 'success', message: data.message });
                }
            },

            /** Bind this workstation to a terminal (server sets the cookie). */
            async selectTerminal(id) {
                if (this.selectingId) return;
                const row = this.rowsById[id];
                if (!row || row.is_active === false) return;

                this.selectingId = id;
                const data = await this._send(selectUrlTemplate.replace('__ID__', id), this._tokenForm());
                this.selectingId = null;
                if (!data) return;

                this.activeTerminalId = data.selected_id ?? id;
                if (data.message) {
                    this.$store.toasts.push({ type: 'success', message: data.message });
                }
            },

            /** Unbind this workstation from any terminal (clears the cookie). */
            async clearSelection() {
                const data = await this._send(clearSelectionUrl, this._tokenForm());
                if (!data) return;

                this.activeTerminalId = null;
                if (data.message) {
                    this.$store.toasts.push({ type: 'success', message: data.message });
                }
            },

            confirmDeleteRow(id) {
                const name = this.rowsById[id]?.name ?? 'this terminal';
                this.$store.confirm.show({
                    title:        `Delete "${name}"?`,
                    message:      'Past sales and shifts keep their history but lose the terminal label. This cannot be undone.',
                    intent:       'danger',
                    confirmLabel: 'Delete terminal',
                    cancelLabel:  'Cancel',
                    onConfirm: async () => {
                        const data = await this._send(deleteUrlTemplate.replace('__ID__', id), this._formWithMethod('DELETE'));
                        if (!data) return;
                        this._applyServerResponse(data);
                        if (data.message) {
                            this.$store.toasts.push({ type: 'success', message: data.message });
                        }
                    },
                });
            },

            _applyServerResponse(data) {
                if (Array.isArray(data.rows)) {
                    this.rowsById = Object.fromEntries(data.rows.map((r) => [r.id, r]));
                }
                if (data.list_html) {
                    const list = this._rootEl.querySelector('.term-list');
                    if (list) {
                        list.replaceChildren();
                        list.insertAdjacentHTML('beforeend', data.list_html);
                        if (window.Alpine) window.Alpine.initTree(list);
                    }
                }
                this._dtCollect();
                this._dtRender();
                this.$nextTick(() => { this._dtCollect(); this._dtRender(); });
            },

            async _send(url, body) {
                try {
                    const { data } = await posPost(url, body);
                    return data;
                } catch (e) {
                    if (e?.status === 422) {
                        this.$store.toasts.push({ type: 'error', message: e?.message || 'Request failed.' });
                    }
                    return null;
                }
            },

            _formWithMethod(method) {
                const fd = new FormData();
                fd.append('_token',  document.querySelector('meta[name="csrf-token"]')?.content || '');
                fd.append('_method', method);
                return fd;
            },

            _tokenForm() {
                const fd = new FormData();
                fd.append('_token', document.querySelector('meta[name="csrf-token"]')?.content || '');
                return fd;
            },
        },
    );
}
