<?php

namespace App\Http\Controllers\AiPortal;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

/**
 * AI cost & token dashboard. Returns rollups suitable for charts:
 *   - per-day spend over a window
 *   - per-month spend over a window
 *   - top providers / models / purposes
 *   - per-call detail (paginated)
 */
class CostController extends Controller
{
    /**
     * Summary view — the data the dashboard uses to render headline tiles
     * + day / month bar charts + provider breakdown.
     *
     * Query params:
     *   from, to  : ISO dates bracketing the window (default last 30 days)
     *   purpose   : optional purpose filter
     *   provider  : optional provider filter
     */
    public function summary(Request $request)
    {
        abort_unless($request->user()->isAdminOrAbove(), 403);

        $from = $request->date('from') ?? now()->subDays(30)->startOfDay();
        $to   = $request->date('to')   ?? now()->endOfDay();
        $purpose  = $request->string('purpose')->trim()->value();
        $provider = $request->string('provider')->trim()->value();

        $base = DB::table('ai_costs')
            ->whereBetween('called_at', [$from, $to])
            ->when($purpose,  fn ($q) => $q->where('purpose', $purpose))
            ->when($provider, fn ($q) => $q->where('provider', $provider));

        // Headline numbers — single roundtrip via raw aggregates.
        $headline = (clone $base)->selectRaw('
            COUNT(*)              AS calls,
            COALESCE(SUM(input_tokens), 0)  AS tokens_in,
            COALESCE(SUM(output_tokens), 0) AS tokens_out,
            COALESCE(SUM(cost_usd), 0)      AS spend_usd,
            COALESCE(AVG(latency_ms), 0)    AS avg_latency_ms
        ')->first();

        // Per-day series — for the bar chart.
        $perDay = (clone $base)
            ->selectRaw('DATE(called_at) AS d, SUM(cost_usd) AS spend, SUM(input_tokens+output_tokens) AS toks, COUNT(*) AS calls')
            ->groupBy('d')->orderBy('d')->get();

        // Per-month series — for month-over-month comparison (24 months back).
        $perMonth = DB::table('ai_costs')
            ->where('called_at', '>=', now()->subMonths(24)->startOfMonth())
            ->selectRaw("DATE_FORMAT(called_at, '%Y-%m') AS m, SUM(cost_usd) AS spend, SUM(input_tokens+output_tokens) AS toks, COUNT(*) AS calls")
            ->groupBy('m')->orderBy('m')->get();

        // Top breakdowns.
        $byProvider = (clone $base)->selectRaw('provider, SUM(cost_usd) AS spend, COUNT(*) AS calls')
            ->groupBy('provider')->orderByDesc('spend')->get();
        $byModel    = (clone $base)->selectRaw('model, SUM(cost_usd) AS spend, COUNT(*) AS calls')
            ->groupBy('model')->orderByDesc('spend')->limit(10)->get();
        $byPurpose  = (clone $base)->selectRaw('purpose, SUM(cost_usd) AS spend, COUNT(*) AS calls')
            ->groupBy('purpose')->orderByDesc('spend')->get();

        // Today + this-month at-a-glance.
        $today = (float) DB::table('ai_costs')
            ->where('called_at', '>=', now()->startOfDay())
            ->sum('cost_usd');
        $monthTotal = (float) DB::table('ai_costs')
            ->where('called_at', '>=', now()->startOfMonth())
            ->sum('cost_usd');

        return response()->json([
            'window'   => ['from' => $from->toIso8601String(), 'to' => $to->toIso8601String()],
            'headline' => [
                'calls'          => (int) $headline->calls,
                'tokens_in'      => (int) $headline->tokens_in,
                'tokens_out'     => (int) $headline->tokens_out,
                'tokens_total'   => (int) ($headline->tokens_in + $headline->tokens_out),
                'spend_usd'      => round((float) $headline->spend_usd, 4),
                'avg_latency_ms' => (int) $headline->avg_latency_ms,
            ],
            'today'         => round($today, 4),
            'month_to_date' => round($monthTotal, 4),
            'per_day'       => $perDay,
            'per_month'     => $perMonth,
            'by_provider'   => $byProvider,
            'by_model'      => $byModel,
            'by_purpose'    => $byPurpose,
        ]);
    }

    /**
     * Per-call detail. Used for "drill into a specific day" and the audit
     * trail — every AI call is line-item reportable with subject linkage.
     */
    public function calls(Request $request)
    {
        abort_unless($request->user()->isAdminOrAbove(), 403);

        $perPage = min(100, max(10, (int) $request->input('per_page', 50)));

        $q = DB::table('ai_costs')
            ->orderByDesc('called_at')
            ->when($request->input('from'),     fn ($q, $v) => $q->where('called_at', '>=', $v))
            ->when($request->input('to'),       fn ($q, $v) => $q->where('called_at', '<=', $v))
            ->when($request->input('purpose'),  fn ($q, $v) => $q->where('purpose', $v))
            ->when($request->input('provider'), fn ($q, $v) => $q->where('provider', $v));

        return response()->json($q->paginate($perPage));
    }
}
