/**
 * Landed Costs - list, create, and allocate against purchases
 */

const API_BASE = (window.API_CONFIG && window.API_CONFIG.BASE_URL) || '/api/v1';
const LANDED_COSTS_URL = (window.API_CONFIG && window.API_CONFIG.ENDPOINTS.LANDED_COSTS) || `${API_BASE}/landed-costs`;
const PURCHASES_URL = (window.API_CONFIG && window.API_CONFIG.ENDPOINTS.PURCHASES) || `${API_BASE}/purchases`;
const SUPPLIERS_URL = (window.API_CONFIG && window.API_CONFIG.ENDPOINTS.SUPPLIERS) || `${API_BASE}/purchases/suppliers`;

let landedCosts = [];
let purchases = [];
let suppliers = [];
let modalInstance = null;
let currencyCode = 'BWP';

function authHeaders() {
    if (window.authBootstrap && typeof window.authBootstrap.authHeader === 'function') {
        return window.authBootstrap.authHeader();
    }
    if (window.auth && typeof window.auth.authHeader === 'function') {
        return window.auth.authHeader();
    }
    const token = localStorage.getItem('token');
    return token ? { Authorization: `Bearer ${token}` } : {};
}

function formatApiError(data, fallback) {
    if (!data) return fallback || 'Request failed';
    const detail = data.detail;
    if (typeof detail === 'string') return detail;
    if (Array.isArray(detail)) {
        return detail.map((d) => d.msg || d.message || JSON.stringify(d)).join('; ');
    }
    if (data.message) return data.message;
    return fallback || 'Request failed';
}

function unwrapList(data) {
    if (Array.isArray(data)) return data;
    if (data && Array.isArray(data.data)) return data.data;
    if (data && Array.isArray(data.items)) return data.items;
    return [];
}

async function apiGet(url) {
    const response = await fetch(url, { headers: authHeaders() });
    const data = await response.json().catch(() => ({}));
    if (!response.ok) throw new Error(formatApiError(data, response.statusText));
    return data;
}

async function apiSend(url, method, body) {
    const response = await fetch(url, {
        method,
        headers: { ...authHeaders(), 'Content-Type': 'application/json' },
        body: body !== undefined ? JSON.stringify(body) : undefined,
    });
    const data = await response.json().catch(() => ({}));
    if (!response.ok) throw new Error(formatApiError(data, response.statusText));
    return data;
}

function formatCurrency(amount) {
    const value = Number(amount) || 0;
    try {
        return new Intl.NumberFormat(undefined, { style: 'currency', currency: currencyCode }).format(value);
    } catch {
        return value.toFixed(2);
    }
}

function formatDate(value) {
    if (!value) return '—';
    const d = new Date(value);
    if (Number.isNaN(d.getTime())) return String(value);
    return d.toLocaleDateString();
}

function getPurchaseRef(purchaseId) {
    const purchase = purchases.find((p) => p.id === purchaseId);
    if (!purchase) return 'N/A';
    return purchase.reference || purchase.supplier_invoice_number || purchase.id.slice(0, 8);
}

function getStatusColor(status) {
    switch ((status || '').toLowerCase()) {
        case 'draft':
            return 'secondary';
        case 'confirmed':
            return 'primary';
        case 'allocated':
            return 'success';
        default:
            return 'dark';
    }
}

function showAlert(message, type = 'info') {
    const placeholder = document.getElementById('alertPlaceholder');
    if (!placeholder) return;
    const wrapper = document.createElement('div');
    wrapper.innerHTML =
        `<div class="alert alert-${type} alert-dismissible fade show" role="alert">` +
        `   ${message}` +
        '   <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
        '</div>';
    placeholder.append(wrapper);
    setTimeout(() => wrapper.remove(), 6000);
}

function setLoading(loading) {
    const tableBody = document.getElementById('landedCostsTableBody');
    if (!tableBody) return;
    if (loading) {
        tableBody.innerHTML =
            '<tr><td colspan="6" class="text-center py-4"><div class="spinner-border spinner-border-sm text-primary" role="status"></div> Loading…</td></tr>';
    }
}

function populateSelect(elementId, data, valueField, textField, placeholder = 'Select...') {
    const select = document.getElementById(elementId);
    if (!select) return;
    select.innerHTML = `<option value="">${placeholder}</option>`;
    data.forEach((item) => {
        const option = new Option(item[textField], item[valueField]);
        select.add(option);
    });
}

function addCostItemRow(item = {}) {
    const container = document.getElementById('lcItemsContainer');
    if (!container) return;
    const itemRow = document.createElement('div');
    itemRow.className = 'row mb-2 align-items-center lc-item-row';
    itemRow.innerHTML =
        '<div class="col-md-5">' +
        `    <input type="text" class="form-control lc-item-desc" placeholder="Description (e.g., Freight)" value="${escapeHtml(item.description || '')}" required>` +
        '</div>' +
        '<div class="col-md-5">' +
        `    <input type="number" class="form-control lc-item-amount" placeholder="Amount" step="0.01" min="0.01" value="${item.amount != null ? item.amount : ''}" required>` +
        '</div>' +
        '<div class="col-md-2">' +
        '    <button type="button" class="btn btn-sm btn-outline-danger lc-remove-item" title="Remove">' +
        '        <i class="bi bi-trash"></i>' +
        '    </button>' +
        '</div>';
    itemRow.querySelector('.lc-remove-item').addEventListener('click', () => itemRow.remove());
    container.appendChild(itemRow);
}

function escapeHtml(str) {
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}

function resetModal() {
    document.getElementById('landedCostId').value = '';
    document.getElementById('lcReference').value = '';
    document.getElementById('lcDate').value = new Date().toISOString().slice(0, 10);
    document.getElementById('lcPurchase').value = '';
    document.getElementById('lcSupplier').value = '';
    document.getElementById('lcNotes').value = '';
    document.getElementById('lcItemsContainer').innerHTML = '';
    addCostItemRow();
    document.getElementById('landedCostModalLabel').textContent = 'Add Landed Cost';
    document.getElementById('saveLandedCost').disabled = false;
    document.querySelectorAll('#landedCostForm input, #landedCostForm select, #landedCostForm textarea, #addLandedCostItem')
        .forEach((el) => { el.disabled = false; });
    document.querySelectorAll('.lc-remove-item').forEach((btn) => { btn.disabled = false; });
}

function renderTable() {
    const tableBody = document.getElementById('landedCostsTableBody');
    if (!tableBody) return;
    tableBody.innerHTML = '';

    if (!landedCosts.length) {
        tableBody.innerHTML = '<tr><td colspan="6" class="text-center text-muted py-4">No landed costs found.</td></tr>';
        return;
    }

    landedCosts.forEach((lc) => {
        const row = document.createElement('tr');
        const status = (lc.status || 'draft').toLowerCase();
        const canAllocate = status !== 'allocated';
        const purchaseRef = lc.purchase_reference || getPurchaseRef(lc.purchase_id);

        row.innerHTML = `
            <td>${escapeHtml(lc.reference || '')}</td>
            <td>${escapeHtml(purchaseRef)}</td>
            <td>${formatDate(lc.date)}</td>
            <td>${formatCurrency(lc.total_amount)}</td>
            <td><span class="badge bg-${getStatusColor(status)}">${escapeHtml(status)}</span></td>
            <td class="text-nowrap">
                <button type="button" class="btn btn-sm btn-outline-secondary me-1 btn-view-lc" data-id="${lc.id}">View</button>
                ${canAllocate
            ? `<button type="button" class="btn btn-sm btn-success btn-allocate-lc" data-id="${lc.id}">Allocate</button>`
            : '<span class="text-muted small">Allocated</span>'}
            </td>
        `;
        tableBody.appendChild(row);
    });

    tableBody.querySelectorAll('.btn-view-lc').forEach((btn) => {
        btn.addEventListener('click', () => viewLandedCost(btn.dataset.id));
    });
    tableBody.querySelectorAll('.btn-allocate-lc').forEach((btn) => {
        btn.addEventListener('click', () => allocateCost(btn.dataset.id));
    });
}

async function loadCurrency() {
    try {
        const settings = await apiGet(`${API_BASE}/settings/currency`);
        const code = settings?.currency_code || settings?.data?.currency_code;
        if (code) currencyCode = code;
    } catch {
        /* use default */
    }
}

async function loadPurchases() {
    const data = await apiGet(`${PURCHASES_URL}?limit=300`);
    purchases = unwrapList(data);
    const options = purchases.map((p) => {
        const ref = p.reference || p.supplier_invoice_number || `Purchase ${p.id.slice(0, 8)}`;
        const date = p.purchase_date ? ` (${p.purchase_date})` : '';
        const supplier = p.supplier?.name || p.supplier_name || '';
        const label = supplier ? `${ref} — ${supplier}${date}` : `${ref}${date}`;
        return { id: p.id, label };
    });
    populateSelect('lcPurchase', options, 'id', 'label', 'Select purchase...');
}

async function loadSuppliers() {
    const data = await apiGet(`${SUPPLIERS_URL}?limit=500`);
    suppliers = unwrapList(data);
    populateSelect('lcSupplier', suppliers, 'id', 'name', 'Optional supplier...');
}

async function loadLandedCosts() {
    setLoading(true);
    try {
        const data = await apiGet(`${LANDED_COSTS_URL}/`);
        landedCosts = unwrapList(data);
        renderTable();
    } catch (err) {
        console.error(err);
        showAlert(err.message || 'Failed to load landed costs', 'danger');
        document.getElementById('landedCostsTableBody').innerHTML =
            '<tr><td colspan="6" class="text-center text-danger">Failed to load landed costs.</td></tr>';
    }
}

async function saveLandedCost() {
    const form = document.getElementById('landedCostForm');
    if (!form.checkValidity()) {
        form.reportValidity();
        return;
    }

    const items = [];
    document.querySelectorAll('#lcItemsContainer .lc-item-row').forEach((row) => {
        const description = row.querySelector('.lc-item-desc')?.value?.trim();
        const amount = parseFloat(row.querySelector('.lc-item-amount')?.value);
        if (description && amount > 0) {
            items.push({ description, amount, allocation_method: 'quantity' });
        }
    });

    if (!items.length) {
        showAlert('Add at least one cost item with a positive amount.', 'warning');
        return;
    }

    const supplierId = document.getElementById('lcSupplier').value || null;
    const payload = {
        reference: document.getElementById('lcReference').value.trim(),
        date: document.getElementById('lcDate').value,
        purchase_id: document.getElementById('lcPurchase').value,
        supplier_id: supplierId,
        notes: document.getElementById('lcNotes').value.trim() || null,
        items,
    };

    const saveBtn = document.getElementById('saveLandedCost');
    saveBtn.disabled = true;
    try {
        await apiSend(`${LANDED_COSTS_URL}/`, 'POST', payload);
        modalInstance.hide();
        showAlert('Landed cost saved successfully.', 'success');
        await loadLandedCosts();
    } catch (err) {
        console.error(err);
        showAlert(err.message || 'Failed to save landed cost', 'danger');
    } finally {
        saveBtn.disabled = false;
    }
}

function viewLandedCost(id) {
    const lc = landedCosts.find((c) => c.id === id);
    if (!lc) return;

    const readOnly = (lc.status || '').toLowerCase() === 'allocated';
    document.getElementById('landedCostId').value = lc.id;
    document.getElementById('lcReference').value = lc.reference || '';
    document.getElementById('lcDate').value = lc.date ? String(lc.date).slice(0, 10) : '';
    document.getElementById('lcPurchase').value = lc.purchase_id || '';
    document.getElementById('lcSupplier').value = lc.supplier_id || '';
    document.getElementById('lcNotes').value = lc.notes || '';

    const itemsContainer = document.getElementById('lcItemsContainer');
    itemsContainer.innerHTML = '';
    (lc.items || []).forEach((item) => addCostItemRow(item));
    if (!(lc.items || []).length) addCostItemRow();

    document.getElementById('landedCostModalLabel').textContent = readOnly ? 'View Landed Cost' : 'Landed Cost';
    document.getElementById('saveLandedCost').disabled = readOnly;
    document.querySelectorAll('#landedCostForm input, #landedCostForm select, #landedCostForm textarea, #addLandedCostItem')
        .forEach((el) => { el.disabled = readOnly; });
    document.querySelectorAll('.lc-remove-item').forEach((btn) => { btn.disabled = readOnly; });

    modalInstance.show();
}

async function allocateCost(id) {
    if (!confirm('Allocate these costs to the purchase line items? This updates inventory costs and cannot be undone.')) {
        return;
    }
    try {
        await apiSend(`${LANDED_COSTS_URL}/${id}/allocate`, 'POST');
        showAlert('Costs allocated successfully.', 'success');
        await loadLandedCosts();
    } catch (err) {
        console.error(err);
        showAlert(err.message || 'Failed to allocate landed cost', 'danger');
    }
}

function bindEvents() {
    document.getElementById('saveLandedCost').addEventListener('click', saveLandedCost);
    document.getElementById('addLandedCostItem').addEventListener('click', () => addCostItemRow());

    const modalEl = document.getElementById('landedCostModal');
    modalEl.addEventListener('show.bs.modal', (event) => {
        if (event.relatedTarget && event.relatedTarget.matches('[data-bs-target="#landedCostModal"]')) {
            resetModal();
        }
    });
}

document.addEventListener('DOMContentLoaded', async () => {
    modalInstance = new bootstrap.Modal(document.getElementById('landedCostModal'));
    bindEvents();
    try {
        await Promise.all([loadCurrency(), loadPurchases(), loadSuppliers()]);
        await loadLandedCosts();
    } catch (err) {
        console.error(err);
        showAlert(err.message || 'Failed to initialize page', 'danger');
    }
});
