<?php

namespace App\Http\Controllers\Api\Company;

use App\Http\Controllers\Controller;
use App\Http\Requests\Company\StoreConsultantRequest;
use App\Http\Requests\Company\UpdateConsultantRequest;
use App\Models\Company;
use App\Models\ConsultantProfile;
use App\Models\Permission;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class CompanyConsultantsController extends Controller
{
    public function index(Request $request)
    {
        $company = $this->company($request);

        $query = $company->consultants()
            ->with('user:id,name,email')
            ->withCount([
                'listings',
                'listings as published_listings_count' => fn ($q) => $q->where('status', 'published'),
                'listings as pending_listings_count' => fn ($q) => $q->where('status', 'pending'),
            ])
            ->latest('id');

        // ?status=active|inactive
        if (in_array($request->query('status'), ['active', 'inactive'], true)) {
            $query->where('is_active', $request->query('status') === 'active');
        }

        if ($request->filled('search')) {
            $search = $request->query('search');
            $query->where(function ($q) use ($search) {
                $q->where('company_name', 'like', "%{$search}%")
                    ->orWhereHas('user', function ($uq) use ($search) {
                        $uq->where('name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    });
            });
        }

        $consultants = $query->paginate(20)->through(fn (ConsultantProfile $c) => $this->consultantArray($c));

        return response()->json($consultants);
    }

    public function show(Request $request, ConsultantProfile $consultant)
    {
        $this->authorizeConsultant($request, $consultant);

        $consultant->load('user:id,name,email')->loadCount([
            'listings',
            'listings as published_listings_count' => fn ($q) => $q->where('status', 'published'),
            'listings as pending_listings_count' => fn ($q) => $q->where('status', 'pending'),
        ]);

        return response()->json(['data' => $this->consultantArray($consultant)]);
    }

   
    public function store(StoreConsultantRequest $request)
    {
        $company = $this->company($request);
        $data = $request->validated();

        $consultant = DB::transaction(function () use ($company, $data) {
            $user = User::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'password' => Hash::make($data['password']),
            ]);

            $profile = ConsultantProfile::create([
                'user_id' => $user->id,
                'company_id' => $company->id,
                'company_name' => $company->name,
                'slug' => $this->uniqueSlug($data['name']),
                'phone' => $data['phone'] ?? null,
                'whatsapp_phone' => $data['whatsapp_phone'] ?? null,
                'license_number' => $data['license_number'] ?? null,
                'city' => $data['city'] ?? null,
                'district' => $data['district'] ?? null,
                'bio' => $data['bio'] ?? null,
                // Firma hesabı admin onayına düşer: onaylanana dek giriş yapamaz,
                // izinleri admin onayı (ConsultantProfilesController@approve) verir.
                'application_status' => ConsultantProfile::STATUS_PENDING,
                'applied_at' => now(),
                'is_active' => false,
                'is_verified' => false,
            ]);

            return $profile;
        });

        return response()->json([
            'data' => $this->consultantArray($consultant->load('user:id,name,email')),
        ], 201);
    }

    public function update(UpdateConsultantRequest $request, ConsultantProfile $consultant)
    {
        $this->authorizeConsultant($request, $consultant);
        $data = $request->validated();

        DB::transaction(function () use ($consultant, $data) {
            $userPayload = Arr::only($data, ['name', 'email']);

            if (! empty($data['password'])) {
                $userPayload['password'] = Hash::make($data['password']);
            }

            if ($userPayload !== []) {
                $consultant->user->update($userPayload);
            }

            $consultant->update(Arr::only($data, [
                'phone', 'whatsapp_phone', 'license_number', 'city', 'district', 'bio',
            ]));
        });

        return response()->json([
            'data' => $this->consultantArray($consultant->fresh()->load('user:id,name,email')),
        ]);
    }

    /**
     * Danışmanı aktif/pasif yapar. Pasifken ilan izinleri geri alınır
     * (girişi sürer ama ilan yönetemez); aktifleşince izinler geri verilir.
     */
    public function setActive(Request $request, ConsultantProfile $consultant)
    {
        $this->authorizeConsultant($request, $consultant);

        $data = $request->validate([
            'is_active' => ['required', 'boolean'],
        ]);

        $consultant->update(['is_active' => $data['is_active']]);

        if ($data['is_active']) {
            // İzinler yalnızca admin onaylı danışmana verilir; onay bekleyen
            // aktifleştirilse bile izin (ve giriş) admin onayına kadar kapalı kalır.
            if ($consultant->application_status === ConsultantProfile::STATUS_APPROVED) {
                $this->grantAgentPermissions($consultant->user);
            }
        } else {
            $permissionIds = Permission::whereIn('key', ConsultantProfile::AGENT_PERMISSION_KEYS)
                ->pluck('id')
                ->all();

            $consultant->user->permissions()->detach($permissionIds);

            // Pasife alınan danışmanın açık oturumları da anında kapansın.
            $consultant->user->tokens()->delete();
        }

        return response()->json([
            'data' => $this->consultantArray($consultant->fresh()->load('user:id,name,email')),
        ]);
    }

    /** İ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 authorizeConsultant(Request $request, ConsultantProfile $consultant): void
    {
        $company = $this->company($request);

        abort_unless($consultant->company_id === $company->id, 403, 'Bu danışman firmanıza kayıtlı değil.');
    }

    private function grantAgentPermissions(User $user): void
    {
        $permissionIds = Permission::whereIn('key', ConsultantProfile::AGENT_PERMISSION_KEYS)
            ->pluck('id')
            ->all();

        $user->permissions()->syncWithoutDetaching($permissionIds);
    }

    private function consultantArray(ConsultantProfile $consultant): array
    {
        return [
            'id' => $consultant->id,
            'slug' => $consultant->slug,
            'company_name' => $consultant->company_name,
            'phone' => $consultant->phone,
            'whatsapp_phone' => $consultant->whatsapp_phone,
            'license_number' => $consultant->license_number,
            'city' => $consultant->city,
            'district' => $consultant->district,
            'bio' => $consultant->bio,
            'profile_image' => $consultant->profile_image,
            'is_verified' => $consultant->is_verified,
            'is_active' => $consultant->is_active,
            'application_status' => $consultant->application_status,
            'listings_count' => $consultant->listings_count ?? null,
            'published_listings_count' => $consultant->published_listings_count ?? null,
            'pending_listings_count' => $consultant->pending_listings_count ?? null,
            'created_at' => $consultant->created_at?->toISOString(),
            'user' => $consultant->user ? [
                'id' => $consultant->user->id,
                'name' => $consultant->user->name,
                'email' => $consultant->user->email,
            ] : null,
        ];
    }

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

        while (ConsultantProfile::where('slug', $slug)->exists()) {
            $slug = "{$base}-{$suffix}";
            $suffix++;
        }

        return $slug;
    }
}
