<?php

declare(strict_types=1);

namespace App\Http\Controllers\Public;

use App\Domain\Status\Models\StatusComponent;
use App\Domain\Status\Models\StatusIncident;
use App\Domain\Status\Services\StatusChecker;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;

/**
 * Public Status Page
 *
 * Kimlik doğrulama gerektirmez — status.example.com muadili.
 * Üç endpoint:
 *   GET  /status        → Inertia (SSR-friendly) public page
 *   GET  /status.json   → Compact JSON for external monitors
 *   GET  /status.rss    → RSS feed of incidents
 */
class StatusPageController extends Controller
{
    public function index(StatusChecker $checker): Response
    {
        $components = StatusComponent::where('public', true)
            ->orderBy('display_order')
            ->get()
            ->map(function (StatusComponent $c) use ($checker) {
                $c->uptime_24h = $checker->uptimePercentage($c, 24);
                $c->uptime_30d = $checker->uptimePercentage($c, 24 * 30);
                $c->avg_response_ms = $checker->avgResponseTime($c, 24);
                $c->daily_uptime_90d = $checker->dailyUptimeBars($c, 90);

                return $c;
            })
            ->groupBy('category');

        // Active incidents (investigating / identified / monitoring)
        $activeIncidents = StatusIncident::where('public', true)
            ->whereIn('status', ['investigating', 'identified', 'monitoring'])
            ->orderByDesc('started_at')
            ->with(['updates' => fn ($q) => $q->orderByDesc('posted_at')])
            ->get();

        // Past incidents — last 30 days, resolved
        $pastIncidents = StatusIncident::where('public', true)
            ->where('status', 'resolved')
            ->where('resolved_at', '>', now()->subDays(30))
            ->orderByDesc('resolved_at')
            ->limit(20)
            ->get();

        // Scheduled / in-progress maintenance
        $maintenance = DB::table('status_scheduled_maintenance')
            ->whereIn('status', ['scheduled', 'in_progress'])
            ->orderBy('scheduled_start_at')
            ->limit(10)
            ->get();

        // Overall status — worst component wins
        $allComponents = StatusComponent::where('public', true)->get();
        $overallStatus = $this->resolveOverallStatus($allComponents);

        return Inertia::render('Public/Status', compact(
            'components',
            'activeIncidents',
            'pastIncidents',
            'maintenance',
            'overallStatus',
        ));
    }

    public function rss(): \Illuminate\Http\Response
    {
        $incidents = StatusIncident::where('public', true)
            ->orderByDesc('updated_at')
            ->limit(50)
            ->get();

        $xml = view('public.status-rss', compact('incidents'))->render();

        return response($xml, 200, ['Content-Type' => 'application/rss+xml; charset=UTF-8']);
    }

    public function jsonApi(StatusChecker $checker): JsonResponse
    {
        $allComponents = StatusComponent::where('public', true)->get();

        $components = $allComponents->map(fn (StatusComponent $c) => [
            'name' => $c->name,
            'slug' => $c->slug,
            'category' => $c->category,
            'status' => $c->current_status,
            'uptime_24h' => $checker->uptimePercentage($c, 24),
            'checked_at' => $c->last_check_at?->toIso8601String(),
        ]);

        $activeIncidents = StatusIncident::where('public', true)
            ->whereIn('status', ['investigating', 'identified', 'monitoring'])
            ->count();

        return response()->json([
            'overall' => $this->resolveOverallStatus($allComponents),
            'components' => $components,
            'active_incidents' => $activeIncidents,
            'last_updated' => now()->toIso8601String(),
        ]);
    }

    // ── Helpers ──────────────────────────────────────────────────────────────

    private function resolveOverallStatus($components): string
    {
        $statuses = $components->pluck('current_status');

        if ($statuses->contains('major_outage')) {
            return 'major_outage';
        }
        if ($statuses->contains('partial_outage')) {
            return 'partial_outage';
        }
        if ($statuses->contains('degraded')) {
            return 'degraded';
        }
        if ($statuses->contains('maintenance')) {
            return 'maintenance';
        }

        return 'operational';
    }
}
