<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\UnidadeOrganizacionalStoreRequest;
use App\Http\Requests\UnidadeOrganizacionalTransferirRequest;
use App\Http\Requests\UnidadeOrganizacionalUpdateRequest;
use App\Models\UnidadeOrganizacional;
use App\Models\Endereco;
use App\Models\Logradouro\Estado;
use App\Services\IncluiUnidadeOrganizacionalService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UnidadeOrganizacionalController extends Controller
{
    private $unidade;

    public function __construct()
    {
        $this->middleware(['role:admin']);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $busca = $request->busca;
        $unidades = UnidadeOrganizacional::search($busca)->paginate();

        return view('admin.unidades-organizacionais.index', ['unidades' => $unidades, 'busca' => $busca]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(UnidadeOrganizacional $superior = null)
    {
        $estados = Estado::orderBy('ufe_sg')->select('ufe_sg')->get();

        return view('admin.unidades-organizacionais.create', [
            'superior_id' => $superior ? $superior->id : null,
            'estados' => $estados,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(UnidadeOrganizacionalStoreRequest $request)
    {
        if ($request->cep) {
            $endereco = new Endereco($request->only('cep', 'logradouro', 'numero', 'cidade', 'bairro', 'estado'));
            $endereco->observacoes = $request->observacoes_endereco;
        }

        $unidadeSuperior = UnidadeOrganizacional::find($request->superior_id);
        $service = new IncluiUnidadeOrganizacionalService(
            $request->nome,
            $request->sigla,
            $request->centro_custo,
            $request->telefone,
            $unidadeSuperior,
            $endereco ?? null
        );
        $unidade = $service->inclui();

        $rotaVoltar = route('admin.unidades-organizacionais.index');

        if (!$unidade->isSuperior()) {
            $rotaVoltar = route('admin.unidades-organizacionais.edit', ['unidade' => $unidade->superior]);
        }

        return redirect()
            ->route('admin.unidades-organizacionais.edit', ['unidade' => $unidade])
            ->with('status', 'Unidade organizacional incluída com sucesso!')
            ->with('sucesso', true)
            ->with('rotaVoltar', $rotaVoltar);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\UnidadeOrganizacional  $unidadeOrganizacional
     * @return \Illuminate\Http\Response
     */
    public function edit(UnidadeOrganizacional $unidade)
    {
        $estados = Estado::orderBy('ufe_sg')->select('ufe_sg')->get();

        return view('admin.unidades-organizacionais.edit', [
            'unidade' => $unidade,
            'estados' => $estados,
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\UnidadeOrganizacional  $unidadeOrganizacional
     * @return \Illuminate\Http\Response
     */
    public function update(UnidadeOrganizacionalUpdateRequest $request, UnidadeOrganizacional $unidade)
    {
        $this->unidade = $unidade;
        $this->unidade->fill($request->except('hierarquia'));
        $endereco = $this->unidade->enderecos()->first();

        DB::beginTransaction();
        $this->saveEndereco($endereco, $request);
        $this->unidade->save();
        $this->unidade->saveTelefones($request->input('telefone', []));
        DB::commit();

        $rotaVoltar = route('admin.unidades-organizacionais.index');

        if (!$this->unidade->isSuperior()) {
            $rotaVoltar = route('admin.unidades-organizacionais.edit', ['unidade' => $unidade->superior]);
        }

        return redirect()->back()
            ->with('status', 'Unidade organizacional editada com sucesso!')
            ->with('sucesso', true)
            ->with('rotaVoltar', $rotaVoltar);
    }

    public function transferirForm(UnidadeOrganizacional $unidade)
    {
        $unidades = UnidadeOrganizacional::where('id', '!=', $unidade->id)->get();

        return view('admin.unidades-organizacionais.transferir', [
            'unidades' => $unidades,
            'unidade' => $unidade,
        ]);
    }

    public function transferir(UnidadeOrganizacionalTransferirRequest $request, UnidadeOrganizacional $unidadeTransferir, UnidadeOrganizacional $unidadeDestino = null)
    {
        $unidadeTransferir->transferePara($unidadeDestino);
        $rotaVoltar = route('admin.unidades-organizacionais.index');

        if (!$unidadeTransferir->isSuperior()) {
            $rotaVoltar = route('admin.unidades-organizacionais.edit', ['unidade' => $unidadeTransferir->superior]);
        }

        return redirect()->back()
            ->with('status', 'Unidade organizacional transferida com sucesso!')
            ->with('sucesso', true)
            ->with('rotaVoltar', $rotaVoltar);
    }


    private function saveEndereco($endereco, $request)
    {
        if ($request->cep && $endereco == null) {
            $endereco = new Endereco($request->only('cep', 'logradouro', 'numero', 'cidade', 'bairro', 'estado', 'complemento'));
            $endereco->observacoes = $request->observacoes_endereco;
            $this->unidade->enderecos()->save($endereco);
        } elseif ($request->cep && $endereco) {
            $endereco->fill($request->only('cep', 'logradouro', 'numero', 'cidade', 'bairro', 'estado', 'complemento'));
            $endereco->observacoes = $request->observacoes_endereco;
            $endereco->save();
        } elseif (!$request->cep && $endereco) {
            $endereco->delete();
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\UnidadeOrganizacional  $unidadeOrganizacional
     * @return \Illuminate\Http\Response
     */
    public function destroy(UnidadeOrganizacional $unidade)
    {
        if ($unidade->temSubordinada() || $unidade->temServidores()) {
            return redirect()->back()
                ->withErrors('Unidade organizacional não pode ser excluída pois tem unidades subordinadas a ela ou servidores alocados');
        }

        $unidade->delete();

        return redirect()->back()
            ->with('status', 'Unidade organizacional excluída com sucesso!');
    }
}
