<?php

namespace App\Nexus\Http\Controllers;

use App\Models\Plan;
use App\Nexus\Analytics\BotAnalyticsService;
use App\Nexus\Analytics\DashboardService;
use App\Nexus\Analytics\UserMetricsService;
use App\Nexus\Analytics\MarketMetricsService;
use App\Nexus\Engine\NexusConfig;
use App\Nexus\Models\NexusConfig as NexusConfigModel;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class NexusDashboardController
{
    private function parseDateRange(Request $request): array
    {
        if ($request->filled('start') && $request->filled('end')) {
            return ['start' => $request->input('start'), 'end' => $request->input('end')];
        }
        if ($request->filled('month')) {
            $month = Carbon::parse($request->input('month') . '-01');
            return ['start' => $month->startOfMonth()->toDateString(), 'end' => $month->endOfMonth()->toDateString()];
        }
        if ($request->filled('range')) {
            $range = $request->input('range');
            $now = Carbon::now();
            return match ($range) {
                'today'     => ['start' => $now->toDateString(), 'end' => $now->toDateString()],
                'yesterday' => ['start' => $now->subDay()->toDateString(), 'end' => $now->toDateString()],
                '7days'     => ['start' => $now->subDays(7)->toDateString(), 'end' => Carbon::now()->toDateString()],
                '30days'    => ['start' => $now->subDays(30)->toDateString(), 'end' => Carbon::now()->toDateString()],
                default     => ['start' => $now->startOfMonth()->toDateString(), 'end' => Carbon::now()->toDateString()],
            };
        }
        return ['start' => Carbon::now()->startOfMonth()->toDateString(), 'end' => Carbon::now()->toDateString()];
    }

    public function overview(Request $request)
    {
        $dates = $this->parseDateRange($request);
        $dashboard = new DashboardService();
        $userService = new UserMetricsService();

        $sessionMetrics = $dashboard->getSessionMetrics($dates['start'], $dates['end']);
        $chartData = $dashboard->getTradingActivityChart($dates['start'], $dates['end']);
        $resultSummary = $dashboard->getSessionResultSummary($dates['start'] === $dates['end'] ? $dates['start'] : null);
        $economyPanel = $dashboard->getEconomyHealthPanel();
        $capWarnings = $dashboard->getProfitCapWarnings(70.0);
        $topBiddersResult = $userService->getTopBidders(10, $dates['start'], $dates['end']);
        $topBidders = $topBiddersResult['data'] ?? [];
        $sessionHistory = $dashboard->getSessionHistory($dates['start'], $dates['end']);
        $availableMonths = $userService->getAvailableMonths();

        $botService = new BotAnalyticsService();
        $botGlance = $botService->getGlanceSummary();

        return view('nexus.dashboard', compact(
            'sessionMetrics', 'chartData', 'resultSummary', 'economyPanel',
            'capWarnings', 'topBidders', 'sessionHistory', 'availableMonths',
            'dates', 'botGlance'
        ));
    }

    public function users(Request $request)
    {
        $dates = $this->parseDateRange($request);
        $userService = new UserMetricsService();

        $topBiddersResult = $userService->getTopBidders(
            (int) ($request->input('limit', 20)), $dates['start'], $dates['end'],
            $request->input('sort', 'wins'), $request->input('dir', 'desc'),
            $request->input('search'),
            ((int) ($request->input('page', 1)) - 1) * (int) ($request->input('limit', 20))
        );
        $topBidders = $topBiddersResult['data'] ?? [];
        $topBiddersTotal = $topBiddersResult['total'] ?? 0;
        $topBiddersPages = $topBiddersResult['pages'] ?? 1;

        $winLossRatio = $userService->getWinLossRatio($dates['start'], $dates['end']);
        $capitalDistribution = $userService->getCapitalDistribution();
        $profitDistribution = $userService->getProfitDistribution();
        $lossAccumulation = $userService->getUsersInLossAccumulation();
        $approachingCap = $userService->getUsersApproachingCap(70.0);
        $participation = $userService->getUserParticipation($dates['start'], $dates['end']);
        $dailyBidders = $userService->getDailyActiveBidders($dates['start'], $dates['end']);
        $winRateDistribution = $userService->getWinRateDistribution($dates['start'], $dates['end']);
        $availableMonths = $userService->getAvailableMonths();

        return view('nexus.users', compact(
            'topBidders', 'topBiddersTotal', 'topBiddersPages',
            'winLossRatio', 'capitalDistribution', 'profitDistribution',
            'lossAccumulation', 'approachingCap', 'participation',
            'dailyBidders', 'winRateDistribution', 'availableMonths', 'dates'
        ));
    }

    public function markets(Request $request)
    {
        $dates = $this->parseDateRange($request);
        $marketService = new MarketMetricsService();

        $pricingHistory = $marketService->getDynamicPricingHistory(7);
        $marketWinRates = $marketService->getMarketWinRates($dates['start'], $dates['end']);
        $categoryActivity = $marketService->getCategoryActivity($dates['start'], $dates['end']);
        $economyIndicators = $marketService->getEconomyIndicators();
        $availableMonths = (new UserMetricsService())->getAvailableMonths();

        return view('nexus.markets', compact(
            'pricingHistory', 'marketWinRates', 'categoryActivity',
            'economyIndicators', 'availableMonths', 'dates'
        ));
    }

    public function controls()
    {
        $allConfig = NexusConfigModel::orderBy('id')->get()->map(function ($row) {
            return [
                'key' => $row->key, 'value' => $row->value, 'type' => $row->type ?? 'string',
                'group' => $row->group ?? 'general', 'description' => $row->description ?? '',
                'is_editable' => (bool) $row->is_editable,
            ];
        })->groupBy('group')->toArray();

        $plans = Plan::whereNotNull('nexus_daily_min')->get();

        $configChanges = [];
        $rawChanges = DB::table('nexus_audit_log')->where('event', 'config_changed')
            ->orderByDesc('created_at')->limit(500)->get(['context', 'actor_id', 'created_at']);
        foreach ($rawChanges as $row) {
            $ctx = is_string($row->context) ? json_decode($row->context, true) : (array) $row->context;
            $key = $ctx['key'] ?? null;
            if ($key && !isset($configChanges[$key])) {
                $configChanges[$key] = ['last_changed' => $row->created_at, 'last_actor_id' => $row->actor_id];
            }
        }

        return view('nexus.controls', compact('allConfig', 'plans', 'configChanges'));
    }

    /**
     * Bots page -- AI bot governance overview.
     * Phase 8 v3: Date range support for historical monthly archive.
     */
    public function bots(Request $request)
    {
        $dates = $this->parseDateRange($request);
        $botService = new BotAnalyticsService();

        $botOverview = $botService->getFullOverview($dates['start'], $dates['end']);
        $botAlerts = $botService->getAlerts(); // always current
        $settlement = $botService->getSettlementPipeline($dates['start'], $dates['end']);
        $chartData = $botService->getChartData($dates['start'], $dates['end']);
        $availableMonths = $botService->getAvailableMonths();

        return view('nexus.bots', compact(
            'botOverview', 'botAlerts', 'settlement', 'chartData',
            'availableMonths', 'dates'
        ));
    }

    public function audit(Request $request)
    {
        $query = DB::table('nexus_audit_log')->orderBy('created_at', 'desc');
        if ($request->filled('event')) $query->where('event', $request->input('event'));
        if ($request->filled('user_id')) {
            $query->where(function ($q) use ($request) {
                $q->where('subject_user_id', $request->input('user_id'))
                  ->orWhere('actor_id', $request->input('user_id'));
            });
        }
        if ($request->filled('session_id')) $query->where('nexus_session_id', $request->input('session_id'));
        if ($request->filled('date_from')) $query->where('created_at', '>=', $request->input('date_from') . ' 00:00:00');
        if ($request->filled('date_to')) $query->where('created_at', '<=', $request->input('date_to') . ' 23:59:59');

        $auditLogs = $query->paginate(50)->withQueryString();
        $eventTypes = DB::table('nexus_audit_log')->select('event')->distinct()->orderBy('event')->pluck('event')->toArray();

        return view('nexus.audit', compact('auditLogs', 'eventTypes'));
    }
}
