<?php

declare(strict_types=1);

namespace App\Application\Campaign;

use App\Application\Campaign\Services\SpotifyCampaignService;
use App\Framework\Attributes\Route;
use App\Framework\Http\Method;
use App\Framework\Http\Session\Session;
use App\Framework\Router\Result\Redirect;

/**
 * Pre-Save Campaign
 *
 * Handles platform-specific pre-save redirects
 */
final readonly class PreSaveCampaign
{
    public function __construct(
        private CampaignService $campaignService,
        private SpotifyCampaignService $spotifyCampaignService
    ) {
    }

    #[Route(path: '/campaign/{slug}/presave/{platform}', method: Method::GET)]
    public function __invoke(string $slug, string $platform, Session $session): Redirect
    {
        // Fetch campaign
        $campaign = $this->campaignService->findBySlug($slug);

        if (! $campaign) {
            return Redirect::to('/404')
                ->withFlash('error', 'Campaign not found');
        }

        // Record pre-save
        $this->campaignService->recordPreSave(
            $campaign->id,
            $platform,
            $session->getId()
        );

        // Handle platform-specific flow
        if ($platform === 'spotify') {
            return $this->handleSpotifyPreSave($session, $campaign, $slug);
        }

        if ($platform === 'apple-music') {
            return $this->handleAppleMusicPreSave($campaign, $slug);
        }

        return Redirect::to("/campaign/{$slug}")
            ->withFlash('error', 'Invalid platform');
    }

    /**
     * Handle Spotify pre-save with OAuth flow
     */
    private function handleSpotifyPreSave(Session $session, object $campaign, string $slug): Redirect
    {
        if (! $campaign->spotify_enabled || ! $campaign->spotify_uri) {
            return Redirect::to("/campaign/{$slug}")
                ->withFlash('error', 'Spotify is not enabled for this campaign');
        }

        // Generate OAuth state for CSRF protection
        $state = bin2hex(random_bytes(16));

        // Store state and campaign slug in session
        $session->set('spotify_oauth_state', $state);
        $session->set('spotify_campaign_slug', $slug);

        // Get Spotify authorization URL
        $authUrl = $this->spotifyCampaignService->getAuthorizationUrl($campaign, $state);

        // Redirect to Spotify for authorization
        return Redirect::to($authUrl);
    }

    /**
     * Handle Apple Music pre-save (direct link, no OAuth)
     */
    private function handleAppleMusicPreSave(object $campaign, string $slug): Redirect
    {
        if (! $campaign->apple_music_enabled || ! $campaign->apple_music_id) {
            return Redirect::to("/campaign/{$slug}")
                ->withFlash('error', 'Apple Music is not enabled for this campaign');
        }

        $appleUrl = "https://music.apple.com/us/album/{$campaign->apple_music_id}";

        // Redirect to success page with Apple Music URL
        return Redirect::to("/campaign/{$slug}/success")
            ->withFlash('success', 'Redirecting to Apple Music...')
            ->withSession([
                'presave_platform' => 'Apple Music',
                'presave_url' => $appleUrl,
            ]);
    }
}
