<?php

namespace App\Http\Controllers\admin;

use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\User;
use App\Models\People;
use App\Services\CompanyServices;
use App\Services\PeopleServices;
use App\Services\UserServices;
use App\Services\ImagesServices;
use App\Traits\GetModelsPaginated;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Role;

class CompanyController extends Controller
{
    protected CompanyServices $companyServices;
    protected PeopleServices $peopleServices;
    protected UserServices $userServices;
    protected ImagesServices $imagesServices;

    use GetModelsPaginated;

    public function __construct(
        CompanyServices $companyServices,
        PeopleServices $peopleServices,
        UserServices $userServices,
        ImagesServices $imagesServices
    ) {
        $this->companyServices = $companyServices;
        $this->peopleServices = $peopleServices;
        $this->userServices = $userServices;
        $this->imagesServices = $imagesServices;
    }

    public function index()
    {
        return view('admin.company.index');
    }

    public function companiesPaginatedJson(Request $request)
    {
        return $this->paginateFromService(
            $request,
            function (int $page, int $length, ?string $searchValue, ?string $status) {
                return $this->companyServices->getCompaniesData($page, $length, $searchValue);
            }
        );
    }

    public function create()
    {
        return view('admin.company.create');
    }

    public function store(Request $request)
    {
        $this->companyServices->createCompany($request);

        return redirect()
            ->route('admin_fit.super_admin.companies.index')
            ->with('success', 'Empresa creada correctamente.');
    }

    public function edit(int $company)
    {
        $companyModel = Company::findOrFail($company);
        $users = $this->companyServices->getCompanyUsers($companyModel);
        $unassignedUsers = $this->companyServices->getUnassignedUsers();

        return view('admin.company.edit', ['company' => $companyModel, 'users' => $users, 'unassignedUsers' => $unassignedUsers]);
    }

    public function update(Request $request, int $company)
    {
        $companyModel = Company::findOrFail($company);
        $this->companyServices->updateCompany($request, $companyModel);

        return redirect()
            ->route('admin_fit.super_admin.companies.edit', $companyModel)
            ->with('success', 'Empresa actualizada correctamente.');
    }

    public function destroy(int $company)
    {
        $companyModel = Company::findOrFail($company);
        $this->companyServices->deleteCompany($companyModel);

        return redirect()
            ->route('admin_fit.super_admin.companies.index')
            ->with('success', 'Empresa eliminada correctamente.');
    }

    public function assignUser(Request $request, int $company)
    {
        $companyModel = Company::findOrFail($company);
        $validated = $request->validate([
            'user_id' => 'required|integer|exists:users,id',
        ]);

        $this->companyServices->assignUserToCompany($companyModel->id, (int) $validated['user_id']);

        return redirect()
            ->route('admin_fit.super_admin.companies.edit', $companyModel)
            ->with('success', 'Usuario asignado correctamente.');
    }

    public function removeUser(int $company, int $user)
    {
        $companyModel = Company::findOrFail($company);
        $this->companyServices->removeUserFromCompany($companyModel->id, $user);

        return redirect()
            ->route('admin_fit.super_admin.companies.edit', $companyModel)
            ->with('success', 'Usuario removido correctamente.');
    }

    public function createUser()
    {
        $roles = Role::where('guard_name', 'web')
            ->where('name', '!=', 'SuperAdmin')
            ->orderBy('name')
            ->get(['id', 'name']);

        return view('admin.company.create_user', compact('roles'));
    }

    public function storeUser(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255', 'unique:users,email'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
            'role_name' => ['required', 'string', 'exists:roles,name'],
            'people.last_name' => ['required', 'string', 'max:100'],
            'people.birth_date' => ['required', 'date'],
            'people.gender' => ['required', 'in:male,female,other'],
            'people.phone' => ['required', 'string', 'max:30'],
            'people.address' => ['required', 'string', 'max:255'],
            'people.document_type' => ['required', 'in:cedula,rif'],
            'people.document_number' => ['required', 'string', 'max:50', 'unique:people,document_number'],
        ]);

        try {
            DB::transaction(function () use ($validated, $request) {
                $peopleData = $validated['people'];
                $person = $this->peopleServices->createPeople($peopleData);
                
                $user = $this->userServices->createUser([
                    'name' => $validated['name'],
                    'email' => $validated['email'],
                    'password' => $validated['password'],
                    'is_active' => true,
                    'people_id' => $person->id,
                ]);

                $user->assignRole($validated['role_name']);
            });

            return redirect()
                ->route('admin_fit.super_admin.companies.index')
                ->with('success', 'Usuario creado correctamente. Ahora puedes asignarlo a una empresa.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Error al crear el usuario: ' . $e->getMessage());
        }
    }
}
