<?php

namespace App\Http\Controllers\Integration;

use App\Http\Controllers\Controller;
use App\Models\CalendarIntegration;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class OutlookCalendarController extends Controller
{
    private function authUrl(): string
    {
        $tenant = config('services.microsoft.tenant', 'common');
        return "https://login.microsoftonline.com/{$tenant}/oauth2/v2.0/authorize";
    }

    private function tokenUrl(): string
    {
        $tenant = config('services.microsoft.tenant', 'common');
        return "https://login.microsoftonline.com/{$tenant}/oauth2/v2.0/token";
    }

    private const ME_URL       = 'https://graph.microsoft.com/v1.0/me';
    private const CALENDAR_URL = 'https://graph.microsoft.com/v1.0/me/calendars?$top=1&$orderby=name';

    public function redirect()
    {
        $state = Str::random(40);
        session(['outlook_oauth_state' => $state]);

        $query = http_build_query([
            'client_id'     => config('services.microsoft.client_id'),
            'redirect_uri'  => config('services.microsoft.redirect'),
            'response_type' => 'code',
            'scope'         => 'openid email profile Calendars.ReadWrite offline_access',
            'state'         => $state,
        ]);

        return redirect($this->authUrl().'?'.$query);
    }

    public function callback(Request $request)
    {
        if ($request->state !== session('outlook_oauth_state')) {
            return redirect()->route('integrations.index')
                ->with('integration_error', 'Ungültiger State-Parameter.');
        }

        if ($request->has('error')) {
            return redirect()->route('integrations.index')
                ->with('integration_error', 'Zugriff verweigert: '.$request->error_description);
        }

        $response = Http::asForm()->post($this->tokenUrl(), [
            'code'          => $request->code,
            'client_id'     => config('services.microsoft.client_id'),
            'client_secret' => config('services.microsoft.client_secret'),
            'redirect_uri'  => config('services.microsoft.redirect'),
            'grant_type'    => 'authorization_code',
        ]);

        if ($response->failed()) {
            return redirect()->route('integrations.index')
                ->with('integration_error', 'Token-Austausch fehlgeschlagen.');
        }

        $tokens = $response->json();

        $me = Http::withToken($tokens['access_token'])
            ->get(self::ME_URL)
            ->json();

        $calendars = Http::withToken($tokens['access_token'])
            ->get(self::CALENDAR_URL)
            ->json();

        $primaryCalendar = $calendars['value'][0] ?? null;

        CalendarIntegration::updateOrCreate(
            ['user_id' => auth()->id(), 'provider' => 'outlook'],
            [
                'provider_email'   => $me['mail'] ?? $me['userPrincipalName'] ?? null,
                'calendar_id'      => $primaryCalendar['id'] ?? null,
                'calendar_name'    => $primaryCalendar['name'] ?? 'Primärer Kalender',
                'access_token'     => $tokens['access_token'],
                'refresh_token'    => $tokens['refresh_token'] ?? null,
                'token_expires_at' => now()->addSeconds($tokens['expires_in'] ?? 3600),
            ]
        );

        return redirect()->route('integrations.index')
            ->with('integration_connected', 'outlook');
    }
}
