using DF.AppUsage.Api.Data;
using DF.AppUsage.Api.Models;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;

namespace DF.AppUsage.Api.Services;

public class DashboardService(AppDbContext db)
{
    public async Task<string> GetDashboardHtmlAsync()
    {
        // Die Preis-Umstellung als SQL-Konstante
        const string cutoff = "2026-01-21 15:50:00";

        // 1. Kosten für Berichte berechnen
        var berichtCosts = await db.Database.SqlQueryRaw<CostStat>(@$"
            SELECT 
                EXTRACT(YEAR FROM ""Timestamp"")::int as ""Year"",
                EXTRACT(MONTH FROM ""Timestamp"")::int as ""Month"",
                SUM(
                    CASE 
                        WHEN ""Timestamp"" < '{cutoff}'::timestamp 
                        THEN ((""Data""->'Measurements'->>'TokensInput')::numeric * 0.14233 / 1000000) + ((""Data""->'Measurements'->>'TokensOutput')::numeric * 0.5694 / 1000000)
                        ELSE ((""Data""->'Measurements'->>'TokensInput')::numeric * 0.38 / 1000000) + ((""Data""->'Measurements'->>'TokensOutput')::numeric * 1.5 / 1000000)
                    END
                )::numeric as ""Cost""
            FROM ""InsightEntries""
            WHERE ""InsightType"" = 'Feature_Use_AiBericht'
            GROUP BY 1, 2 ORDER BY 1, 2").ToListAsync();

        // 2. Kosten für Lieferscheine berechnen
        var lieferscheinCosts = await db.Database.SqlQueryRaw<CostStat>(@$"
            SELECT 
                EXTRACT(YEAR FROM ""Timestamp"")::int as ""Year"",
                EXTRACT(MONTH FROM ""Timestamp"")::int as ""Month"",
                SUM(
                    CASE 
                        WHEN ""Timestamp"" < '{cutoff}'::timestamp 
                        THEN ((""Data""->'Measurements'->>'TokensInput')::numeric * 2.75 / 1000000) + ((""Data""->'Measurements'->>'TokensOutput')::numeric * 11.00 / 1000000)
                        ELSE ((""Data""->'Measurements'->>'TokensInput')::numeric * 1.78 / 1000000) + ((""Data""->'Measurements'->>'TokensOutput')::numeric * 7.48 / 1000000)
                    END
                )::numeric as ""Cost""
            FROM ""InsightEntries""
            WHERE ""InsightType"" = 'Feature_Use_AiLieferschein'
            GROUP BY 1, 2 ORDER BY 1, 2").ToListAsync();


        // 1. App-Installationen
        var installData = await db.Database.SqlQueryRaw<AppInstallStat>(@"
            SELECT ""Data""->'Properties'->>'App' as ""App"", 
                ""Data""->'Properties'->>'Version' as ""Version"", 
                date_trunc('day', ""Timestamp"") as ""Day"", 
                COUNT(*)::int as ""Count""
            FROM ""InsightEntries""
            WHERE ""InsightType"" = 'AppLaunched_NewVersion' AND ""Timestamp"" >= now() - interval '30 days'
            GROUP BY 1, 2, 3 ORDER BY 3 ASC").ToListAsync();

        // 2. Berichte (Hier ist WithFreitext drin, wir stellen nur sicher, dass der Name exakt passt)
        var berichtData = await db.Database.SqlQueryRaw<AiStat>(@"
            SELECT EXTRACT(YEAR FROM ""Timestamp"")::int as ""Year"",
                EXTRACT(MONTH FROM ""Timestamp"")::int as ""Month"",
                COUNT(*)::int as ""Count"",
                SUM(COALESCE((""Data""->'Measurements'->>'AiFreitext')::int, 0))::int as ""WithFreitext""
            FROM ""InsightEntries""
            WHERE ""InsightType"" = 'Feature_Use_AiBericht'
            GROUP BY 1, 2 ORDER BY 1, 2").ToListAsync();

        // 3. Lieferscheine (HIER fehlte die Spalte für den Record)
        var lieferscheinData = await db.Database.SqlQueryRaw<AiStat>(@"
            SELECT EXTRACT(YEAR FROM ""Timestamp"")::int as ""Year"",
                EXTRACT(MONTH FROM ""Timestamp"")::int as ""Month"",
                COUNT(*)::int as ""Count"",
                0::int as ""WithFreitext"" -- Die Dummy-Spalte für den Record
            FROM ""InsightEntries""
            WHERE ""InsightType"" = 'Feature_Use_AiLieferschein'
            GROUP BY 1, 2 ORDER BY 1, 2").ToListAsync();
            
        // 1. Gesamtkosten für den AKTUELLEN Monat (C# Logik)
        var jetzt = DateTime.Now;
        var kostenBerichtMonat = berichtCosts
            .Where(d => d.Year == jetzt.Year && d.Month == jetzt.Month)
            .Sum(d => d.Cost);

        var kostenLieferscheinMonat = lieferscheinCosts
            .Where(d => d.Year == jetzt.Year && d.Month == jetzt.Month)
            .Sum(d => d.Cost);

        var gesamtMonat = kostenBerichtMonat + kostenLieferscheinMonat;

        // 2. Gesamtkosten ÜBER ALLES (einfach alles summieren)
        var gesamtAllTime = berichtCosts.Sum(d => d.Cost) + lieferscheinCosts.Sum(d => d.Cost);

        // 2. HTML Template zusammenbauen
        return RenderHtml(installData, berichtData, lieferscheinData, berichtCosts, lieferscheinCosts, gesamtMonat, gesamtAllTime);
        //return RenderHtml(installData, berichtData, lieferscheinData, berichtCosts, lieferscheinCosts, gesamtMonat);            
        // return RenderHtml(installData, berichtData, lieferscheinData);
        //return RenderHtml(installData, berichtData, lieferscheinData, berichtCosts, lieferscheinCosts);

    }

    private string RenderHtml(
        List<AppInstallStat> installs, 
        List<AiStat> berichte,
        List<AiStat> lieferscheine,
        List<CostStat> bCosts,
        List<CostStat> lCosts,
        decimal gesamtMonat,
        decimal gesamtAllTime) 
    {
        // Wir serialisieren die Daten hier einmal vorab, um sie sicher in den JS-Block zu schreiben
        var jsonInstalls = JsonSerializer.Serialize(installs);
        var jsonBerichte = JsonSerializer.Serialize(berichte);
        var jsonLieferscheine = JsonSerializer.Serialize(lieferscheine);
        var jsonBCosts = JsonSerializer.Serialize(bCosts);
        var jsonLCosts = JsonSerializer.Serialize(lCosts);

        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset='UTF-8'>
            <title>DF KI Dashboard</title>
            <script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
            <style>
                body {{ font-family: sans-serif; margin: 40px; background: #f8f9fa; color: #333; }}
                .container {{ max-width: 1100px; margin: auto; }}

                /* Die neue Summen-Kachel */
                .summary-card {{ 
                    background: linear-gradient(135deg, #0056b3 0%, #004085 100%); 
                    color: white; padding: 30px; border-radius: 15px; 
                    margin-bottom: 30px; text-align: center;
                    box-shadow: 0 4px 15px rgba(0,0,0,0.2);
                }}
                .summary-card h3 {{ margin: 0; opacity: 0.8; font-weight: normal; font-size: 1.2em; }}
                .summary-card .amount {{ font-size: 3.5em; font-weight: bold; margin: 5px 0; }}
                .summary-card .all-time {{ opacity: 0.7; font-size: 1.1em; border-top: 1px solid rgba(255,255,255,0.2); padding-top: 10px; margin-top: 10px; }}                
                
                .card {{ background: white; padding: 20px; border-radius: 10px; margin-bottom: 30px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }}
                h1 {{ color: #0056b3; }}
                h2 {{ margin-top: 0; color: #0056b3; }}
            </style>
        </head>
        <body>
            <div class='container'>
                <h1>KI & App Insights Dashboard</h1>
                
                <div class='summary-card'>
                    <h3>KI-Kosten im {DateTime.Now:MMMM}</h3>
                    <div class='amount'>{gesamtMonat:N2} &euro;</div>
                    <div class='all-time'>von <strong>{gesamtAllTime:N2} &euro;</strong> gesamt seit Aufzeichnung</div>
                </div>
                
                <div class='card'><h2>App Rollout (Letzte 30 Tage)</h2><canvas id='installChart'></canvas></div>
                <div class='card'><h2>KI Berichte (Monatsvergleich)</h2><canvas id='berichtChart'></canvas></div>
                <div class='card'><h2>KI Lieferscheine</h2><canvas id='lieferscheinChart'></canvas></div>
                
                <div class='card'>
                    <h2>Gesch&auml;tzte KI-Kosten (&euro;)</h2>
                    <canvas id='costChart'></canvas>
                </div>
            </div>

            <script>
                const config = {{
                    installs: {jsonInstalls},
                    berichte: {jsonBerichte},
                    lieferscheine: {jsonLieferscheine}
                }};

                // HELFER: Verteilt Daten (Monat/Count) auf ein 12-Elemente-Array
                function fillMonths(dataRaw, year) {{
                    const arr = new Array(12).fill(0);
                    dataRaw.filter(d => d.Year === year).forEach(d => {{
                        arr[d.Month - 1] = d.Count;
                    }});
                    return arr;
                }}

                // --- 1. APP ROLLOUT MIT SOLO-KLICK-LOGIK ---
                const dates = [...new Set(config.installs.map(d => d.Day.split('T')[0]))].sort();
                const appGroups = {{}};
                config.installs.forEach(d => {{
                    const label = d.App.split('.').reverse()[1] + ' (' + d.Version + ')';
                    if(!appGroups[label]) appGroups[label] = new Array(dates.length).fill(0);
                    const idx = dates.indexOf(d.Day.split('T')[0]);
                    appGroups[label][idx] = d.Count;
                }});

                new Chart(document.getElementById('installChart'), {{
                    type: 'line',
                    data: {{
                        labels: dates,
                        datasets: Object.keys(appGroups).map(key => ({{
                            label: key,
                            data: appGroups[key],
                            tension: 0.2,
                            borderColor: '#' + (Math.random().toString(16) + '000000').substring(2,8)
                        }}))
                    }},
                    options: {{
                        plugins: {{
                            legend: {{
                                onClick: function(e, legendItem, legend) {{
                                    const index = legendItem.datasetIndex;
                                    const ci = legend.chart;
                                    
                                    // Prüfen, ob dieser Datensatz bereits der einzige sichtbare ist
                                    let isSolo = true;
                                    ci.data.datasets.forEach((ds, i) => {{
                                        if (i !== index && ci.isDatasetVisible(i)) isSolo = false;
                                        if (i === index && !ci.isDatasetVisible(i)) isSolo = false;
                                    }});

                                    if (isSolo) {{
                                        // Wenn schon solo -> alle wieder einblenden
                                        ci.data.datasets.forEach((ds, i) => ci.show(i));
                                    }} else {{
                                        // Sonst: Alle verstecken, nur diesen zeigen
                                        ci.data.datasets.forEach((ds, i) => {{
                                            if (i === index) ci.show(i);
                                            else ci.hide(i);
                                        }});
                                    }}
                                }}
                            }}
                        }},
                        scales: {{
                            y: {{ beginAtZero: true }}
                        }}
                    }}
                }});

                // --- 2. BERICHTE ---
                const bYears = [...new Set(config.berichte.map(d => d.Year))];
                new Chart(document.getElementById('berichtChart'), {{
                    type: 'line',
                    data: {{
                        labels: ['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
                        datasets: bYears.map(y => ({{
                            label: 'Berichte ' + y,
                            data: fillMonths(config.berichte, y),
                            borderColor: y === 2026 ? 'blue' : '#ccc',
                            borderWidth: y === 2026 ? 3 : 1
                        }}))
                    }}
                }});

                // --- 3. LIEFERSCHEINE ---
                const lYears = [...new Set(config.lieferscheine.map(d => d.Year))].sort();

                // Eine kleine Farb-Palette für die Jahre
                const yearColors = {{
                    2024: '#6c757d', // Grau
                    2025: '#ffc107', // Gelb/Gold
                    2026: '#28a745'  // Sattes Grün
                }};

                new Chart(document.getElementById('lieferscheinChart'), {{
                    type: 'line',
                    data: {{
                        labels: ['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
                        datasets: lYears.map(y => ({{
                            label: 'Lieferscheine ' + y,
                            data: fillMonths(config.lieferscheine, y),
                            // Falls das Jahr nicht in unserer Liste ist, nehmen wir ein zufälliges Grün
                            borderColor: yearColors[y] || '#88c999', 
                            backgroundColor: (yearColors[y] || '#88c999') + '22', // +22 fügt Transparenz hinzu
                            borderWidth: y === 2026 ? 3 : 2,
                            fill: true,
                            tension: 0.3
                        }}))
                    }},
                    options: {{
                        responsive: true,
                        plugins: {{
                            legend: {{ position: 'bottom' }}
                        }}
                    }}
                }});

                // --- KOSTEN DASHBOARD ---
                const bCosts = {JsonSerializer.Serialize(bCosts)};
                const lCosts = {JsonSerializer.Serialize(lCosts)};

                function mapToCost(dataRaw, year) {{
                    const arr = new Array(12).fill(0);
                    dataRaw.filter(d => d.Year === year).forEach(d => {{
                        arr[d.Month - 1] = parseFloat(d.Cost.toFixed(2));
                    }});
                    return arr;
                }}

                const costYears = [...new Set([...bCosts, ...lCosts].map(d => d.Year))].sort();

                new Chart(document.getElementById('costChart'), {{
                    type: 'bar',
                    data: {{
                        labels: ['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
                        datasets: costYears.flatMap(y => [
                            {{
                                label: 'Berichte ' + y,
                                data: mapToCost(bCosts, y),
                                backgroundColor: y === 2026 ? '#0056b3' : '#adb5bd',
                                stack: 'Stack ' + y
                            }},
                            {{
                                label: 'Lieferscheine ' + y,
                                data: mapToCost(lCosts, y),
                                backgroundColor: y === 2026 ? '#28a745' : '#6c757d',
                                stack: 'Stack ' + y
                            }}
                        ])
                    }},
                    options: {{
                        plugins: {{
                            tooltip: {{
                                callbacks: {{
                                    label: (ctx) => ctx.dataset.label + ': ' + ctx.raw.toFixed(2) + ' €'
                                }}
                            }}
                        }},
                        scales: {{
                            y: {{ 
                                beginAtZero: true,
                                ticks: {{ callback: (value) => value + ' €' }}
                            }}
                        }}
                    }}
                }});                
            </script>
        </body>
        </html>";
    }
}