<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreWinbackCampaignRequest;
use App\Models\WinbackCampaign;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class WinbackCampaignController extends Controller
{
    public function index(Request $request): Response
    {
        $query = WinbackCampaign::query()
            ->withCount('recipients')
            ->withCount(['recipients as reactivated_count' => function ($q): void {
                $q->where('reactivated', true);
            }]);

        if ($request->filled('status') && $request->input('status') !== 'all') {
            $query->where('status', $request->input('status'));
        }

        $campaigns = $query->orderByDesc('created_at')->paginate(25);

        // Compute reactivation rate for each campaign
        $campaigns->getCollection()->transform(function (WinbackCampaign $campaign) {
            $campaign->setAttribute(
                'reactivation_rate',
                $campaign->recipients_count > 0
                    ? round(($campaign->reactivated_count / $campaign->recipients_count) * 100, 1)
                    : 0
            );

            return $campaign;
        });

        return Inertia::render('Admin/WinbackCampaigns/Index', [
            'campaigns' => $campaigns,
            'filters' => [
                'status' => $request->input('status', 'all'),
            ],
        ]);
    }

    public function create(): Response
    {
        return Inertia::render('Admin/WinbackCampaigns/Create');
    }

    public function store(StoreWinbackCampaignRequest $request): RedirectResponse
    {
        WinbackCampaign::query()->create($request->validated());

        return redirect()
            ->route('winback-campaigns.index')
            ->with('success', 'Win-back campaign created successfully.');
    }

    public function show(WinbackCampaign $winbackCampaign): Response
    {
        $winbackCampaign->loadCount('recipients');
        $winbackCampaign->loadCount(['recipients as reactivated_count' => function ($q): void {
            $q->where('reactivated', true);
        }]);
        $winbackCampaign->loadCount(['recipients as unsubscribed_count' => function ($q): void {
            $q->whereNotNull('unsubscribed_at');
        }]);

        $totalEmailsSent = $winbackCampaign->recipients()->sum('current_email_index');
        $totalOpens = $winbackCampaign->recipients()->sum('opened_count');
        $totalClicks = $winbackCampaign->recipients()->sum('clicked_count');

        $recipients = $winbackCampaign->recipients()
            ->with('user:id,name,email')
            ->orderByDesc('created_at')
            ->paginate(25);

        $reactivationRate = $winbackCampaign->recipients_count > 0
            ? round(($winbackCampaign->reactivated_count / $winbackCampaign->recipients_count) * 100, 1)
            : 0;

        $openRate = $totalEmailsSent > 0
            ? round(($totalOpens / $totalEmailsSent) * 100, 1)
            : 0;

        return Inertia::render('Admin/WinbackCampaigns/Show', [
            'campaign' => $winbackCampaign,
            'recipients' => $recipients,
            'analytics' => [
                'total_recipients' => $winbackCampaign->recipients_count,
                'total_emails_sent' => (int) $totalEmailsSent,
                'open_rate' => $openRate,
                'reactivation_rate' => $reactivationRate,
                'reactivated_count' => $winbackCampaign->reactivated_count,
                'unsubscribed_count' => $winbackCampaign->unsubscribed_count,
                'total_opens' => (int) $totalOpens,
                'total_clicks' => (int) $totalClicks,
            ],
        ]);
    }

    public function edit(WinbackCampaign $winbackCampaign): Response
    {
        return Inertia::render('Admin/WinbackCampaigns/Edit', [
            'campaign' => $winbackCampaign,
        ]);
    }

    public function update(StoreWinbackCampaignRequest $request, WinbackCampaign $winbackCampaign): RedirectResponse
    {
        $winbackCampaign->update($request->validated());

        return redirect()
            ->route('winback-campaigns.index')
            ->with('success', 'Win-back campaign updated successfully.');
    }

    public function destroy(WinbackCampaign $winbackCampaign): RedirectResponse
    {
        $winbackCampaign->update(['status' => 'archived']);

        return redirect()
            ->route('winback-campaigns.index')
            ->with('success', 'Win-back campaign archived successfully.');
    }
}
