import { apiGet, apiPut } from '../api.js';
import { pageHeaderHTML, showToast } from '../app.js';
import { clientTableActionsHTML, confirmAndPatchClientArchive } from '../client-archive.js';

let overview = null;
let staleClients = [];
let followupSearch = '';

export async function insightsPage() {
    const app = document.getElementById('app');
    app.innerHTML = `
        ${pageHeaderHTML('Insights')}
        <div id="insightsContent"><div class="spinner"></div></div>
    `;

    try {
        const [ov, stale] = await Promise.all([
            apiGet('analytics.php?overview=1'),
            apiGet('analytics.php?staleClients=1'),
        ]);
        overview = ov;
        staleClients = stale.clients || [];
        renderInsights();
    } catch (e) {
        showToast(e.message, 'error');
        document.getElementById('insightsContent').innerHTML =
            `<p class="error-text">${esc(e.message)}</p>`;
    }
}

function renderInsights() {
    const el = document.getElementById('insightsContent');
    const ov = overview || {};

    const kpiCards = `
        <div class="insights-kpi-grid">
            <div class="insights-kpi card">
                <div class="insights-kpi-value">${ov.clientCount ?? 0}</div>
                <div class="insights-kpi-label">Clients</div>
            </div>
            <div class="insights-kpi card">
                <div class="insights-kpi-value">${ov.clientsWithCompletions ?? 0}</div>
                <div class="insights-kpi-label">With completions</div>
            </div>
            <div class="insights-kpi card">
                <div class="insights-kpi-value">${ov.submissionsLast7d ?? 0}</div>
                <div class="insights-kpi-label">Uploads (7 days)</div>
            </div>
            <div class="insights-kpi card">
                <div class="insights-kpi-value">${ov.submissionsLast30d ?? 0}</div>
                <div class="insights-kpi-label">Uploads (30 days)</div>
            </div>
        </div>
    `;

    const uploadChart = verticalBarChart(
        (ov.submissionsByDay || []).map(d => ({
            label: formatChartDay(d.date),
            value: d.count,
            title: `${d.date}: ${d.count} upload(s)`,
        })),
        { emptyLabel: 'No uploads in this period' }
    );

    const withoutCompletions = Math.max(0, (ov.clientCount ?? 0) - (ov.clientsWithCompletions ?? 0));
    const engagementChart = horizontalBarChart([
        { label: 'With completions', value: ov.clientsWithCompletions ?? 0 },
        { label: 'No completions yet', value: withoutCompletions },
    ], { suffix: '' });

    const idleChart = horizontalBarChart(idleBucketItems(staleClients), {
        suffix: '',
        variant: 'warn',
    });

    const completionChart = horizontalBarChart(
        (ov.questionnaires || []).map(q => ({
            label: q.name,
            value: q.completionRatio ?? 0,
            title: `${q.name}: ${q.completionRatio ?? 0}%`,
        })),
        { suffix: '%', max: 100 }
    );

    const scoringProfiles = ov.scoringProfiles || [];
    const scoringCharts = scoringProfiles.map(sp => {
        const computed = sp.computedBands || sp.bands || {};
        const coach = sp.coachBands || {};
        const computedChart = horizontalBarChart([
            { label: 'Green', value: computed.green ?? 0 },
            { label: 'Yellow', value: computed.yellow ?? 0 },
            { label: 'Red', value: computed.red ?? 0 },
        ], { suffix: '' });
        const coachChart = horizontalBarChart([
            { label: 'Green', value: coach.green ?? 0 },
            { label: 'Yellow', value: coach.yellow ?? 0 },
            { label: 'Red', value: coach.red ?? 0 },
        ], { suffix: '' });
        return `
            <div class="card insights-chart-card">
                <h3>${esc(sp.name)}</h3>
                <p class="insights-chart-hint">
                    ${sp.clientCount ?? 0} client(s) with complete profile
                    ${sp.averageTotal != null ? ` · avg ${sp.averageTotal}` : ''}
                    ${sp.pendingReview ? ` · ${sp.pendingReview} pending Counselor review` : ''}
                </p>
                <p class="insights-chart-hint" style="margin:0 0 6px"><strong>Calculated bands</strong></p>
                ${computedChart}
                <p class="insights-chart-hint" style="margin:12px 0 6px"><strong>Counselor decisions</strong></p>
                ${coachChart}
            </div>`;
    }).join('');

    const qRows = (ov.questionnaires || []).map(q => `
        <tr>
            <td><strong>${esc(q.name)}</strong></td>
            <td>${q.completedCount ?? 0} / ${q.eligibleCount ?? 0}</td>
            <td>${q.completionRatio ?? 0}%</td>
        </tr>
    `).join('');

    el.innerHTML = `
        ${kpiCards}
        <div class="insights-charts-grid">
            <div class="card insights-chart-card">
                <h3>Uploads per day</h3>
                <p class="insights-chart-hint">Last 14 days</p>
                ${uploadChart}
            </div>
            <div class="card insights-chart-card">
                <h3>Client engagement</h3>
                <p class="insights-chart-hint">Among clients in your scope</p>
                ${engagementChart}
            </div>
            <div class="card insights-chart-card">
                <h3>Days since last activity</h3>
                <p class="insights-chart-hint">Clients with at least one completion</p>
                ${idleChart}
            </div>
        </div>
        ${scoringProfiles.length ? `
        <div class="card" style="margin-top:20px">
            <h3 style="margin:0 0 8px">Scoring profiles</h3>
            <p class="insights-chart-hint" style="margin:0 0 12px">Calculated vs Counselor band distribution among clients with a complete weighted score</p>
            <div class="insights-charts-grid">${scoringCharts}</div>
        </div>` : ''}
        <div class="card" style="margin-top:20px">
            <h3 style="margin:0 0 8px">Completion by questionnaire</h3>
            <p class="insights-chart-hint" style="margin:0 0 12px">Share of clients who completed each active questionnaire</p>
            ${completionChart}
            <div class="table-wrapper">
                <table class="data-table">
                    <thead>
                        <tr><th>Questionnaire</th><th>Completed</th><th>Rate</th></tr>
                    </thead>
                    <tbody>${qRows || '<tr><td colspan="3">No active questionnaires</td></tr>'}</tbody>
                </table>
            </div>
        </div>
        <div class="card" style="margin-top:20px">
            <h3 style="margin:0 0 8px">Needs follow-up</h3>
            <p class="data-toolbar-hint" style="margin:0 0 12px">
                Clients who completed at least one questionnaire, sorted by longest time since last activity.
            </p>
            <div class="filter-bar">
                <input type="search" id="followupListSearch" class="filter-search"
                    placeholder="Search client, counselor, questionnaire, note…" value="${esc(followupSearch)}">
                <span class="data-toolbar-hint" id="followupListCount"></span>
            </div>
            <div class="table-wrapper">
                <table class="data-table">
                    <thead>
                        <tr>
                            <th>Client</th><th>Counselor</th><th>Last questionnaire</th>
                            <th>Completed at</th><th>Days idle</th><th>Note</th><th></th>
                        </tr>
                    </thead>
                    <tbody id="followupTableBody"></tbody>
                </table>
            </div>
        </div>
    `;

    document.getElementById('followupListSearch').addEventListener('input', (e) => {
        followupSearch = e.target.value;
        renderFollowupTableBody();
    });

    renderFollowupTableBody();
}

function followupSearchText(c) {
    return [
        c.clientCode,
        c.coachUsername,
        c.lastQuestionnaireName,
        c.lastQuestionnaireID,
        c.note,
        c.lastCompletedAt,
        c.daysSinceLastActivity != null ? String(c.daysSinceLastActivity) : '',
    ].filter(Boolean).join(' ');
}

function filteredFollowupClients() {
    const q = followupSearch.trim().toLowerCase();
    if (!q) return staleClients;
    return staleClients.filter(c => followupSearchText(c).toLowerCase().includes(q));
}

function followupRowHTML(c) {
    const code = esc(c.clientCode);
    return `
        <tr data-client="${code}">
            <td><code>${code}</code></td>
            <td>${esc(c.coachUsername)}</td>
            <td>${esc(c.lastQuestionnaireName || '—')}</td>
            <td>${esc(c.lastCompletedAt || '—')}</td>
            <td>${c.daysSinceLastActivity != null ? c.daysSinceLastActivity : '—'}</td>
            <td class="followup-note-cell">
                <textarea class="followup-note-input" rows="2" data-client="${code}"
                    placeholder="Follow-up note…">${esc(c.note || '')}</textarea>
                <div class="followup-note-actions">
                    <button type="button" class="btn btn-sm btn-primary save-note-btn" data-client="${code}">Save note</button>
                </div>
            </td>
            <td class="followup-actions-cell">
                ${clientTableActionsHTML({ clientCode: code, archived: false, showDelete: false })}
            </td>
        </tr>`;
}

function renderFollowupTableBody() {
    const body = document.getElementById('followupTableBody');
    const countEl = document.getElementById('followupListCount');
    if (!body) return;

    const filtered = filteredFollowupClients();

    if (!filtered.length) {
        body.innerHTML = `
            <tr>
                <td colspan="7" style="text-align:center;color:var(--text-secondary);padding:24px">
                    ${staleClients.length ? 'No clients match' : 'No clients'}
                </td>
            </tr>`;
        if (countEl) {
            countEl.textContent = followupSearch.trim() && staleClients.length
                ? `0 of ${staleClients.length} clients`
                : '';
        }
        return;
    }

    body.innerHTML = filtered.map(c => followupRowHTML(c)).join('');

    if (countEl) {
        const q = followupSearch.trim();
        countEl.textContent = q
            ? `${filtered.length} of ${staleClients.length} clients`
            : `${staleClients.length} client${staleClients.length === 1 ? '' : 's'}`;
    }

    body.querySelectorAll('.save-note-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            const tr = btn.closest('tr');
            const ta = tr?.querySelector('.followup-note-input');
            saveNote(btn.dataset.client, ta);
        });
    });

    body.querySelectorAll('.archive-client-btn').forEach(btn => {
        btn.addEventListener('click', () => archiveFromFollowup(btn.dataset.code));
    });
}

async function archiveFromFollowup(clientCode) {
    const ok = await confirmAndPatchClientArchive(clientCode, true);
    if (!ok) return;
    staleClients = staleClients.filter(c => c.clientCode !== clientCode);
    renderFollowupTableBody();
}

async function saveNote(clientCode, ta) {
    if (!ta) return;
    try {
        await apiPut('analytics.php', { clientCode, note: ta.value.trim() });
        const row = staleClients.find(c => c.clientCode === clientCode);
        if (row) row.note = ta.value.trim();
        showToast('Note saved', 'success');
    } catch (e) {
        showToast(e.message, 'error');
    }
}

function esc(s) {
    const d = document.createElement('div');
    d.textContent = s ?? '';
    return d.innerHTML;
}

function formatChartDay(isoDate) {
    if (!isoDate) return '';
    const d = new Date(isoDate + 'T12:00:00');
    if (Number.isNaN(d.getTime())) return isoDate.slice(5);
    return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
}

function chartMax(values, fallbackMax = 1) {
    const m = Math.max(0, ...values);
    return m > 0 ? m : fallbackMax;
}

function verticalBarChart(items, { emptyLabel = 'No data' } = {}) {
    if (!items.length) {
        return `<p class="insights-chart-hint">${esc(emptyLabel)}</p>`;
    }
    const max = chartMax(items.map(i => i.value));
    return `
        <div class="insights-vchart" role="img" aria-label="Bar chart">
            ${items.map(item => {
                const pct = max ? Math.round((100 * item.value) / max) : 0;
                return `
                    <div class="insights-vchart-col" title="${esc(item.title || `${item.label}: ${item.value}`)}">
                        <div class="insights-vchart-bar-wrap">
                            <div class="insights-vchart-bar" style="height:${pct}%"></div>
                        </div>
                        <span class="insights-vchart-value">${item.value}</span>
                        <span class="insights-vchart-label">${esc(item.label)}</span>
                    </div>`;
            }).join('')}
        </div>`;
}

function horizontalBarChart(items, { suffix = '%', max: fixedMax, variant = '' } = {}) {
    if (!items.length) {
        return '<p class="insights-chart-hint">No data</p>';
    }
    const max = fixedMax ?? chartMax(items.map(i => i.value));
    const fillClass = variant === 'warn' ? 'insights-hchart-fill--warn'
        : variant === 'muted' ? 'insights-hchart-fill--muted'
        : '';
    return `
        <div class="insights-hchart" role="img" aria-label="Bar chart">
            ${items.map(item => {
                const pct = max ? Math.round((100 * item.value) / max) : 0;
                const display = suffix === '%' ? `${item.value}${suffix}` : String(item.value);
                return `
                    <div class="insights-hchart-row" title="${esc(item.title || `${item.label}: ${display}`)}">
                        <span class="insights-hchart-label">${esc(item.label)}</span>
                        <div class="insights-hchart-track">
                            <div class="insights-hchart-fill ${fillClass}" style="width:${pct}%"></div>
                        </div>
                        <span class="insights-hchart-num">${esc(display)}</span>
                    </div>`;
            }).join('')}
        </div>`;
}

function idleBucketItems(clients) {
    const buckets = [
        { label: '0–7 days', value: 0 },
        { label: '8–30 days', value: 0 },
        { label: '31–90 days', value: 0 },
        { label: '90+ days', value: 0 },
        { label: 'No uploads yet', value: 0 },
    ];
    for (const c of clients) {
        const d = c.daysSinceLastActivity;
        if (d == null) buckets[4].value += 1;
        else if (d <= 7) buckets[0].value += 1;
        else if (d <= 30) buckets[1].value += 1;
        else if (d <= 90) buckets[2].value += 1;
        else buckets[3].value += 1;
    }
    return buckets.filter(b => b.value > 0);
}
