<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Campaign;
use App\Models\Offerwall;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Rules\OfferUrlTemplate;

class CampaignsController extends Controller
{
    public function index(Request $request)
    {
        $campaigns = Campaign::with('offerwall')
            ->when($request->filled('status'), fn ($query) => $query->where('status', $request->input('status')))
            ->when($request->filled('search'), fn ($query) => $query->where('name', 'like', '%' . $request->input('search') . '%'))
            ->latest()
            ->paginate(15)
            ->withQueryString();

        $offerwalls = Offerwall::orderBy('name')->get();
        $stats = [
            'active' => Campaign::where('status', 'active')->count(),
            'draft' => Campaign::where('status', 'draft')->count(),
            'paused' => Campaign::where('status', 'paused')->count(),
            'featured' => Campaign::where('featured', true)->count(),
        ];

        return view('admin.campaigns', compact('campaigns', 'offerwalls', 'stats'));
    }

    public function store(Request $request)
    {
        Campaign::create($this->validated($request));
        return redirect()->route('admin.campaigns')->with('success', 'Campaign created.');
    }

    public function update(Request $request, Campaign $campaign)
    {
        $campaign->update($this->validated($request));
        return redirect()->route('admin.campaigns')->with('success', 'Campaign updated.');
    }

    public function destroy(Campaign $campaign)
    {
        $campaign->delete();
        return redirect()->route('admin.campaigns')->with('success', 'Campaign deleted.');
    }

    public function bulk(Request $request)
    {
        $data = $request->validate([
            'ids' => ['required', 'array', 'min:1'],
            'ids.*' => ['integer', 'exists:campaigns,id'],
            'action' => ['required', 'in:activate,draft,pause,end,feature,unfeature,delete'],
        ]);

        $count = DB::transaction(function () use ($data) {
            $query = Campaign::whereIn('id', $data['ids']);

            return match ($data['action']) {
                'delete' => $query->delete(),
                'activate' => $query->update(['status' => 'active']),
                'draft' => $query->update(['status' => 'draft']),
                'pause' => $query->update(['status' => 'paused']),
                'end' => $query->update(['status' => 'ended']),
                'feature' => $query->update(['featured' => true]),
                'unfeature' => $query->update(['featured' => false]),
            };
        });

        return back()->with('success', "Bulk action applied to {$count} campaign(s).");
    }

    private function validated(Request $request): array
    {
        $data = $request->validate([
            'offerwall_id' => ['nullable', 'exists:offerwalls,id'],
            'name' => ['required', 'string', 'max:140'],
            'description' => ['nullable', 'string', 'max:1000'],
            'reward_points' => ['required', 'numeric', 'min:0'],
            'payout' => ['required', 'numeric', 'min:0'],
            'status' => ['required', 'in:draft,active,paused,ended'],
            'featured' => ['nullable', 'boolean'],
            'is_hot' => ['nullable', 'boolean'],
            'curation_locked' => ['nullable', 'boolean'],
            'category' => ['required', 'in:games,other,surveys,partners'],
            'device' => ['required', 'in:all,desktop,mobile,android,ios'],
            'countries' => ['nullable', 'string', 'max:180'],
            'direct_url' => ['nullable', new OfferUrlTemplate, 'max:2000'],
            'direct_launch_mode' => ['required', 'in:iframe,external'],
            'icon' => ['nullable', 'image', 'max:12048'],
            'starts_at' => ['nullable', 'date'],
            'ends_at' => ['nullable', 'date', 'after_or_equal:starts_at'],
        ]) + ['featured' => false, 'is_hot' => false, 'curation_locked' => false];

        if ($request->hasFile('icon')) {
            $data['icon_path'] = $request->file('icon')->store('campaigns', 'public');
        }

        unset($data['icon']);

        return $data;
    }
}
