import('bootstrap');
import $ from 'jquery';
import 'datatables.net-bs5';
import * as bootstrap from 'bootstrap';

function destroyDataTable(selector: string): void {
    if ($.fn.DataTable.isDataTable(selector)) {
        $(selector).DataTable().destroy();
    }
}

function getAdmLocale(): string {
    const match = window.location.pathname.match(/^\/adm\/([a-z]{2})\//i);
    return match ? match[1].toLowerCase() : 'de';
}

function formatGeoLocation(location: Record<string, unknown>): string {
    const country = String(location.country ?? '');
    const isp = String(location.isp ?? '');
    const zip = String(location.zip ?? '');
    const city = String(location.city ?? '');

    return [country, isp, zip, city].filter(Boolean).join(', ');
}

function renderGeoModalBody(location: Record<string, unknown>): string {
    const rows = [
        ['Land', location.country],
        ['Region', location.regionName],
        ['Stadt', location.city],
        ['PLZ', location.zip],
        ['ISP', location.isp],
        ['Organisation', location.org],
        ['Timezone', location.timezone],
        ['Lat', location.lat],
        ['Lon', location.lon],
        ['Query', location.query],
    ];

    const list = rows
        .filter(([, value]) => value !== undefined && value !== null && String(value) !== '')
        .map(([label, value]) => `<dt class="col-sm-4">${label}</dt><dd class="col-sm-8">${String(value)}</dd>`)
        .join('');

    return `<dl class="row mb-0">${list}</dl>`;
}

function ensureGeoModalOnBody(): HTMLElement | null {
    const candidates = Array.from(document.querySelectorAll('#admLoginGeoModal'));
    if (candidates.length === 0) {
        return null;
    }

    const modalEl = candidates[candidates.length - 1] as HTMLElement;
    candidates.slice(0, -1).forEach((el) => el.remove());

    if (modalEl.parentElement !== document.body) {
        document.body.appendChild(modalEl);
    }

    return modalEl;
}

function bindGeoModal(): void {
    $(document).off('click.admLoginGeo', '.js-adm-login-geo');
    $(document).on('click.admLoginGeo', '.js-adm-login-geo', async function (event) {
        event.preventDefault();

        const button = this as HTMLElement;
        const id = button.getAttribute('data-id');
        if (!id) {
            return;
        }

        const modalEl = ensureGeoModalOnBody();
        const modalBody = document.getElementById('admLoginGeoModalBody');
        if (!modalEl || !modalBody) {
            return;
        }

        const modal = bootstrap.Modal.getOrCreateInstance(modalEl);
        modalBody.innerHTML = '<div class="text-muted">Lade …</div>';
        modal.show();

        modalEl.addEventListener('shown.bs.modal', () => {
            const backdrop = document.querySelector('.modal-backdrop:last-of-type');
            if (backdrop instanceof HTMLElement) {
                backdrop.classList.add('adm-login-geo-backdrop');
            }
        }, { once: true });

        try {
            const response = await fetch(`/adm/${getAdmLocale()}/log-login/geo-data?id=${encodeURIComponent(id)}`, {
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    Accept: 'application/json',
                },
            });

            if (!response.ok) {
                throw new Error('HTTP ' + response.status);
            }

            const payload = await response.json() as { location?: Record<string, unknown>; error?: string };
            if (!payload.location) {
                throw new Error(payload.error || 'No location data');
            }

            modalBody.innerHTML = renderGeoModalBody(payload.location);

            const cell = button.closest('td');
            if (cell) {
                cell.textContent = formatGeoLocation(payload.location);
            }
        } catch (error) {
            modalBody.innerHTML = '<div class="text-danger">Geo-Daten konnten nicht geladen werden.</div>';
            console.error('Geo lookup failed:', error);
        }
    });
}

export function initLoginTable(): void {
    destroyDataTable('#loginTable');
    bindGeoModal();

    const table = $('.table-responsive');

    table.off('show.bs.dropdown hide.bs.dropdown');
    table.on('show.bs.dropdown', function () {
        $('#loginTable').css('overflow', 'inherit');
    });
    table.on('hide.bs.dropdown', function () {
        $('#loginTable').css('overflow', 'auto');
    });

    const period: string = $('#period').val() as string;
    const state: string = $('#state').val() as string;

    let url: string = '../../../adm/de/log-login/data';

    if (period && state) {
        url = url + '?period=' + period + '&state=' + state;
    } else if (period) {
        url = url + '?period=' + period;
    } else if (state) {
        url = url + '?state=' + state;
    }

    $('#loginTable').DataTable({
        initComplete: function () {
            $('input[type="search"]').first().focus();
        },
        stateSave: true,
        autoWidth: true,
        paging: true,
        ordering: true,
        order: [[0, 'asc']],
        serverSide: true,
        ajax: {
            url: url,
        },
        columns: [
            { data: 'id' },
            { data: 'username' },
            { data: 'password' },
            { data: 'isSuccess' },
            { data: 'loginDatetime' },
            { data: 'ipAddress' },
            { data: 'location' },
        ],
        columnDefs: [
            {
                targets: 6,
                createdCell: function (td, cellData, rowData) {
                    if (!rowData.location) {
                        $(td).html(
                            '<span class="float-end">' +
                            '<button type="button" class="btn btn-primary js-adm-login-geo" data-id="' + rowData.id + '" aria-label="Geo-Daten laden">' +
                            '<i class="icofont-globe"></i>' +
                            '</button>' +
                            '</span>'
                        );
                    } else {
                        const geoLocation = JSON.parse(rowData.location);
                        $(td).html(geoLocation.country + ', ' + geoLocation.isp + ', ' + geoLocation.zip + ', ' + geoLocation.city);
                    }
                },
            },
            {
                targets: 3,
                createdCell: function (td, cellData, rowData) {
                    if (rowData.isSuccess === false) {
                        $(td).addClass('bg-danger text-white');
                        $(td).text('FAILED');
                    } else {
                        $(td).addClass('bg-success text-white');
                        $(td).text('SUCCESS');
                    }
                },
            },
        ],
    });
}

if (document.getElementById('loginTable') && !document.getElementById('admDashboardOffcanvasContent')) {
    $(function () {
        initLoginTable();
    });
}
