<?php

namespace App\Services;

use App\Models\Company;
use App\Models\Company_user;
use App\Models\User;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;

class CompanyServices
{
    public function getCompaniesData(
        int $page,
        int $length,
        ?string $searchValue = null
    ): LengthAwarePaginator {
        $query = Company::query()
            ->select([
                'id',
                'name',
                'email',
                'phone',
                'address',
                'created_at'
            ])
            ->withCount('companyUsers')
            ->orderByDesc('id');

        if (!empty($searchValue)) {
            $query->where(function ($subQuery) use ($searchValue): void {
                $subQuery->where('name', 'like', "%{$searchValue}%")
                    ->orWhere('email', 'like', "%{$searchValue}%")
                    ->orWhere('phone', 'like', "%{$searchValue}%")
                    ->orWhere('address', 'like', "%{$searchValue}%");
            });
        }

        $paginator = $query->paginate($length, ['*'], 'page', $page);

        $paginator->getCollection()->transform(function (Company $company) {
            return [
                'id' => $company->id,
                'name' => $company->name,
                'email' => $company->email,
                'phone' => $company->phone,
                'address' => $company->address,
                'users_count' => $company->company_users_count,
                'created_at_formatted' => $company->created_at?->format('d/m/Y H:i'),
            ];
        });

        return $paginator;
    }

    public function createCompany(Request $request): Company
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:50',
            'address' => 'nullable|string|max:255',
        ]);

        return Company::create($validated);
    }

    public function updateCompany(Request $request, Company $company): Company
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:50',
            'address' => 'nullable|string|max:255',
        ]);

        $company->update($validated);

        return $company->refresh();
    }

    public function deleteCompany(Company $company): void
    {
        DB::transaction(function () use ($company): void {
            $company->companyUsers()->delete();
            $company->delete();
        });
    }

    public function getCompanyUsers(Company $company): array
    {
        return $company->companyUsers()
            ->with('user.people')
            ->get()
            ->map(function (Company_user $companyUser) {
                return [
                    'id' => $companyUser->user->id,
                    'name' => $companyUser->user->name,
                    'email' => $companyUser->user->email,
                    'phone' => $companyUser->user->people?->phone,
                    'status' => $companyUser->status,
                    'assigned_at' => $companyUser->created_at?->format('d/m/Y'),
                ];
            })
            ->toArray();
    }

    public function getUnassignedUsers(): \Illuminate\Support\Collection
    {
        $assignedUserIds = Company_user::pluck('user_id')->toArray();

        return User::query()
            ->select(['id', 'name', 'email'])
            ->with('people')
            ->whereNotIn('id', $assignedUserIds)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();
    }

    public function assignUserToCompany(int $companyId, int $userId): Company_user
    {
        $existing = Company_user::where('company_id', $companyId)
            ->where('user_id', $userId)
            ->first();

        if ($existing) {
            $existing->update(['status' => true]);
            return $existing->refresh();
        }

        return Company_user::create([
            'company_id' => $companyId,
            'user_id' => $userId,
            'status' => true,
        ]);
    }

    public function removeUserFromCompany(int $companyId, int $userId): void
    {
        Company_user::where('company_id', $companyId)
            ->where('user_id', $userId)
            ->delete();
    }
}
