<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Consultant\UpdateListingRequest;
use App\Http\Resources\AdminListingResource;
use App\Models\ConsultantProfile;
use App\Models\Listing;
use App\Models\ListingCategory;
use App\Models\Setting;
use App\Services\ListingFeatureService;
use App\Services\ListingFilterService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ListingModerationController extends Controller
{
    public function __construct(
        private ListingFilterService $filters,
        private ListingFeatureService $features,
    ) {}

    public function index(Request $request)
    {
        $query = Listing::query()
            ->with(['category', 'consultantProfile.user', 'coverImage'])
            ->withCount('media');

        // Moderasyon: tüm statüleri görebilir, statüye göre filtreler.
        if ($request->filled('status')) {
            $query->where('status', $request->query('status'));
        }

        if ($request->filled('search')) {
            $search = $request->query('search');
            $locale = app()->getLocale();
            $query->where(function ($q) use ($search, $locale) {
                $q->whereRaw("COALESCE(JSON_UNQUOTE(JSON_EXTRACT(title, CONCAT('$.', ?))), JSON_UNQUOTE(JSON_EXTRACT(title, '$.en'))) LIKE ?", [$locale, "%{$search}%"])
                    ->orWhere('city', 'like', "%{$search}%");
            });
        }

        if ($request->filled('category')) {
            $query->whereHas('category', fn($q) => $q->where('slug', $request->query('category')));
        }

        if (is_numeric($request->query('price_min'))) {
            $query->where('price', '>=', $request->query('price_min'));
        }
        if (is_numeric($request->query('price_max'))) {
            $query->where('price', '<=', $request->query('price_max'));
        }

        if ($request->boolean('featured')) {
            $query->where('is_featured', true);
        }

        // Sıralama (public ile aynı seçenekler); varsayılan en yeni oluşturulan.
        if ($request->filled('sort')) {
            $this->filters->applySort($query, $request->query('sort'));
        } else {
            $query->latest();
        }

        return AdminListingResource::collection($query->paginate(15)->withQueryString());
    }

    public function show(Listing $listing)
    {
        $listing->load([
            'category',
            'consultantProfile.user',
            'media',
            'videos',
            'featureValues.feature',
        ]);

        return new AdminListingResource($listing);
    }


    public function update(UpdateListingRequest $request, Listing $listing)
    {
        $category = $request->filled('category_id')
            ? ListingCategory::findOrFail($request->integer('category_id'))
            : $listing->category;

        $preparedFeatures = $this->features->validate($category, $request->input('features', []));

        
        $version = $request->filled('version')
            ? $request->integer('version')
            : (int) $listing->version;

        
        return DB::transaction(function () use (
            $category,
            $preparedFeatures,
            $request,
            $listing,
            $version,
        ) {
            
            $listing->fill($request->only([
                'title',
                'short_description',
                'description',
                'price',
                'currency',
                'country',
                'city',
                'district',
                'neighborhood',
                'address',
                'latitude',
                'longitude',
                'gross_area',
                'net_area',
            ]));

            if ($request->filled('category_id')) {
                $listing->category_id = $category->id;
            }

            $data = $listing->getDirty();
            $data['version'] = $version + 1;

            $updateRows = Listing::query()
                ->whereKey($listing->id)
                ->where('version', $version)
                ->update($data);

            if ($updateRows === 0) {
                abort(
                    409,
                    'Bu ilan siz düzenlemeden önce düzenleme talebi aldı lütfen ilanı baştan kontrol ediniz'
                );
            }

            $listing->refresh();

            $this->features->sync($listing, $preparedFeatures);

            return new AdminListingResource(
                $listing->load(['category', 'consultantProfile.user', 'media', 'videos', 'featureValues.feature'])
            );
        });



        /* $listing->fill($request->only([
            'title',
            'short_description',
            'description',
            'price',
            'currency',
            'country',
            'city',
            'district',
            'neighborhood',
            'address',
            'latitude',
            'longitude',
            'gross_area',
            'net_area',
        ]));

        if ($request->filled('category_id')) {
            $listing->category_id = $category->id;
        }

        $listing->save();

        $this->features->sync($listing, $preparedFeatures);

        return new AdminListingResource(
            $listing->load(['category', 'consultantProfile.user', 'media', 'videos', 'featureValues.feature'])
        ); */
    }

    public function approve(Listing $listing)
    {
        if ($listing->status === 'published') {
            return response()->json(['message' => 'İlan zaten yayında.'], 422);
        }

        
        $hasCompany = $listing->consultantProfile?->company_id !== null;
        if ($hasCompany && $listing->status !== 'agency_approved') {
            return response()->json([
                'message' => 'Bu ilan firmaya bağlı bir danışmana ait; önce firma onayı gerekir.',
            ], 422);
        }

        $listing->update([
            'status' => 'published',
            'rejection_reason' => null,
            'published_at' => $listing->published_at ?? now(),
        ]);

        //Burda artık listing sistemde kalam doğrulaması yapılacak

        $day = (int) Setting::query()
            ->where('key', 'listing_reconfirmation_days')
            ->value('value');

        $listing->update([
            'last_confirmed_at' => now(),
            // Ayar seed edilmemişse 0 gün olup ertesi gün pending'e düşmesin.
            'reconfirmation_due_at' => now()->addDays($day ?: 30),
            'reconfirmation_status' => Listing::RECONFIRMATION_CONFIRMED

        ]);


        return new AdminListingResource(
            $listing->load(['category', 'consultantProfile.user', 'coverImage'])
        );
    }

    public function reject(Request $request, Listing $listing)
    {
        $data = $request->validate([
            'reason' => ['required', 'string', 'max:1000'],
        ]);

        $listing->update([
            'status' => 'rejected',
            'rejection_reason' => $data['reason'],
            'published_at' => null,
        ]);

        return new AdminListingResource(
            $listing->load(['category', 'consultantProfile.user', 'coverImage'])
        );
    }

    public function setFeatured(Request $request, Listing $listing)
    {
        $data = $request->validate([
            'is_featured' => ['required', 'boolean'],
        ]);

        $listing->update(['is_featured' => $data['is_featured']]);

        return new AdminListingResource(
            $listing->load(['category', 'consultantProfile.user', 'coverImage'])
        );
    }

    public function changeConsultant(Request $request, Listing $listing)
    {
        $data = $request->validate([
            'consultant_profile_id' => ['required', 'integer', 'exists:consultant_profiles,id'],
        ]);

        $updated = $listing->update([
            'consultant_profile_id' => $data['consultant_profile_id']
        ]);


        return response()->json([
            'message' => 'İlanın danışmanı başarılı bir şekilde değiştirildi'

        ], 201);
    }

    public function changeDealStatus(Request $request, Listing $listing)
    {
        $data = $request->validate([
            'deal_status' => ['required', 'string', 'in:available,sold,rented'],
        ]);

        $listing->update([
            'deal_status' => $data['deal_status'],
        ]);

        return response()->json([
            'message' => 'İlan durumu güncellendi.',
            'data' => [
                'slug' => $listing->slug,
                'deal_status' => $listing->deal_status,
            ],
        ]);
    }
}
