var CustomCDR = {
    currentPage: 1,
    currentSort: 'calldate',
    currentDir: 'DESC',
    charts: {},
    loading: false,
    pageSize: 50
};

$(document).ready(function() {
    var $wrapper = $('#customcdr-wrapper');
    CustomCDR.pageSize = parseInt($wrapper.data('page-size')) || 50;
    var defaultRange = parseInt($wrapper.data('default-range')) || 30;

    // Set default date range
    setDatePreset(defaultRange + 'd');

    // Bind events
    bindEvents();

    // Load filter dropdowns and initial data
    loadFilterOptions();
    loadData();
});

// =====================
// Event Binding
// =====================

function bindEvents() {
    // Date presets
    $('.date-presets .btn').on('click', function() {
        $('.date-presets .btn').removeClass('active');
        $(this).addClass('active');
        setDatePreset($(this).data('preset'));
        CustomCDR.currentPage = 1;
        loadData();
    });

    // Search button
    $('#cdr-btn-search').on('click', function() {
        CustomCDR.currentPage = 1;
        loadData();
    });

    // Enter key in search/filter inputs
    $('#cdr-search, #cdr-extension, #cdr-did').on('keypress', function(e) {
        if (e.which === 13) {
            CustomCDR.currentPage = 1;
            loadData();
        }
    });

    // Dropdown changes
    $('#cdr-direction, #cdr-disposition').on('change', function() {
        CustomCDR.currentPage = 1;
        loadData();
    });

    // Reset
    $('#cdr-btn-reset').on('click', function() {
        $('#cdr-extension').val('');
        $('#cdr-did').val('');
        $('#cdr-direction').val('all');
        $('#cdr-disposition').val('all');
        $('#cdr-search').val('');
        CustomCDR.currentPage = 1;
        CustomCDR.currentSort = 'calldate';
        CustomCDR.currentDir = 'DESC';
        $('.date-presets .btn').removeClass('active');
        $('[data-preset="30d"]').addClass('active');
        setDatePreset('30d');
        loadData();
    });

    // Column sorting
    $('#cdr-table thead th[data-sort]').on('click', function() {
        var col = $(this).data('sort');
        if (CustomCDR.currentSort === col) {
            CustomCDR.currentDir = (CustomCDR.currentDir === 'ASC') ? 'DESC' : 'ASC';
        } else {
            CustomCDR.currentSort = col;
            CustomCDR.currentDir = 'ASC';
        }
        CustomCDR.currentPage = 1;
        loadData();
    });

    // CSV export
    $('#cdr-btn-csv').off('click').on('click', function() {
        exportCsv();
    });

    // Print
    $('#cdr-btn-print').off('click').on('click', function() {
        window.print();
    });

    // Recording playback — open modal with direct audio stream
    $(document).on('click', '.btn-play-recording', function(e) {
        e.preventDefault();
        var file = $(this).data('file');
        var calldate = $(this).data('calldate');
        var streamUrl = 'ajax.php?module=customcdr&command=serveRecording&file=' +
                        encodeURIComponent(file) + '&calldate=' + encodeURIComponent(calldate);
        var dlUrl = streamUrl + '&download=1';

        var player = document.getElementById('recording-player');
        player.pause();
        player.src = streamUrl;

        $('#recording-info').text(file);
        $('#recording-download').attr('href', dlUrl);
        $('#recording-modal').modal('show');

        player.load();
        player.play();
    });

    // Stop playback when modal closes
    $('#recording-modal').on('hidden.bs.modal', function() {
        var player = document.getElementById('recording-player');
        player.pause();
        player.src = '';
    });
}

// =====================
// Date Presets
// =====================

function setDatePreset(preset) {
    var now = new Date();
    var from, to;

    to = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);

    switch (preset) {
        case 'today':
            from = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
            break;
        case 'yesterday':
            from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1, 0, 0, 0);
            to = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1, 23, 59, 59);
            break;
        case '7d':
            from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7, 0, 0, 0);
            break;
        case '30d':
            from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 30, 0, 0, 0);
            break;
        case 'month':
            from = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0);
            break;
        case 'lastmonth':
            from = new Date(now.getFullYear(), now.getMonth() - 1, 1, 0, 0, 0);
            to = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
            break;
        default:
            // Treat as Nd
            var days = parseInt(preset) || 30;
            from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - days, 0, 0, 0);
            break;
    }

    $('#cdr-date-from').val(formatDatetimeLocal(from));
    $('#cdr-date-to').val(formatDatetimeLocal(to));
}

function formatDatetimeLocal(d) {
    var pad = function(n) { return n < 10 ? '0' + n : n; };
    return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) +
           'T' + pad(d.getHours()) + ':' + pad(d.getMinutes());
}

// =====================
// Filter Options (populate extension/DID datalists)
// =====================

function loadFilterOptions() {
    $.ajax({
        url: 'ajax.php',
        type: 'POST',
        data: { module: 'customcdr', command: 'getFilterOptions' },
        dataType: 'json',
        success: function(data) {
            var $extList = $('#cdr-extension-list');
            var $didList = $('#cdr-did-list');
            $extList.empty();
            $didList.empty();

            $extList.append('<option value="All">');
            (data.extensions || []).forEach(function(ext) {
                $extList.append('<option value="' + escapeHtml(ext) + '">');
            });

            $didList.append('<option value="All">');
            (data.dids || []).forEach(function(did) {
                $didList.append('<option value="' + escapeHtml(did) + '">');
            });
        }
    });
}

// =====================
// Data Loading
// =====================

function loadData() {
    if (CustomCDR.loading) return;
    CustomCDR.loading = true;

    var params = getFilterParams();
    params.command = 'getCdrData';
    params.module = 'customcdr';
    params.page = CustomCDR.currentPage;
    params.sort = CustomCDR.currentSort;
    params.dir = CustomCDR.currentDir;

    $('#cdr-tbody').html('<tr><td colspan="9" class="text-center text-muted">Loading...</td></tr>');

    $.ajax({
        url: 'ajax.php',
        type: 'POST',
        data: params,
        dataType: 'json',
        success: function(data) {
            if (data.error) {
                $('#cdr-tbody').html('<tr><td colspan="9" class="text-center text-danger">' +
                    escapeHtml(data.error) + '</td></tr>');
                return;
            }
            updateStats(data.stats);
            updateCharts(data.charts);
            updateTable(data.rows);
            updatePagination(data.pagination);
            updateSortIndicators();
        },
        error: function(xhr) {
            $('#cdr-tbody').html('<tr><td colspan="9" class="text-center text-danger">Failed to load data</td></tr>');
        },
        complete: function() {
            CustomCDR.loading = false;
        }
    });
}

function getFilterParams() {
    return {
        date_from: $('#cdr-date-from').val() ? $('#cdr-date-from').val().replace('T', ' ') + ':00' : '',
        date_to: $('#cdr-date-to').val() ? $('#cdr-date-to').val().replace('T', ' ') + ':59' : '',
        extension: $('#cdr-extension').val(),
        did: $('#cdr-did').val(),
        direction: $('#cdr-direction').val(),
        disposition: $('#cdr-disposition').val(),
        search: $('#cdr-search').val()
    };
}

// =====================
// Stats Update
// =====================

function updateStats(stats) {
    $('#stat-total').text(stats.total_calls.toLocaleString());
    $('#stat-answered').text(stats.answered.toLocaleString());
    $('#stat-noanswer').text(stats.no_answer.toLocaleString());
    $('#stat-busy').text(stats.busy.toLocaleString());
    $('#stat-failed').text(stats.failed.toLocaleString());
    $('#stat-avg-duration').text(formatDuration(stats.avg_duration));

    var total = stats.total_calls || 0;
    $('#cdr-result-count').text(total.toLocaleString() + ' call' + (total !== 1 ? 's' : '') + ' found');
}

// =====================
// Chart Updates
// =====================

var COLORS = {
    'ANSWERED':  '#5cb85c',
    'NO ANSWER': '#f0ad4e',
    'BUSY':      '#d9534f',
    'FAILED':    '#777777'
};

function destroyChart(name) {
    if (CustomCDR.charts[name]) {
        CustomCDR.charts[name].destroy();
        CustomCDR.charts[name] = null;
    }
}

function updateCharts(charts) {
    renderVolumeChart(charts.volume_by_day);
    renderDispositionChart(charts.disposition_pie);
    renderExtensionsChart(charts.top_extensions);
    renderDidsChart(charts.top_dids);
    renderHourlyChart(charts.hourly);
}

function renderVolumeChart(data) {
    destroyChart('volume');
    var ctx = document.getElementById('chart-volume');
    if (!ctx) return;

    // Organize data: days as labels, one dataset per disposition
    var dayMap = {};
    var dispositions = {};
    (data || []).forEach(function(r) {
        if (!dayMap[r.day]) dayMap[r.day] = {};
        dayMap[r.day][r.disposition] = parseInt(r.cnt);
        dispositions[r.disposition] = true;
    });

    var days = Object.keys(dayMap).sort();
    var datasets = [];
    Object.keys(dispositions).forEach(function(disp) {
        datasets.push({
            label: disp,
            data: days.map(function(d) { return dayMap[d][disp] || 0; }),
            backgroundColor: COLORS[disp] || '#aaa'
        });
    });

    CustomCDR.charts.volume = new Chart(ctx, {
        type: 'bar',
        data: { labels: days, datasets: datasets },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                x: { stacked: true },
                y: { stacked: true, beginAtZero: true }
            },
            plugins: { legend: { position: 'bottom' } }
        }
    });
}

function renderDispositionChart(data) {
    destroyChart('disposition');
    var ctx = document.getElementById('chart-disposition');
    if (!ctx) return;

    var labels = [];
    var values = [];
    var colors = [];
    (data || []).forEach(function(r) {
        labels.push(r.disposition);
        values.push(parseInt(r.cnt));
        colors.push(COLORS[r.disposition] || '#aaa');
    });

    CustomCDR.charts.disposition = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: labels,
            datasets: [{ data: values, backgroundColor: colors }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: { legend: { position: 'bottom' } }
        }
    });
}

function renderExtensionsChart(data) {
    destroyChart('extensions');
    var ctx = document.getElementById('chart-extensions');
    if (!ctx) return;

    var labels = [];
    var values = [];
    (data || []).forEach(function(r) {
        labels.push(r.ext);
        values.push(parseInt(r.total));
    });

    CustomCDR.charts.extensions = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: 'Calls',
                data: values,
                backgroundColor: '#337ab7'
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            indexAxis: 'y',
            scales: { x: { beginAtZero: true } },
            plugins: { legend: { display: false } }
        }
    });
}

function renderDidsChart(data) {
    destroyChart('dids');
    var ctx = document.getElementById('chart-dids');
    if (!ctx) return;

    var labels = [];
    var values = [];
    (data || []).forEach(function(r) {
        labels.push(r.did);
        values.push(parseInt(r.cnt));
    });

    CustomCDR.charts.dids = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: 'Calls',
                data: values,
                backgroundColor: '#5bc0de'
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            indexAxis: 'y',
            scales: { x: { beginAtZero: true } },
            plugins: { legend: { display: false } }
        }
    });
}

function renderHourlyChart(data) {
    destroyChart('hourly');
    var ctx = document.getElementById('chart-hourly');
    if (!ctx) return;

    // Fill all 24 hours
    var hourData = new Array(24).fill(0);
    (data || []).forEach(function(r) {
        hourData[parseInt(r.hr)] = parseInt(r.cnt);
    });

    var labels = [];
    for (var i = 0; i < 24; i++) {
        labels.push(i + ':00');
    }

    CustomCDR.charts.hourly = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: 'Calls',
                data: hourData,
                backgroundColor: '#f0ad4e'
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: { y: { beginAtZero: true } },
            plugins: { legend: { display: false } }
        }
    });
}

// =====================
// Table Update
// =====================

function updateTable(rows) {
    var $tbody = $('#cdr-tbody');
    $tbody.empty();

    if (!rows || rows.length === 0) {
        $tbody.html('<tr><td colspan="9" class="text-center text-muted">No records found</td></tr>');
        return;
    }

    rows.forEach(function(r) {
        var dispClass = getDispositionClass(r.disposition);
        var dirClass = getDirectionClass(r.direction);
        var recording = '';
        if (r.recordingfile) {
            var dlUrl = 'ajax.php?module=customcdr&command=serveRecording&file=' +
                        encodeURIComponent(r.recordingfile) + '&calldate=' +
                        encodeURIComponent(r.calldate) + '&download=1';
            recording = '<button type="button" class="btn btn-xs btn-default btn-play-recording" ' +
                        'data-file="' + escapeHtml(r.recordingfile) + '" ' +
                        'data-calldate="' + escapeHtml(r.calldate) + '" title="Play recording">' +
                        '<i class="fa fa-play"></i></button> ' +
                        '<a href="' + dlUrl + '" class="btn btn-xs btn-default" title="Download recording">' +
                        '<i class="fa fa-download"></i></a>';
        }

        var tr = '<tr>' +
            '<td>' + escapeHtml(r.calldate) + '</td>' +
            '<td>' + escapeHtml(r.src) + '</td>' +
            '<td>' + escapeHtml(r.dst) + '</td>' +
            '<td>' + escapeHtml(r.did || '') + '</td>' +
            '<td><span class="label ' + dirClass + '">' + escapeHtml(r.direction) + '</span></td>' +
            '<td>' + formatDuration(r.duration) + '</td>' +
            '<td>' + formatDuration(r.billsec) + '</td>' +
            '<td><span class="label ' + dispClass + '">' + escapeHtml(r.disposition) + '</span></td>' +
            '<td>' + recording + '</td>' +
            '</tr>';
        $tbody.append(tr);
    });
}

function getDispositionClass(disp) {
    switch (disp) {
        case 'ANSWERED':  return 'disp-answered';
        case 'NO ANSWER': return 'disp-noanswer';
        case 'BUSY':      return 'disp-busy';
        case 'FAILED':    return 'disp-failed';
        default:          return 'label-default';
    }
}

function getDirectionClass(dir) {
    switch (dir) {
        case 'Inbound':  return 'dir-inbound';
        case 'Outbound': return 'dir-outbound';
        case 'Internal': return 'dir-internal';
        default:         return 'dir-other';
    }
}

// =====================
// Sort Indicators
// =====================

function updateSortIndicators() {
    $('#cdr-table thead th[data-sort]').each(function() {
        var $icon = $(this).find('.sort-icon');
        var col = $(this).data('sort');
        if (col === CustomCDR.currentSort) {
            $icon.addClass('active');
            $icon.html(CustomCDR.currentDir === 'ASC' ? '&#9650;' : '&#9660;');
        } else {
            $icon.removeClass('active');
            $icon.html('');
        }
    });
}

// =====================
// Pagination
// =====================

function updatePagination(pag) {
    var $ul = $('#cdr-pagination');
    var $jump = $('#cdr-page-jump');
    $ul.empty();

    if (pag.totalPages <= 1) {
        $jump.hide();
        return;
    }

    var page = pag.page;
    var total = pag.totalPages;

    // « First
    $ul.append('<li class="' + (page <= 1 ? 'disabled' : '') +
        '"><a href="#" data-page="1" title="First page">&laquo;</a></li>');

    // ‹ Previous
    $ul.append('<li class="' + (page <= 1 ? 'disabled' : '') +
        '"><a href="#" data-page="' + (page - 1) + '" title="Previous page">&lsaquo;</a></li>');

    // Page numbers (show max 5 around current)
    var startPage = Math.max(1, page - 2);
    var endPage = Math.min(total, page + 2);

    if (startPage > 1) {
        $ul.append('<li><a href="#" data-page="1">1</a></li>');
        if (startPage > 2) {
            $ul.append('<li class="disabled"><span class="pag-ellipsis">&hellip;</span></li>');
        }
    }

    for (var i = startPage; i <= endPage; i++) {
        $ul.append('<li class="' + (i === page ? 'active' : '') +
            '"><a href="#" data-page="' + i + '">' + i + '</a></li>');
    }

    if (endPage < total) {
        if (endPage < total - 1) {
            $ul.append('<li class="disabled"><span class="pag-ellipsis">&hellip;</span></li>');
        }
        $ul.append('<li><a href="#" data-page="' + total + '">' + total + '</a></li>');
    }

    // › Next
    $ul.append('<li class="' + (page >= total ? 'disabled' : '') +
        '"><a href="#" data-page="' + (page + 1) + '" title="Next page">&rsaquo;</a></li>');

    // » Last
    $ul.append('<li class="' + (page >= total ? 'disabled' : '') +
        '"><a href="#" data-page="' + total + '" title="Last page">&raquo;</a></li>');

    // Bind page link clicks
    $ul.find('a[data-page]').off('click').on('click', function(e) {
        e.preventDefault();
        if ($(this).parent().hasClass('disabled')) return;
        var p = parseInt($(this).data('page'));
        if (p >= 1 && p <= total && p !== page) {
            CustomCDR.currentPage = p;
            loadData();
        }
    });

    // Page jump input
    $jump.show();
    $('#cdr-page-input').attr('max', total).val(page);

    $('#cdr-page-go').off('click').on('click', function() {
        goToPageInput(total);
    });
    $('#cdr-page-input').off('keypress').on('keypress', function(e) {
        if (e.which === 13) {
            e.preventDefault();
            goToPageInput(total);
        }
    });
}

function goToPageInput(total) {
    var p = parseInt($('#cdr-page-input').val());
    if (p >= 1 && p <= total && p !== CustomCDR.currentPage) {
        CustomCDR.currentPage = p;
        loadData();
    }
}

// =====================
// CSV Export
// =====================

function exportCsv() {
    var params = getFilterParams();
    params.module = 'customcdr';
    params.command = 'exportCsv';
    window.location.href = 'ajax.php?' + $.param(params);
}

// =====================
// Helpers
// =====================

function formatDuration(seconds) {
    seconds = parseInt(seconds) || 0;
    if (seconds < 60) return seconds + 's';
    var m = Math.floor(seconds / 60);
    var s = seconds % 60;
    if (m < 60) return m + 'm ' + s + 's';
    var h = Math.floor(m / 60);
    m = m % 60;
    return h + 'h ' + m + 'm ' + s + 's';
}

function escapeHtml(str) {
    if (str === null || str === undefined) return '';
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
}
