<?php

namespace App\Controllers\Admin;

use App\Models\MenuItemModel;
use App\Models\PageModel;

class Menus extends BaseController
{
    protected $menuModel;

    public function initController($request, $response, $logger)
    {
        parent::initController($request, $response, $logger);
        $this->menuModel = new MenuItemModel();
    }

    public function index()
    {
        helper('menu');

        $pages = (new PageModel())->findAll();
        $pageTitles = [];
        foreach ($pages as $page) {
            $pageTitles[$page['id']] = $page['title'];
        }

        $this->data['title']     = 'Menu Navigasi';
        $this->data['allItems']  = $this->menuModel->getFlatTree();
        $this->data['pageTitles'] = $pageTitles;

        return view('admin/menus/index', $this->data);
    }

    public function new()
    {
        $this->data['title']    = 'Tambah Menu';
        $this->data['item']     = [];
        $this->data['parents']  = $this->menuModel
            ->where('parent_id', null)
            ->orderBy('sort_order', 'ASC')
            ->findAll();

        return view('admin/menus/form', $this->data);
    }

    public function create()
    {
        $data = $this->request->getPost();
        $data['parent_id']   = $data['parent_id'] ?: null;
        $data['target']      = $data['target'] ?? '_self';
        $data['status']      = $data['status'] ?? 0;
        $data['section_key'] = $data['section_key'] ?: null;
        $data['sort_order']  = (int) ($data['sort_order'] ?? 0);
        $data['type']        = 'custom';

        if (!$this->menuModel->insert($data)) {
            return redirect()->back()->withInput()->with('error', 'Gagal menyimpan menu.');
        }

        return redirect()->to('/admin/menus')->with('success', 'Menu berhasil ditambahkan.');
    }

    public function edit($id)
    {
        $this->data['title']   = 'Edit Menu';
        $this->data['item']    = $this->menuModel->find($id);

        if (!$this->data['item']) {
            return redirect()->to('/admin/menus')->with('error', 'Menu tidak ditemukan.');
        }

        $excludeIds   = $this->menuModel->getDescendantIds($id);
        $excludeIds[] = $id;

        $this->data['parents'] = $this->menuModel
            ->where('parent_id', null)
            ->whereNotIn('id', $excludeIds)
            ->orderBy('sort_order', 'ASC')
            ->findAll();

        $this->data['locked'] = $this->data['item']['type'] !== 'custom';

        return view('admin/menus/form', $this->data);
    }

    public function update($id)
    {
        $item = $this->menuModel->find($id);

        if (!$item) {
            return redirect()->to('/admin/menus')->with('error', 'Menu tidak ditemukan.');
        }

        $data = $this->request->getPost();

        if ($item['type'] !== 'custom') {
            $data = [
                'parent_id'  => $data['parent_id'] ?: null,
                'sort_order' => (int) ($data['sort_order'] ?? 0),
            ];
        } else {
            $data['parent_id']   = $data['parent_id'] ?: null;
            $data['target']      = $data['target'] ?? '_self';
            $data['status']      = $data['status'] ?? 0;
            $data['section_key'] = $data['section_key'] ?: null;
            $data['sort_order']  = (int) ($data['sort_order'] ?? 0);
        }

        if (!$this->menuModel->update($id, $data)) {
            return redirect()->back()->withInput()->with('error', 'Gagal memperbarui menu.');
        }

        return redirect()->to('/admin/menus')->with('success', 'Menu berhasil diperbarui.');
    }

    public function delete($id)
    {
        $item = $this->menuModel->find($id);

        if (!$item) {
            return redirect()->to('/admin/menus')->with('error', 'Menu tidak ditemukan.');
        }

        if ($item['type'] !== 'custom') {
            return redirect()->to('/admin/menus')->with('error', 'Menu bawaan tidak dapat dihapus.');
        }

        $children = $this->menuModel->where('parent_id', $id)->countAllResults();
        if ($children > 0) {
            return redirect()->to('/admin/menus')->with('error', 'Hapus menu anak terlebih dahulu.');
        }

        if (!$this->menuModel->delete($id)) {
            return redirect()->to('/admin/menus')->with('error', 'Gagal menghapus menu.');
        }

        return redirect()->to('/admin/menus')->with('success', 'Menu berhasil dihapus.');
    }

    public function reorder()
    {
        $input = json_decode($this->request->getBody(), true);
        $items = $input['items'] ?? [];

        if (empty($items)) {
            return $this->response->setJSON(['success' => false]);
        }

        $db = \Config\Database::connect();
        $db->transBegin();

        foreach ($items as $item) {
            $id        = (int) $item['id'];
            $parentId  = !empty($item['parent_id']) ? (int) $item['parent_id'] : null;
            $sortOrder = (int) $item['sort_order'];

            $db->table('menu_items')
                ->where('id', $id)
                ->update([
                    'parent_id'  => $parentId,
                    'sort_order' => $sortOrder,
                ]);
        }

        if ($db->transStatus() === false) {
            $db->transRollback();
            return $this->response->setJSON(['success' => false]);
        }

        $db->transCommit();

        return $this->response->setJSON(['success' => true, 'csrfHash' => csrf_hash()]);
    }
}
