<?php

namespace App\Services;

use App\Http\Resources\SalesmanResource;
use App\Models\Salesman;
use App\Models\User;
use App\Observers\SalesmanObserver;
use App\Traits\HasResponse;
use Illuminate\Support\Facades\DB;

/**
 * Class SalesmanService
 * @package App\Services
 */
class SalesmanService
{
    use HasResponse;

    /** @var UserService */
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function list($withPagination)
    {
        $salesman = Salesman::salesmanFilters()->orderBy('id', 'desc');

        $salesman = !empty($withPagination)
            ? $salesman->paginate($withPagination['perPage'], page: $withPagination['page'])
            : $salesman->get();

        $salesman = SalesmanResource::collection($salesman->load('channel', 'company', 'branchOffice'));

        return $this->successResponse('Lectura exitosa.', $salesman);
    }

    public function register($params)
    {
        DB::beginTransaction();
        try {
            #Validar rut
            $rut = Salesman::where('rut', $params['rut'])->active()->company()->first();
            if ($rut) return $this->errorResponse('El rut ingresado ya se encuentra registrado', 400);

            #Validar duplicidad de username
            if (isset($params['username'])) {
                $username = User::where('username', $params['username'])->active()->company()->first();
                if ($username) return $this->errorResponse('El username ingresado ya se encuentra registrado', 400);
            }

            $salesman = Salesman::create([
                'rut' => $params['rut'],
                'name' => $params['name'],
                'surname' => $params['surname'],
                'gender' => $params['gender'],
                'type_person' => $params['type_person'],
                'age' => $params['age'],
                'birthdate' => $params ['birthdate'],
                'email' => $params['email'],
                'address' => $params['address'] ?? null,
                'phone' => $params['phone'] ?? null,
                'idchannel' => $params['idchannel'],
                'idcompany' => $params['idcompany']
            ]);

            $this->userService->registerUser($params['rut'], $params['email'], 3, $params['idcompany'], $params['username'] ?? null);

            DB::commit();
            return $this->successResponse('Vendedor creado satisfactoriamente.', $salesman);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->externalError('durante la creación de un vendedor.', $th->getMessage());
        }
    }

    public function update($id, $params)
    {
        DB::beginTransaction();
        try {
            #Validar vendedor
            $salesman = Salesman::activeForID($id)->first();
            if (!$salesman) return $this->errorResponse('El vendedor seleccionado no esta disponible', 400);

            #Validar duplicidad de rut
            $rut = Salesman::where('id', '!=', $id)->where('rut', $params['rut'])->active()->company()->first();
            if ($rut) return $this->errorResponse('El rut ingresado ya se encuentra registrado', 400);

            $salesman->update($params);

            DB::commit();
            return $this->successResponse('Vendedor actualizado satisfactoriamente.', $salesman);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->externalError('durante la actualización de un vendedor.', $th->getMessage());
        }
    }

    public function delete($id)
    {
        DB::beginTransaction();
        try {
            #Validar vendedor
            $salesman = Salesman::activeForID($id)->first();
            if (!$salesman) return $this->errorResponse('El vendedor seleccionado no esta disponible', 400);

            $salesman = Salesman::find($id);
            $salesman->update(['status' => 2]);

            DB::commit();
            return $this->successResponse('Vendedor eliminado satisfactoriamente.', $salesman);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->externalError('durante la eliminación de un vendedor.', $th->getMessage());
        }
    }
}
