<?php
/*=========================================================================================
    App Name  : PPID PTUN Semarang
    File Name : MenuController
    --------------------------------------------------------------------------------------
    Author    : Fuad Auliya Rohman
    Email     : fuad.dev16@gmail.com
==========================================================================================*/

namespace Modules\Menu\Http\Controllers;

use App\Models\Menu;
use App\Models\Report;
use App\Models\Article;
use App\Models\MenuType;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Models\ReportCategory;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Facades\DataTables;
use Illuminate\Support\Facades\Validator;
use Illuminate\Contracts\Support\Renderable;
use Modules\Menu\Services\MenuServiceInterface;

class MenuController extends Controller
{
    protected $view = 'menu::';
    protected $table = 'MenuTable';
    protected $targetModal = 'app-modal';
    protected $menuService;

    public function __construct(MenuServiceInterface $menuService)
    {
        $this->menuService = $menuService;
    }

    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index()
    {
        $Menu = Menu::where('parent_id','0')->orderBy('sequence', 'asc')->get();
        $SubMenu = Menu::where('parent_id','!=','0')->orderBy('sequence', 'asc')->get();
        $bc = breadcrumb(array(['link' => '#', 'page' => __('lang.menu')]));

        return view($this->view . 'index', [
            'Menu'    => $Menu,
            'SubMenu' => $SubMenu,
            'bc'      => $bc,
            'table'   => $this->table,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        $MenuType = MenuType::where('status', 'Y')->get();

        return response()->json([
            'html' => view($this->view . 'menu', [
                'table'       => $this->table,
                'targetModal' => $this->targetModal,
                'updateMode'  => false,
                'MenuType'    => $MenuType,
                'Menu'        => false,
                'method'      => route('menu.store'),
            ])->render(),
        ]);
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(Request $request)
    {
        try {
            Validator::make($request->all(), [
                'label'  => 'required',
                'tipe'   => 'required',
                'target' => 'required',
                'tautan' => 'required',
            ]);

            $this->menuService->create([
                'menu_type_id' => $request->tipe,
                'label' => $request->label,
                'url' => $request->tautan,
                'target' => $request->target,
            ]);

            return redirect()->route('menu.index')->with("success", __('messages.save_success', ['action' => __('lang.menu'),]));
        } catch (\Exception $e) {
            // WRITE LOG
            writeAppLog($e->getMessage(), 'error');

            return redirect()->back()->with("failed", __('messages.save_failed', ['action' => __('lang.menu'),]));
        }
    }

    /**
     * Show the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function show(string $hash_id)
    {
        return view('menu::show');
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit(string $hash_id)
    {
        $MenuType = MenuType::where('status', 'Y')->get();
        $Menu = $this->menuService->findById(decryptString($hash_id));

        return response()->json([
            'html' => view($this->view . 'menu', [
                'table'       => $this->table,
                'targetModal' => $this->targetModal,
                'updateMode'  => true,
                'MenuType'    => $MenuType,
                'Menu'        => $Menu,
                'method'      => route('menu.update', ['id' => encryptString($Menu->id)]),
            ])->render(),
        ]);
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(Request $request, string $hash_id)
    {
        try {
            Validator::make($request->all(), [
                'label'  => 'required',
                'tipe'   => 'required',
                'target' => 'required',
                'tautan' => 'required',
            ]);

            $Menu = $this->menuService->findById(decryptString($hash_id));
            $Menu->update([
                'menu_type_id' => $request->tipe,
                'label' => $request->label,
                'url' => $request->tautan,
                'target' => $request->target,
            ]);

            if ($Menu == TRUE) {
                return redirect()->route('menu.index')->with("success", __('messages.update_success', ['action' => __('lang.menu'),]));
            }
        } catch (\Exception $e) {
            // WRITE LOG
            writeAppLog($e->getMessage(), 'error');

            return redirect()->back()->with("failed", __('messages.update_failed', ['action' => __('lang.menu'),]));
        }
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy(string $hash_id)
    {
        try {
            $id = decryptString($hash_id);

            $Artikel = $this->menuService->findById($id);

            if ($Artikel->delete() !== FALSE) {
                return response()->json([
                    'status' => true,
                    'message' => __('messages.delete_success', ['name' => __('lang.menu'),]),
                ]);
            }
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => __('messages.delete_failed', ['action' => __('lang.menu'),]),
            ]);
        }
    }

    public function storeUpdate(Request $request)
    {
        try {
            $dataRepons = json_decode($request->data);
            $order = 1;
            foreach ($dataRepons as $key => $menu) {
                $Menu = $this->menuService->findById($menu->id);
                if (isset($menu->parent_id)) {
                    $parent = $menu->parent_id;
                }else {
                    $parent = '0';
                }

                $data = [
                    'parent_id' => $parent,
                    'sequence' => $order,
                    'status' => 'Y',
                ];

                $Menu->update($data);

                $order++;
            }

            return response()->json([
                'status' => true,
                'message' => __('messages.update_success', ['action' => __('lang.menu'),]),
            ]);
        } catch (\Exception $e) {
            // WRITE LOG
            writeAppLog($e->getMessage(), 'error');

            return redirect()->back()->with("failed", __('messages.update_failed', ['action' => __('lang.menu'),]));
        }
    }

    public function getShow(Request $request)
    {
        if ($request->ajax()) {
            $getMenuType = MenuType::findOrFail($request->value);

            if ($getMenuType) {
                $post = $getMenuType->name;

                if ($post == 'articles' || $post == 'reports' || $post == 'pages') {
                    $selects = explode(',', $getMenuType->options);
                    $option = "<option value='0'>" . __('lang.select_data', ['data' => __('lang.tampilan')]) . "</option>";
                    foreach ($selects as $row) {
                        $option .= '<option value="' . $row . '">' . __('lang.by_' . $row) . '</option>';
                    }

                    $data = [
                        'option' => true,
                        'value' => $option,
                    ];
                } else if ($post == 'other') {
                    $data = [
                        'url' => false,
                        'option' => false,
                    ];
                } else {
                    $data = [
                        'url' => true,
                        'value' => $getMenuType->url,
                    ];
                }

                return response()->json($data);
            }
            return false;
        }
    }

    public function getBy(Request $request)
    {
        if ($request->ajax()) {
            $value = $request->value;
            $getMenuType = MenuType::findOrFail($request->type);
            if ($getMenuType) {
                $dataMenu = $this->generateUrlMenu($getMenuType->name);
                if ($value == "cat" || $value == "pos") {
                    $data = DB::table($dataMenu['table'])->where('status','Y')->first();

                    if ($data) {
                        $option = "<option value='0'>" . __('lang.select') . "</option>";
                        foreach ($data as $row) {
                            $option .= '<option value="' . $row->id . '">' . $row->name . '</option>';
                        }
                        $data = [
                            'option' => true,
                            'value' => $option,
                        ];
                    }
                } else if ($value == 'all') {
                    $data = [
                        'url' => true,
                        'value' => $getMenuType->url,
                    ];
                } else {
                    $data = [
                        'link' => $dataMenu['link'],
                        'lang' => $dataMenu['lang'],
                    ];
                }

                return response()->json($data);
            }
        }
    }

    public function getShowPageLink(string $type)
    {
        return response()->json([
            'html' => view($this->view . 'menu-link', [
                'table'       => $this->table,
                'targetModal' => $this->targetModal,
                'updateMode'  => true,
                'dataTableUrl'   => route('menu.datatableMenuLink', ['type' => $type]),
            ])->render(),
        ]);
    }

    private function generateUrlMenu($menu)
    {
        if ($menu) {
            switch ($menu) {
                case "articles":
                    $data = [
                        'table' => 'articles',
                        'language' => 'article',
                        'link' => route('menu.getShowPageLink',['type' => '1']),
                        'url' => 'category',
                        'lang' => __('lang.list_data', ['data' => __('lang.artikel')]),
                    ];
                    break;
                case "reports":
                    $data = [
                        'table' => 'reports',
                        'language' => 'report',
                        'link' => route('menu.getShowPageLink', ['type' => '2']),
                        'url' => 'report',
                        'lang' => __('lang.list_data', ['data' => __('lang.laporan')]),
                    ];
                    break;
                case "pages":
                    $data = [
                        'table' => 'articles',
                        'language' => 'static_pages',
                        'link' => route('menu.getShowPageLink', ['type' => '3']),
                        'url' => 'page',
                        'lang' => __('lang.list_data', ['data' => __('lang.halaman_static')]),
                    ];
                    break;
                default:
                    $data = [];
            }

            return $data;
        }

        return false;
    }

    public function datatableMenuLink(Request $request, string $type)
    {
        if ($request->ajax()) {
            if ($type == '1') {
                $data = Article::select('id', 'tittle', 'status', 'slug', 'publish_date', DB::raw("'$type' as type"))->where('status', 'publish')->whereNotNull('categori_id')->orderBy('id', 'desc')->get();
            } elseif ($type == '2') {
                $data = Report::select('id', 'tittle', 'status', 'slug', 'publish_date', DB::raw("'$type' as type"))->where('status', 'publish')->orderBy('id', 'desc')->get();
            } elseif ($type == '3') {
                $data = Article::select('id', 'tittle', 'status', 'slug', 'publish_date', DB::raw("'$type' as type"))->where('status', 'publish')->whereNull('categori_id')->orderBy('id', 'desc')->get();
            }

            return DataTables::of($data)
                ->addIndexColumn()
                ->editColumn('id', fn($row) => encryptString($row->id))
                ->editColumn('title', fn($row) => Str::limit($row->tittle, 30))
                ->addColumn('publish_date', function ($row) {
                    return $row->publish_date ? fullSimpleDate($row->publish_date) : '-';
                })
                ->editColumn('slug', function ($row) {;
                    if ($row->type == '1') {
                        $MenuType = MenuType::FindOrFail('2');
                    }elseif($row->type == '2'){
                        $MenuType = MenuType::FindOrFail('4');
                    }elseif($row->type == '3'){
                        $MenuType = MenuType::FindOrFail('3');
                    }

                    return $MenuType->url.'/'. $row->slug;
                })
                ->rawColumns(['status', 'publish_date', 'slug'])
                ->make('true');;
        }
    }
}
