<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Jobs\AuditMetaCampaignSafetyJob;
use App\Jobs\SyncMetaAdsInsightsJob;
use App\Models\Item;
use App\Models\MetaCampaignSafetyAudit;
use App\Services\Meta\MetaAdsPerformanceService;
use App\Services\Meta\MetaAdsProductRuleService;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;

class MetaAdsPerformanceController extends Controller
{
    public function __construct(
        private readonly MetaAdsPerformanceService $performanceService,
        private readonly MetaAdsProductRuleService $productRuleService
    ) {
    }

    public function index(Request $request)
    {
        $data = $this->performanceService->report($request);
        $data['rule_settings'] = $this->productRuleService->settings();
        $data['safety_audit'] = Schema::hasTable('meta_campaign_safety_audits')
            ? MetaCampaignSafetyAudit::query()->latest('id')->first()
            : null;

        return view(
            'admin-views.report.meta-ads-performance',
            $data
        );
    }

    public function sync(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'from' => 'required|date',
            'to' => 'required|date|after_or_equal:from',
        ]);

        if ($validator->fails()) {
            Toastr::error($validator->errors()->first());

            return back()->withInput();
        }

        $from = Carbon::parse((string) $request->input('from'))->startOfDay();
        $to = Carbon::parse((string) $request->input('to'))->endOfDay();

        if ($from->diffInDays($to) > 180) {
            Toastr::error('Meta Ads Insights sync is limited to 180 days per request.');

            return back()->withInput();
        }

        if (config('queue.default') === 'sync') {
            Toastr::error('Meta Ads Insights sync requires an asynchronous queue driver.');

            return back();
        }

        SyncMetaAdsInsightsJob::dispatch($from->toDateString(), $to->toDateString());
        Toastr::success('Meta Ads Insights sync queued.');

        return back();
    }

    public function auditSafety()
    {
        if (config('queue.default') === 'sync') {
            Toastr::error('Meta targeting audit requires an asynchronous queue driver.');

            return back();
        }

        AuditMetaCampaignSafetyJob::dispatch();
        Toastr::success('Read-only Meta targeting audit queued.');

        return back();
    }

    public function updateProduct(Request $request, int $item)
    {
        $validator = Validator::make($request->all(), [
            'priority' => 'required|in:high,medium,low',
            'excluded' => 'nullable|boolean',
            'exclusion_reason' => 'nullable|string|max:255',
        ]);

        if ($validator->fails()) {
            Toastr::error($validator->errors()->first());

            return back();
        }

        $product = Item::withoutGlobalScopes()->findOrFail($item);
        $this->productRuleService->updateProduct(
            $product,
            (string) $request->input('priority'),
            $request->boolean('excluded'),
            $request->input('exclusion_reason'),
            auth('admin')->id()
        );

        Toastr::success('Meta product controls updated. The current winning ad was not edited.');

        return back();
    }

    public function updateRules(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'auto_exclude_enabled' => 'nullable|boolean',
            'auto_restore_enabled' => 'nullable|boolean',
            'minimum_final_orders' => 'required|integer|min:1|max:1000',
            'maximum_return_rate' => 'required|numeric|min:0|max:100',
            'minimum_profit' => 'required|numeric|min:-100000000|max:100000000',
            'high_profit_minimum_profit' => 'required|numeric|min:-100000000|max:100000000',
            'high_profit_minimum_roas' => 'required|numeric|min:0|max:1000',
        ]);

        if ($validator->fails()) {
            Toastr::error($validator->errors()->first());

            return back();
        }

        $values = $validator->validated();
        $values['auto_exclude_enabled'] = $request->boolean('auto_exclude_enabled');
        $values['auto_restore_enabled'] = $request->boolean('auto_restore_enabled');
        $this->productRuleService->updateSettings($values, auth('admin')->id());

        Toastr::success('Meta product rule settings updated. Rules run after the next successful daily sync.');

        return back();
    }
}
