<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Offerwall;
use App\Models\ProviderOffer;
use App\Support\OfferCurator;
use App\Support\ProviderOfferImporter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ProviderOffersController extends Controller
{
    public function index(Request $request, ProviderOfferImporter $importer)
    {
        $offers = ProviderOffer::with(['offerwall'])
            ->withCount('clicks')
            ->when($request->filled('search'), function ($query) use ($request) {
                $search = $request->query('search');

                $query->where(function ($nested) use ($search) {
                    $nested->where('name', 'like', "%{$search}%")
                        ->orWhere('description', 'like', "%{$search}%")
                        ->orWhere('provider_offer_id', 'like', "%{$search}%")
                        ->orWhereHas('offerwall', fn ($wall) => $wall->where('name', 'like', "%{$search}%"));
                });
            })
            ->when($request->filled('offerwall_id'), fn ($query) => $query->where('offerwall_id', $request->query('offerwall_id')))
            ->when($request->filled('category'), fn ($query) => $query->where('category', $request->query('category')))
            ->when($request->filled('status'), function ($query) use ($request) {
                if ($request->query('status') === 'active') {
                    $query->where('is_active', true);
                }

                if ($request->query('status') === 'hidden') {
                    $query->where('is_active', false);
                }
            })
            ->orderByDesc('is_hot')
            ->orderByDesc('is_featured')
            ->orderByDesc('reward_points')
            ->paginate(20)
            ->withQueryString();

        $stats = [
            'total' => ProviderOffer::count(),
            'active' => ProviderOffer::where('is_active', true)->count(),
            'hidden' => ProviderOffer::where('is_active', false)->count(),
            'hot' => ProviderOffer::where('is_hot', true)->count(),
        ];

        $offerwalls = Offerwall::withCount('providerOffers')->orderBy('name')->get();
        $feedStates = $offerwalls->mapWithKeys(function (Offerwall $offerwall) use ($importer) {
            $config = $offerwall->sdk_data ?? [];

            return [$offerwall->id => [
                'enabled' => $importer->enabled($offerwall),
                'configured' => $importer->configured($offerwall),
                'live' => $offerwall->hasLiveApiFeed(),
                'success' => $config['offer_feed_last_success'] ?? null,
                'message' => $config['offer_feed_last_message'] ?? null,
                'count' => (int) ($config['offer_feed_last_count'] ?? 0),
                'checked_at' => $config['offer_feed_last_checked_at'] ?? null,
            ]];
        });
        $liveOfferwallIds = $offerwalls
            ->filter(fn (Offerwall $offerwall) => $offerwall->hasLiveApiFeed())
            ->pluck('id');
        $stats['live'] = ProviderOffer::where('is_active', true)
            ->whereIn('offerwall_id', $liveOfferwallIds)
            ->count();

        return view('admin.provider-offers', [
            'offers' => $offers,
            'stats' => $stats,
            'offerwalls' => $offerwalls,
            'feedStates' => $feedStates,
        ]);
    }

    public function update(Request $request, ProviderOffer $providerOffer)
    {
        $data = $request->validate([
            'name' => ['sometimes', 'required', 'string', 'max:255'],
            'category' => ['sometimes', 'required', 'in:games,other,surveys,partners'],
            'reward_points' => ['sometimes', 'required', 'numeric', 'min:0'],
            'is_active' => ['sometimes', 'boolean'],
            'is_featured' => ['sometimes', 'boolean'],
            'is_hot' => ['sometimes', 'boolean'],
            'curation_locked' => ['sometimes', 'boolean'],
        ]);

        foreach (['is_active', 'is_featured', 'is_hot', 'curation_locked'] as $field) {
            if ($request->has($field)) {
                $data[$field] = $request->boolean($field);
            }
        }

        $providerOffer->update($data);

        return back()->with('status', 'Provider offer updated.');
    }

    public function bulk(Request $request)
    {
        $data = $request->validate([
            'ids' => ['required', 'array', 'min:1'],
            'ids.*' => ['integer', 'exists:provider_offers,id'],
            'action' => ['required', 'in:show,hide,delete,mark_hot,mark_featured,clear,lock,unlock'],
        ]);

        if ($data['action'] === 'delete') {
            $deleted = ProviderOffer::whereIn('id', $data['ids'])->delete();

            return back()->with('status', "Deleted {$deleted} provider offer(s).");
        }

        $updates = match ($data['action']) {
            'show' => ['is_active' => true],
            'hide' => ['is_active' => false],
            'mark_hot' => ['is_hot' => true],
            'mark_featured' => ['is_featured' => true],
            'clear' => ['is_hot' => false, 'is_featured' => false],
            'lock' => ['curation_locked' => true],
            'unlock' => ['curation_locked' => false],
        };

        DB::transaction(function () use ($data, $updates) {
            ProviderOffer::whereIn('id', $data['ids'])->update($updates);
        });

        return back()->with('status', 'Bulk action applied to '.count($data['ids']).' offer(s).');
    }

    public function syncAll(ProviderOfferImporter $importer, OfferCurator $curator)
    {
        $messages = [];

        Offerwall::query()
            ->orderBy('name')
            ->get()
            ->each(function (Offerwall $offerwall) use ($importer, &$messages) {
                $result = $importer->sync($offerwall);
                $messages[] = $offerwall->name.': '.$result['message'];
            });

        $curator->curate();

        return back()->with('status', $messages ? implode(' ', $messages) : 'No active providers were found.');
    }

    public function syncProvider(Offerwall $offerwall, ProviderOfferImporter $importer, OfferCurator $curator)
    {
        $result = $importer->sync($offerwall);
        $curator->curate($offerwall->id);

        return back()->with('status', $offerwall->name.': '.$result['message']);
    }

    public function curateNow(OfferCurator $curator)
    {
        $summary = $curator->curate(null, true);

        return back()->with(
            'status',
            "Curation complete: {$summary['hot']} marked hot, {$summary['featured']} marked featured, {$summary['cleared']} cleared."
        );
    }
}
