<?php

namespace App\Http\Controllers\Admin\Servidor;

use App\Enums\ProventoAposentadoEnum;
use App\Enums\RegimeServidorEnum;
use App\Enums\TipoAposentadoriaEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegistroServidorStoreRequest;
use App\Http\Requests\RegistroServidorUpdateRequest;
use App\Models\Cargo;
use App\Models\Endereco;
use App\Models\Logradouro\Estado;
use App\Models\NivelSalarial;
use App\Models\RegistroServidor;
use App\Models\Servidor;
use App\Models\UnidadeOrganizacional;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class RegistroServidorController extends Controller
{
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Servidor $servidor)
    {
        $cargos = Cargo::all();
        $unidades = UnidadeOrganizacional::all();
        $estados = Estado::orderBy('ufe_sg')->select('ufe_sg')->get();
        $regimes = RegimeServidorEnum::getAll();
        $proventos = ProventoAposentadoEnum::getAll();
        $tiposAposentadoria = TipoAposentadoriaEnum::getAll();
        $niveisSalariais = NivelSalarial::all();

        return view('admin.servidores.registros.create', [
            'cargos' => $cargos,
            'unidades' => $unidades,
            'servidor' => $servidor,
            'estados' => $estados,
            'regimes' => $regimes,
            'proventos' => $proventos,
            'tiposAposentadoria' => $tiposAposentadoria,
            'niveisSalariais' => $niveisSalariais,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(RegistroServidorStoreRequest $request, Servidor $servidor)
    {
        $registro = new RegistroServidor($request->only('data_admissao', 'cargo_id', 'readaptado', 'cargoreadaptado_id', 'data_desligamento', 'unidadeorganizacional_id', 'nivel_salarial_id'));
        $registro->numero = $request->numero_registro;
        $registro->regime = RegimeServidorEnum::make((int) $request->regime);

        if ($registro->regime->isAposentado()) {
            $registro->fill($request->only('data_aposentadoria', 'portaria_aposentadoria', 'paridade'));
            $registro->tipo_aposentadoria = $request->tipo_aposentadoria ? TipoAposentadoriaEnum::make((int) $request->tipo_aposentadoria) : null;
            $registro->proventos = $request->proventos ? ProventoAposentadoEnum::make((int) $request->proventos) : null;
        }

        DB::beginTransaction();

        $servidor->registros()->save($registro);

        if ($request->unidadeorganizacional_id) {
            $unidade = UnidadeOrganizacional::find($request->unidadeorganizacional_id);
            $registro->unidadeOrganizacional()->associate($unidade);

            if ($request->cep_lotacao) {
                $endereco = $this->makeEndereco($request);
                $registro->enderecos()->save($endereco);
            }
        }

        DB::commit();

        return redirect()
            ->route('admin.servidores.edit', ['servidor' => $servidor])
            ->with('status', 'Registro incluído com sucesso!');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\RegistroServidor  $registroServidor
     * @return \Illuminate\Http\Response
     */
    public function edit(Servidor $servidor, RegistroServidor $registro)
    {
        $cargos = Cargo::all();
        $unidades = UnidadeOrganizacional::all();
        $estados = Estado::orderBy('ufe_sg')->select('ufe_sg')->get();
        $regimes = RegimeServidorEnum::getAll();
        $endereco = $registro->enderecos->first();
        $proventos = ProventoAposentadoEnum::getAll();
        $tiposAposentadoria = TipoAposentadoriaEnum::getAll();
        $niveisSalariais = NivelSalarial::all();

        return view('admin.servidores.registros.edit', [
            'cargos' => $cargos,
            'unidades' => $unidades,
            'servidor' => $servidor,
            'registro' => $registro,
            'endereco' => $endereco,
            'regimes' => $regimes,
            'estados' => $estados,
            'proventos' => $proventos,
            'tiposAposentadoria' => $tiposAposentadoria,
            'niveisSalariais' => $niveisSalariais,
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\RegistroServidor  $registroServidor
     * @return \Illuminate\Http\Response
     */
    public function update(RegistroServidorUpdateRequest $request, Servidor $servidor, RegistroServidor $registro)
    {
        $registro->fill($request->only('data_admissao', 'cargo_id', 'readaptado', 'cargoreadaptado_id', 'data_desligamento', 'unidadeorganizacional_id', 'nivel_salarial_id'));
        $endereco = $registro->enderecos()->first();
        $registro->regime = RegimeServidorEnum::make((int) $request->regime);
        $registro->numero = $request->numero_registro;

        if ($registro->regime->isAposentado()) {
            $registro->fill($request->only('data_aposentadoria', 'portaria_aposentadoria', 'paridade'));
            $registro->tipo_aposentadoria = $request->tipo_aposentadoria ? TipoAposentadoriaEnum::make((int) $request->tipo_aposentadoria) : null;
            $registro->proventos = $request->proventos ? ProventoAposentadoEnum::make((int) $request->proventos) : null;
        } else {
            $registro->data_aposentadoria = null;
            $registro->portaria_aposentadoria = null;
            $registro->paridade = null;
            $registro->tipo_aposentadoria = null;
            $registro->proventos = null;
        }

        DB::beginTransaction();

        $this->saveEndereco($request, $registro, $endereco);

        $registro->save();

        DB::commit();

        return redirect()
            ->route('admin.servidores.edit', ['servidor' => $servidor])
            ->with('status', 'Registro editado com sucesso!');
    }

    private function saveEndereco(Request $request, RegistroServidor $registro, ?Endereco $endereco)
    {
        if ($request->cep && !$endereco) {
            $endereco = $this->makeEndereco($request);
            $registro->enderecos()->save($endereco);
        } elseif ($request->cep && $endereco) {
            $endereco = $this->makeEndereco($request, $endereco);
            $endereco->save();
        } elseif (!$request->cep && $endereco) {
            $endereco->delete();
        }
    }

    private function makeEndereco(Request $request, ?Endereco $endereco = null)
    {
        if (!$endereco) {
            $endereco = new Endereco();
        }

        $endereco->cep = $request->cep;
        $endereco->logradouro = $request->logradouro;
        $endereco->bairro = $request->bairro;
        $endereco->numero = $request->numero;
        $endereco->cidade = $request->cidade;
        $endereco->estado = $request->estado;
        $endereco->complemento = $request->complemento;
        $endereco->observacoes = $request->observacoes_endereco;

        return $endereco;
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\RegistroServidor  $registroServidor
     * @return \Illuminate\Http\Response
     */
    public function destroy(Servidor $servidor, RegistroServidor $registro)
    {
        if ($servidor->registros->count() == 1) {
            return redirect()->back()
                ->withErrors('Servidor deve ter pelo menos um registro');
        }

        $registro->delete();

        return redirect()
            ->route('admin.servidores.edit', ['servidor' => $servidor])
            ->with('status', 'Registro excluído com sucesso!');
    }
}
