<?php

namespace App\Http\Controllers\Api\Company;

use App\Http\Controllers\Controller;
use App\Http\Resources\AdminListingResource;
use App\Models\Company;
use App\Models\Listing;
use App\Services\ListingFilterService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

/**
 * Agency Panel ilan moderasyonu: firma, kendi danışmanlarının ilanlarını görür,
 * onaylar (yayınlar) veya reddeder. Admin moderasyon yetkisi tüm ilanlar üzerinde
 * ayrıca devam eder; bağımsız (firmasız) danışman ilanlarını eskisi gibi admin onaylar.
 */
class CompanyListingsController extends Controller
{
    public function __construct(private ListingFilterService $filters) {}

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

        $query = Listing::query()
            ->whereHas('consultantProfile', fn($q) => $q->where('company_id', $company->id))
            ->with(['category', 'consultantProfile.user', 'coverImage'])
            ->withCount('media');

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

        // Belirli bir danışmana göre filtre (firmaya ait olmalı).
        if ($request->filled('consultant_id')) {
            $query->whereHas('consultantProfile', function ($q) use ($company, $request) {
                $q->where('company_id', $company->id)
                    ->where('id', $request->integer('consultant_id'));
            });
        }

        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 ($request->filled('sort')) {
            $this->filters->applySort($query, $request->query('sort'));
        } else {
            $query->latest();
        }

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

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

        $listing->load([
            'category',
            'consultantProfile.user',
            'media',
            'featureValues.feature',
        ]);

        return new AdminListingResource($listing);
    }

    
    public function approve(Request $request, Listing $listing)
    {
        $this->authorizeListing($request, $listing);

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


        if ($listing->status === 'agency_approved') {
            return response()->json(['message' => 'Firma onayı verildi; yönetici onayı bekleniyor.'], 422);
        }

        // version gönderilmezse mevcut sürümle devam edilir (kilit istemci
        // sürüm bildirdiğinde uygulanır); return olmazsa yanıt gövdesiz kalır.
        $version = $request->filled('version')
            ? $request->integer('version')
            : (int) $listing->version;

        return DB::transaction(function () use ($request, $listing, $version) {

            $updateRows = Listing::query()
                ->whereKey($listing->id)
                ->where('version', $version)
                ->update([
                    'status' => 'agency_approved',
                    'rejection_reason' => null,
                    'version' => $version + 1
                ]);

            if ($updateRows === 0) {
                abort(
                    409,
                    'Siz işlem yapmadan önce ilanda değişikllikler meydana geldi ' .
                        'ilanı tekrar inceleyip karar vermenizi tavsiye ediyoruz'
                );
            }

            $listing->refresh();

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






        /* $listing->update([
            'status' => 'agency_approved',
            'rejection_reason' => null,
        ]);

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

    public function reject(Request $request, Listing $listing)
    {
        $this->authorizeListing($request, $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'])
        ); */


        // approve ile aynı desen: sürüm fallback'i + yanıtın dönmesi için return.
        $version = $request->filled('version')
            ? $request->integer('version')
            : (int) $listing->version;

        return DB::transaction(function () use ($data, $listing, $version) {

            $updateRows = Listing::query()
                ->whereKey($listing->id)
                ->where('version', $version)
                ->update([
                    'status' => 'rejected',
                    'rejection_reason' => $data['reason'],
                    'published_at' => null,
                    'version' => $version + 1
                ]);

            if ($updateRows === 0) {
                abort(
                    409,
                    'Siz işlem yapmadan önce ilanda değişikllikler meydana geldi ' .
                        'ilanı tekrar inceleyip karar vermenizi tavsiye ediyoruz'
                );
            }

            $listing->refresh();

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




    }

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








    /** İstek sahibinin onaylı firmasını döndürür; yoksa 403. */
    private function company(Request $request): Company
    {
        $company = $request->user()->company;

        abort_unless(
            $company && $company->application_status === Company::STATUS_APPROVED,
            403,
            'Onaylı bir firmanız bulunmuyor.'
        );

        return $company;
    }

    private function authorizeListing(Request $request, Listing $listing): void
    {
        $company = $this->company($request);

        abort_unless(
            $listing->consultantProfile?->company_id === $company->id,
            403,
            'Bu ilan firmanızın danışmanlarına ait değil.'
        );
    }
}
