<?php

namespace App\Http\Controllers;

use App\Http\Requests\HtmlRequest;
use App\Http\Services\HtmlService;
use App\Models\Html;
use App\Models\ReusableMenu;
use App\Models\Structure;
use App\Models\Phone;
use App\Models\Link;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
class HtmlController extends Controller
{
    private const PERMISSAO = 'GERENCIADOR_DE_PAGINAS_HTML';

    private HtmlService $htmlService;

    public function __construct(HtmlService $htmlService)
    {
        $this->middleware('htmls');
        $this->htmlService = $htmlService;
    }

    public function index(Request $request): View|RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'visualizar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $filters = [
            'q' => $request->input('q'),
            'perPage' => 20,
        ];

        $htmls = $this->htmlService
            ->paginate($filters)
            ->appends($request->only(['q']));

        return view("admin.htmls.index", [
            "htmls" => $htmls,
            "filterParams" => $request->only(['q']),
        ]);
    }

    public function create(Request $request): View|RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'adicionar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $returnUrl = $request->input('return_url');
        if (!$returnUrl) {
            $returnUrl = url()->previous();
        }

        return view("admin.htmls.create", [
            "secretarias" => Structure::where("status", "ATIVADO")->orderBy('name', 'asc')->get(),
            "reusableMenus" => ReusableMenu::where('status', 'ATIVADO')->orderBy('title', 'asc')->get(),
            "filterParams" => $request->only(['q', 'page']),
            "returnUrl" => $returnUrl,
        ]);
    }

    public function store(HtmlRequest $request): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'adicionar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $data = $request->validated();

        try {
            $this->htmlService->create($data + [
                'code' => $request->input('code'),
                'css' => $request->input('css'),
                'js' => $request->input('js'),
                'order' => $request->input('order'),
            ]);
        } catch (\Throwable $e) {
            Log::error('Erro ao criar Página HTML (controller)', ['exception' => $e]);
            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar criar esta página HTML. Tente novamente mais tarde.'));
        }

        $returnUrl = $request->input('return_url');
        if ($returnUrl) {
            return redirect($returnUrl)->with('success', __('HTML criado com sucesso!'));
        }

        return redirect()
            ->route('admin.htmls.index', $request->only(['q', 'page']))
            ->with('success', __('HTML criado com sucesso!'));
    }

    public function show(Html $html)
    {
        //
    }

    public function edit(Request $request, Html $html): View|RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'editar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $returnUrl = $request->input('return_url');
        if (!$returnUrl) {
            $returnUrl = url()->previous();
        }

        return view('admin.htmls.edit', [
            'html' => $html,
            "secretarias" => Structure::where("status", "ATIVADO")->orderBy('name', 'asc')->get(),
            "reusableMenus" => ReusableMenu::where('status', 'ATIVADO')->orderBy('title', 'asc')->get(),
            "filterParams" => $request->only(['q', 'page']),
            "returnUrl" => $returnUrl,
        ]);
    }

    public function update(HtmlRequest $request, Html $html): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'editar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $data = $request->validated();

        try {
            $this->htmlService->update($html, $data + [
                'code' => $request->input('code'),
                'css' => $request->input('css'),
                'js' => $request->input('js'),
                'order' => $request->input('order'),
            ]);
        } catch (\Throwable $e) {
            Log::error('Erro ao atualizar Página HTML (controller)', [
                'html_id' => $html->id,
                'exception' => $e,
            ]);

            $message = $e->getMessage();
            if (is_string($message) && str_starts_with($message, '*')) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', $message);
            }

            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar atualizar esta página HTML. Tente novamente mais tarde.'));
        }

        $returnUrl = $request->input('return_url');
        if ($returnUrl) {
            return redirect($returnUrl)->with("success", __("* Página HTML atualizada com sucesso!"));
        }

        return redirect()
            ->route('admin.htmls.index', $request->only(['q', 'page']))
            ->with("success", __("* Página HTML atualizada com sucesso!"));
    }

    public function destroy(Request $request, Html $html): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'excluir');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        try {
            $this->htmlService->delete($html);
            return redirect()
                ->route('admin.htmls.index', $request->only(['q', 'page']))
                ->with("success", __("* A página HTML foi excluída com sucesso! Esta ação não pode ser desfeita!"));
        } catch (\Throwable $e) {
            Log::error('Erro ao excluir Página HTML (controller)', [
                'html_id' => $html->id,
                'exception' => $e,
            ]);
            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar excluir esta página HTML. Tente novamente mais tarde.'));
        }
    }

    public function toggleVisibility(Request $request, Html $html): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'editar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        try {
            $this->htmlService->updateVisibility($html, (string) $request->input('checkVisibility'));
            return redirect()
                ->route('admin.htmls.index', $request->only(['q', 'page']))
                ->with("success", __("* A visibilidade da Página HTML foi atualizada com sucesso!"));
        } catch (\Throwable $e) {
            Log::error('Erro ao alterar visibilidade Página HTML (controller)', [
                'html_id' => $html->id,
                'exception' => $e,
            ]);

            // Verifica se é a nossa exception de regra de negócio
            $message = $e->getMessage();
            if (str_contains($message, 'Não é possível ativar')) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', $message);
            }

            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar alterar a visibilidade desta página HTML. Tente novamente mais tarde.'));
        }
    }

    public function toggleStatus(Request $request, Html $html): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'editar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        try {
            $this->htmlService->updateStatus($html, (string) $request->input('checkStatus'));
            return redirect()
                ->route('admin.htmls.index', $request->only(['q', 'page']))
                ->with("success", __("* O status da Página HTML foi atualizado com sucesso!"));
        } catch (\Throwable $e) {
            Log::error('Erro ao alterar status Página HTML (controller)', [
                'html_id' => $html->id,
                'exception' => $e,
            ]);
            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar alterar o status desta página HTML. Tente novamente mais tarde.'));
        }
    }

    public function toggleCustomMenu(Request $request, Html $html): RedirectResponse
    {
        $response = $this->checkPermissao(self::PERMISSAO, 'editar');

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        try {
            $this->htmlService->updateCustomMenuEnabled($html, (bool) $request->input('custom_menu_enabled', false));
            return redirect()
                ->route('admin.htmls.index', $request->only(['q', 'page']))
                ->with('success', __("* O Menu Personalizado da Página HTML foi atualizado com sucesso!"));
        } catch (\Throwable $e) {
            Log::error('Erro ao alterar Menu Personalizado Página HTML (controller)', [
                'html_id' => $html->id,
                'exception' => $e,
            ]);

            $message = $e->getMessage();
            if (is_string($message) && str_starts_with($message, '*')) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', $message);
            }

            return redirect()
                ->back()
                ->withInput()
                ->with('error', __('Erro ao tentar alterar o Menu Personalizado. Tente novamente mais tarde.'));
        }
    }

    public function preview(Request $request): View|RedirectResponse
    {
        // Allow previewing for add/edit permissions
        $response = $this->checkPermissao(self::PERMISSAO, 'visualizar');
        // Using 'visualizar' or check if user can create/edit. Usually if they are in form, they can.

        if ($response instanceof RedirectResponse) {
            return $response;
        }

        $data = $request->all();

        // Create a temporary Html object
        $html = new Html();
        $html->fill($data);
        $html->slug = 'preview-pagina'; // Dummy slug

        $viewContent = $data['code'] ?? '';

        $structureId = $data['structure_id'] ?? null;
        $secretaria = null;

        if (!empty($structureId)) {
            $secretaria = Structure::select("*")->where([
                        ["id", "=", $structureId],
                        ["status", "=", "ATIVADO"]
                    ])->orderBy('name', 'asc')->first();
        }

        if (!$secretaria) {
            $secretaria = Structure::select("*")->where([
                        ["type", "=", "GABINETE_PREFEITURA"],
                        ["status", "=", "ATIVADO"]
                    ])->orderBy('name', 'asc')->first();
        }

        if (!$secretaria) {
             return redirect()->back()->with('error', 'Não foi possível encontrar uma secretaria para o contexto de visualização.');
        }

        $custom_menu_links = collect();

        // Regra de prioridade:
        // 1) Se o menu personalizado estiver ativado, o reutilizável não deve aparecer.
        // 2) Se não estiver, tenta renderizar o menu reutilizável (apenas se ATIVADO).
        $customMenuEnabled = (bool) ($data['custom_menu_enabled'] ?? false);
        if ($customMenuEnabled) {
            $custom_menu_links = collect(); // Sem links porque preview usa um HTML temporário.
        } elseif (!empty($data['reusable_menu_id'])) {
            $reusableMenu = ReusableMenu::with('menuLinks')
                ->where('id', $data['reusable_menu_id'])
                ->where('status', 'ATIVADO')
                ->first();
            if ($reusableMenu) {
                $custom_menu_links = $reusableMenu->menuLinks;
            }
        }

        // Context data
        $htmls = Html::where([
                    ["structure_id", "=", $secretaria->id],
                    ["visibility", "=", "ATIVADO"]
                ])
                ->orderBy('created_at', 'asc')
                ->get();

        $telefones = Phone::where("structure_id", $secretaria->id)->orderBy('created_at', 'asc')->get();
        $links = Link::where("structure_id", $secretaria->id)->orderBy('created_at', 'asc')->get();

        $noticias = DB::table('news')
                ->leftJoin('news_rel_structures', 'news_rel_structures.news_id', '=', 'news.id')
                ->select("news.*")
                ->orderBy('news.created_at', 'DESC')
                ->where([["news_rel_structures.structure_id", $secretaria->id]])
                ->paginate(15);

        $phones = [];
        foreach ($telefones as $telefone) {
            $convertArray = explode(",", $telefone->description);
            $tels = array_map('trim', $convertArray);
            $tLink = null;
            foreach ($tels as $tel) {
                $tLink[] = ["numero" => $tel, "link" => "+55" . str_replace("+55", "", str_replace("-", "", str_replace(" ", "", str_replace(")", "", str_replace("(", "", $tel)))))];
            }
            $phones[] = ["telefone" => $telefone->titulo, "numeros" => $tLink];
        }
        $telefones = $phones;

        return view("paginas.html", compact(['html', 'secretaria', 'telefones', 'noticias', 'links', 'htmls', 'viewContent', 'custom_menu_links']));
    }
}
