<?php

namespace App\Http\Controllers\Api\Consultant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Consultant\StoreListingRequest;
use App\Http\Requests\Consultant\UpdateListingRequest;
use App\Http\Resources\ConsultantListingResource;
use App\Http\Resources\ListingDetailResource;
use App\Models\Listing;
use App\Models\ListingCategory;
use App\Services\ListingFeatureService;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;

class ListingController extends Controller
{
    public function __construct(private ListingFeatureService $features) {}

    public function index(Request $request)
    {
        $profile = $this->consultantProfile($request);

        $query = Listing::query()
            ->where('consultant_profile_id', $profile->id)
            ->with(['category', 'coverImage'])
            ->withCount('media')
            ->latest();

        if ($request->filled('status')) {
            $query->where('status', $request->query('status'));
        }

        return ConsultantListingResource::collection($query->paginate(12));
    }

    public function store(StoreListingRequest $request)
    {
        $profile = $this->consultantProfile($request);
        $category = ListingCategory::findOrFail($request->integer('category_id'));




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



        $listing = Listing::create([
            'consultant_profile_id' => $profile->id,
            'category_id' => $category->id,
            'title' => $request->input('title'),
            'slug' => $this->uniqueSlug($request->input('title')),
            'short_description' => $request->input('short_description'),
            'description' => $request->input('description'),
            'price' => $request->input('price'),
            'currency' => $request->input('currency', 'EUR'),
            'country' => $request->input('country'),
            'city' => $request->input('city'),
            'district' => $request->input('district'),
            'neighborhood' => $request->input('neighborhood'),
            'address' => $request->input('address'),
            'latitude' => $request->input('latitude'),
            'longitude' => $request->input('longitude'),
            'gross_area' => $request->input('gross_area'),
            'net_area' => $request->input('net_area'),
            'status' => 'pending',
            'is_featured' => false,
            'view_count' => 0,
        ]);

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

        return (new ListingDetailResource(
            $listing->load(['category', 'consultantProfile', 'media', 'videos', 'featureValues.feature'])
        ))->response()->setStatusCode(201);
    }

    public function show(Request $request, Listing $listing)
    {
        $this->authorizeOwnership($request, $listing);

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

    public function update(UpdateListingRequest $request, Listing $listing)
    {
        $this->authorizeOwnership($request, $listing);

        // version gönderilmezse mevcut sürüm kullanılır (eski istemciler 409'a
        // düşmesin); gönderildiğinde iyimser kilit tam olarak uygulanır.
        $version = $request->filled('version')
            ? $request->integer('version')
            : (int) $listing->version;


        $category = $request->filled('category_id')
            ? ListingCategory::findOrFail($request->integer('category_id'))
            : $listing->category;

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

        DB::transaction(function () use ($request, $version, $listing, $category, $preparedFeatures) {
            // Çevrilebilir alanlar (title vb.) MODEL üzerinden doldurulmalı: ham
            // Query Builder update'i düz string yazar ve JSON kolon kontrolüne
            // takılır. fill sonrası getDirty() DB'ye hazır (json-encode edilmiş)
            // değerleri verir; kilitli tek UPDATE bu değerlerle atılır.
            $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;
            }

            // Reddedilmiş ilan danışman düzenleyince yeniden incelemeye döner
            // (kaynak İLANIN durumu; istek gövdesinde status alanı yok).
            if ($listing->status === 'rejected') {
                $listing->status = 'pending';
            }

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

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

            if ($upddateRows === 0) {
                abort(
                    409,
                    'Bu ilanı siz düzenlerken bir başkası tarafından güncellendi.Lütfen karışıklık olmamması için ' .
                        'Sayfayı günceliyip tekrar değerlendiriniz '
                );
            }

            $listing->refresh();

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

        return new ListingDetailResource(
            $listing->load([
                'category',
                'consultantProfile',
                '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;
        }

        // Reddedilmiş bir ilan düzenlenince tekrar incelemeye gönderilir.
        if ($listing->status === 'rejected') {
            $listing->status = 'pending';
        }

        $listing->save();

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

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

    public function destroy(Request $request, Listing $listing)
    {
        $this->authorizeOwnership($request, $listing);

        $listing->delete();

        return response()->json(['message' => 'İlan silindi.']);
    }

    public function submit(Request $request, Listing $listing)
    {
        $this->authorizeOwnership($request, $listing);

        if (! in_array($listing->status, ['draft', 'rejected'], true)) {
            return response()->json([
                'message' => 'Bu ilan zaten incelemede veya yayında.',
            ], 422);
        }

        $listing->update(['status' => 'pending']);

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

    public function changeDealStatus(Request $request, Listing $listing)
    {
        $this->authorizeOwnership($request, $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,
            ],
        ]);
    }




    //Auth kontollleri
    private function authorizeOwnership(Request $request, Listing $listing): void
    {
        $profile = $this->consultantProfile($request);

        abort_unless($listing->consultant_profile_id === $profile->id, 403, 'Bu ilan üzerinde yetkiniz yok.');
    }

    private function consultantProfile(Request $request)
    {
        $profile = $request->user()->consultantProfile;

        abort_unless($profile, 403, 'Danışman profiliniz bulunmuyor.');

        return $profile;
    }

    private function uniqueSlug(string $title): string
    {
        $base = Str::slug($title) ?: 'listing';
        $slug = $base;
        $suffix = 1;

        // Soft-delete: çöpe atılmış ilanların slug'ları da doludur (unique index).
        while (Listing::withTrashed()->where('slug', $slug)->exists()) {
            $slug = "{$base}-{$suffix}";
            $suffix++;
        }

        return $slug;
    }
}
