<?php 
use Eae\Backoffice\Generic\ContentType;

class AdminMenusController extends Controller {
    
    public function __construct(){ 
        $this->beforeFilter('csrf', array('on' => 'post'));    
    }
    
    public function getIndex()
    {                         
        return View::make('admin/pages/menus/list');
    }
    
    public function postList(){
        $page = Input::get("current");
        $sort = Input::get("sort");
        $search = Input::get("searchPhrase");

        Menu::resolveConnection()->getPaginator()->setCurrentPage($page);
        if (!empty($search)) {
            $query = Menu::where(function ($query) use ($search) {
                $query->orWhere('name', 'like', "%{$search}%");
            });
        } else {
            $query = Menu::query();
        }
        if (empty($sort)) {
            $rows = $query->paginate(Input::get("rowCount"));    
        } else {
            foreach ($sort as $field => $direction) {
                if(empty($direction) || !str_is(strtolower($direction),"desc")){
                    $order_direction = "asc";    
                }
                $rows = $query->orderBy($field, strtolower($direction))->paginate(Input::get("rowCount"));
                break;
            }
        }

        $result = array(
            "total"             => $rows->getTotal(),
            "current"           => $rows->getCurrentPage(), 
            "rowCount"          => Input::get("rowCount"),
            "rows"              => $rows->getCollection()  
        );
        
        return Response::json($result);            
    }
    
    public function postInsert()
    {  
        
    }
    
    public function postCreateMenuItem() {
        $type = Input::get('type');     
        $languages = LaravelLocalization::getSupportedLanguagesKeys();
        $defaultLanguage = \Config::get('app.locale');
        if ($type === 'page') {
            $pageId = Input::get('page_id');
            if (!$pageId || !is_numeric($pageId)) {
                return Response::json(false); 
            }

            $page = Entry::find($pageId);
            
            $tempMenuItem = new stdClass();
            //$tempMenuItem->url = $page->uri;
            $tempMenuItem->target = null;
            $tempMenuItem->active = $page->status == 'published';
            $tempMenuItem->id = 'new_' . rand(0, 3000000);
            $tempMenuItem->entry = $page;
            $tempMenuItem->languages = array();
            foreach ($languages as $language) {
                $itemLang = new stdClass();
                $itemLang->language_id = $language;
                $pageLanguage = $page->languages->findByLocale($language);
                $pageWO = $page->getActiveWebsiteEntry();
                if ($pageLanguage) {
                    $itemLang->title = $pageLanguage->title;
                } else {
                    $itemLang->title = '';
                }
                if ($pageWO) {
                    $pageWOLang = $pageWO->languages->findBylocale($language);
                    $itemLang->url = $pageWOLang->lang_uri;
                }
                $tempMenuItem->languages[] = $itemLang;
             
                if ($language == $defaultLanguage) {
                    $tempMenuItem->title = $pageLanguage->title;
                }
            }
            $viewHtml = View::make('admin.pages.menus.menu_item')
                ->with('menuItem', $tempMenuItem)
                ->render();
            $result = array (
                'success'        => true,
                'menu_item_html' => $viewHtml         
            );
            
            return Response::json($result);
        } else if ($type == 'link') {
            $data = array(
                'title'         => Input::get('menu_label', ''),
                'url'           => Input::get('link_url'),
                'new_window'    => Input::get('new_window') == 'true'
            );
              
            $validator = Validator::make(
                $data,
                $this->itemRules($type)
            );
            if ($validator->fails()) {
                $result = array (
                    'success' => false,
                    'errors'  => $validator->messages()->toArray()
                );
                return Response::json($result);
            }
            
            $tempMenuItem = new stdClass();
            //$tempMenuItem->url = $data['url'];
            $tempMenuItem->target = $data['new_window'] ? '_blank' : null;
            $tempMenuItem->active = true;
            $tempMenuItem->id = 'new_' . rand(0, 3000000);
            $tempMenuItem->entry = null;
            $tempMenuItem->languages = array();
            foreach ($data['title'] as $lang => $value) {
                $itemLang = new stdClass();
                $itemLang->language_id = $lang;
                $itemLang->title = $value;
                $itemLang->url = $data['url'][$lang];
                $tempMenuItem->languages[] = $itemLang; 
                
                if ($lang == $defaultLanguage) {
                    $tempMenuItem->title = $value;
                }
            } 
            
            $viewHtml = View::make('admin.pages.menus.menu_item')
                ->with('menuItem', $tempMenuItem)
                ->render();
            $result = array (
                'success'        => true,
                'menu_item_html' => $viewHtml         
            );
            
            return Response::json($result);
        }
    }
    
    private function buildStructure (&$menuStructure, &$i, &$data, $parentId = null) {

        foreach ($menuStructure as $menuItem) {
            $i++;
            $menuItem->title = $data['titles'][$menuItem->id]['en'];
            $menuItem->position = $i;
            $menuItem->parent_id = $parentId;
            
            $pageWO = null;
            if ($data['types'][$menuItem->id] == 'page') {
                $page = Entry::find($data['entry_id'][$menuItem->id]);
    
                if (!$page) {
                    //Todo: some error action?
                }
                $menuItem->entry = $page;
                $pageWO = $menuItem->entry->getActiveWebsiteEntry();
                //$menuItem->url = $page->uri;
            } else {
                //$menuItem->url = $data['urls'][$menuItem->id];
                $menuItem->entry = null;
            }
            $menuItem->target = isset($data['new_windows'][$menuItem->id]) ? '_blank' : null;
            $menuItem->active = isset($data['states'][$menuItem->id]) ? true : false;
            $languages = LaravelLocalization::getSupportedLanguagesKeys();
            $menuItem->languages = array();
            foreach ($languages as $language) {
                $itemLang = new stdClass();
                $itemLang->language_id = $language;
                $itemLang->title = $data['titles'][$menuItem->id][$language];
                
                $itemLang->url = $data['urls'][$menuItem->id][$language];
                if ($pageWO) { 
                    $pageWOLang = $pageWO->languages->findByLocale($language);
                    $itemLang->url = $pageWOLang->lang_uri;
                } else {
                    $itemLang->url = $data['urls'][$menuItem->id][$language];
                }
                
                $menuItem->languages[] = $itemLang;
             
                if ($language == \Config::get('app.locale')) {
                    $menuItem->title = $data['titles'][$menuItem->id][$language];
                }
            }
            
            //$i++;
            if (isset($menuItem->children)) {
                $this->buildStructure($menuItem->children, $i, $data, $menuItem->id);
            }
        }
    }
    
    public function postEdit($menuId) {  
        $menu = Menu::find($menuId);
        if (!$menu ) {
            App::abort(404);
        }
        $user = Auth::backend()->user();
       
        if (!$user->hasPermission('cms.manage')) {
            App::abort(403);
        }
        
        $ids = Input::get('menu_id');
        $ids = $ids ? $ids : array();
        $menuStructure = json_decode(Input::get('menu_structure'));
        $types = Input::get('menu_type');
        $titles = Input::get('title');
        $urls = Input::get('url');
        $states = Input::get('active');
        $newWindows = Input::get('new_window');
        $entriesIds = Input::get('entry_id');
        $toDelete = Input::get('to_delete');
        $contentType = ContentTypes::find('page');
        $pages = $contentType->toList();
  
        $data = array(      
            'titles'        => $titles,
            'types'         => $types,
            'urls'          => $urls,
            'states'        => $states,
            'new_windows'   => $newWindows,
            'entry_id'      => $entriesIds
        );
        $counter = 0;
        $this->buildStructure($menuStructure, $counter, $data);

        //Validation
        $menuErrors = array();
        foreach ($ids as $itemId) {
            //validation fields
            $itemValidationFields = array(
                'title[' . $itemId . ']'       => $titles[$itemId]
            );
            if ($types[$itemId] == 'link') {
                $itemValidationFields['url[' . $itemId . ']'] = $urls[$itemId]; 
            } 
           
            $validator = Validator::make(
                $itemValidationFields,
                $this->itemRules($types[$itemId], $itemId)
            );
            
            if ($validator->fails()) {
                $menuErrors[$itemId] = $validator->errors();
            }
        }                                    
        
        if (sizeof($menuErrors) > 0) {
            return View::make('admin/pages/menus/edit_menu')
                ->with(array(
                    'menu'           => $menu,
                    'pages'          => $pages,
                    'menuItems'      => $menuStructure,
                    'menu_errors'    => $menuErrors,
                    'to_delete'      => $toDelete
                ));
        }
        
        //Saves Menu
        DB::transaction(function() use ($menu, $menuStructure, $toDelete) {
            $this->saveMenuStructure($menu->id, $menuStructure);
            
            //deletes excluded menu items
            if ($toDelete) {
                $toDelete = explode(',', $toDelete);
                foreach ($toDelete as $id) {
                    if (is_numeric($id)) {
                        $menu->menuItems()->find($id)->delete();
                    }
                }
            }
        });
        
        return Redirect::to('/admin/menus/edit/' . $menuId)->with("message", Lang::get('backend.save_success'));
    }
    
    private function saveMenuStructure ($menuId, &$menuStructure, $parentId = null) {
        foreach ($menuStructure as $item) {
            if (strpos ($item->id, 'new_') !== false) {
                //New MenuITem
                $menuItem = new MenuItem();
            } else {
                //Existing MenuItem
                $menuItem = MenuItem::find($item->id);
                //Reset langugage fields
                MenuItemLanguage::where('menu_item_id', $item->id)->delete();
            }
            $menuItem->parent_id = $parentId;
            $menuItem->menu_id = $menuId;
            $menuItem->target = $item->target;
            $menuItem->position = $item->position;
            $menuItem->active = $item->active;
             
            

            //Languae fields
            $langFields = array();
            foreach ($item->languages as $language) {
                $menuItemLang = new MenuItemLanguage(array(
                    'language_id'     => $language->language_id,
                    'title'           => $language->title
                ));
                if (isset($item->entry) && $item->entry) {
                    //Page item
                    $menuItem->entry_id = $item->entry->id;
                    $entryWO = $item->entry->getActiveWebsiteEntry();
                    $entryWOLang = $entryWO->languages->findByLocale($language->language_id);
                    $menuItemLang->url = $entryWOLang->lang_uri;
                } else {
                    //Link Item
                    $menuItemLang->url = $language->url;
                }
                $langFields[] = $menuItemLang;
            }
            
            $menuItem->save();
            $menuItem->languages()->saveMany($langFields);
            
            if (isset($item->children)) {
                $this->saveMenuStructure($menuId, $item->children, $menuItem->id);
            }
        }         
    }
                                     
    public function getEdit($menuId = null)
    {                                        
        if ($menuId == null && !is_numeric($menuId)) {
            App::abort(404);
        }
        $user = Auth::backend()->user();   
        
        $menu = Menu::find($menuId);
        if (!$menu) {
            App::abort(404);
        }
        if (!$user->hasPermission('cms.manage')) {
            App::abort(403);
        }
        
        RequestContext::set('selected_menu', 'admin_menus');
        RequestContext::set('selected_menu_option', 'admin_menu_' . $menu->id);
        
        $contentType = ContentTypes::find('page');
        $pages = $contentType->toList();
 
        $structuredMenu = $menu->getStructuredItems();

        return View::make('admin/pages/menus/edit_menu')
            ->with(array(
                'user'      => $user,
                'menu'      => $menu,
                'pages'     => $pages,
                'menuItems' => $structuredMenu
            ));
    }
    
    private function itemRules ($type, $groupIndex = null) {

        $languages = LaravelLocalization::getSupportedLanguagesKeys();
        if ($groupIndex) {
            $groupIndex = '[' . $groupIndex . ']';
        }
        if ($type == 'link') { 
            $rules = generateLangRules(array (
                'title' . $groupIndex  => 'required|max:100',
                'url' . $groupIndex => 'required|max:255'
            ), $languages);  
        } else {
            $rules = generateLangRules(array (
                'title' . $groupIndex  => 'required|max:100',
            ), $languages);
        }      
        return $rules;
    }
}
