<?php

namespace IZON\Admin\Web\Controllers;

use Exception;

use \IZON\Admin\Services\SimpleAdminService;

use IZON\MVC\Controller;
use IZON\MVC\HttpRequest;
use IZON\MVC\ModelAndView;

/**
 * controller, ktery zobrazuje dashboard
 */
abstract class SimpleAdminController implements Controller {
    
    /**
     * @var SimpleAdminService 
     */
    protected $adminService;
    
    /**
     *
     * @var string name of view to call 
     */
    protected $viewName;

    /**
     *
     * @var string pod jakym id je ulozen v 
     */
    protected $thisControllerId;


    public function __construct(SimpleAdminService $adminService,
                                $viewName,
                                $thisControllerId) {
        $this->adminService = $adminService;
        $this->viewName = $viewName;
        $this->thisControllerId = $thisControllerId;
    }
    
    /**
     * execute je defaultni akce, ktera se zavola, pokud neni specifikovana jina metoda
     * @param HttpRequest $request
     * @return ModelAndView
     */
    public function execute(HttpRequest $request) {
        $modelAndView = new ModelAndView("admin/". $this->viewName ."/list");
        
        $paginatorConfig = $this->adminService->getPaginatorConfig();
        
        $modelAndView->putParameter("pageContent", 
                                    $this->adminService->getPage($paginatorConfig));
        
        $this->loadData($modelAndView);
        
        return $modelAndView;
    }
    
    /**
     * zobrazi editacni formular a naplni ho daty
     */
    public function edit(HttpRequest $request) {
        $modelAndView = new ModelAndView("admin/". $this->viewName ."/form");
        
        $form = $this->createForm();
        $modelAndView->putParameter("form", $form);
                
        if( $request->hasParameter("id") ) { // posila se id, musi se editovat odpovidajici objekt
            $id = $request->getParameter("id");
            
            $object = $this->adminService->get($id);
            
            $form->edit($object);
        } else {
            $article = $this->createDomainObject();
            $form->edit($article);
        }
        
        $this->loadData($modelAndView);
        
        return $modelAndView;
    }
    
    public function save(HttpRequest $request) {
        // TODO: pridat validaci atd.
        
        $form = $this->createForm();
        
        $form->setValues($request->getParameters());
        
        if( $request->hasParameter("id")
            && $request->getParameter("id") != '' ) { // posila se id, musi se editovat odpovidajici objekt
            $id = $request->getParameter("id");
            
            $object = $this->adminService->get($id);
            $form->flush($object);
            $this->adminService->update($object);
        } else {
            // TODO: potom odstranit
            $object = $this->createDomainObject();
            $form->flush($object);
            
            $this->adminService->save($object);
        }

        // TODO: predavat nejak informaci o this module nebo tak neco a nepouzivat Config
        $modelAndView = new ModelAndView(
                     $this->thisControllerId,
                     ['action' => 'execute'], true);
        
        return $modelAndView;
    }
    
    public function delete(HttpRequest $request) {
        if( !$request->hasParameter("id") ) {
            throw new Exception("Can't delete. No id provided");
        }
        
        $id = $request->getParameter("id");
        $this->adminService->delete($id);
        
        // TODO: provide flash message
        
        $modelAndView = new ModelAndView(
                    $this->thisControllerId,
                    ['action' => 'execute'], true);
        
        $this->loadData($modelAndView);
        
        return $modelAndView;
    }
    
    /**
     * vytvori editacni formular
     */
    protected abstract function createForm();
    
    /**
     * vytvori domenovy objekt pro editaci
     */
    protected abstract function createDomainObject();

    /**
     * nacte dalsi potrebna data
     */
    protected abstract function loadData(ModelAndView $modelAndView);
    
}
