<?php

include_once(dirname(__FILE__).'/UserModel.php');
include_once(dirname(__FILE__).'/UserList.php');
include_once(dirname(__FILE__).'/UserPage.php');

class ModuleUser extends Module
{
  public array $UserPanel;
  public User $User;

  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'User';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'User management';
    $this->Models = array(User::GetClassName(), UserOnline::GetClassName(), PermissionGroup::GetClassName(), PermissionOperation::GetClassName(),
      PermissionGroupAssignment::GetClassName(), PermissionUserAssignment::GetClassName());

    $this->UserPanel = array();
    $this->User = new User($System);
  }

  function DoInsertSampleData(): void
  {
    $DbResult = $this->Database->select('User', 'Id', 'Login="admin"');
    if ($DbResult->num_rows == 0)
    {
      $UserId = $this->Database->insert('User', array('Id' => 1, 'Login' => 'admin', 'Name' => 'Admin', 'Password' => 'd04b7c77a814de3207315c2f82dcd97a90ed33ca',
        'Salt' => 'd5d8eb61e1a20d98b45b415ccd2fae802cb41294', 'Email' => 'admin@localhost', 'LastIpAddress' => null, 'LastLoginTime' => null,
        'RegistrationTime' => '2021-02-17 14:56:22', 'Locked' => 0, 'InitPassword' => null));

      $PermissionGroup1 = $this->Database->insert('PermissionGroup', array('Description' => 'Ostatní'));
      $PermissionGroup2 = $this->Database->insert('PermissionGroup', array('Description' => 'Registrovaní uživatelé'));
      $PermissionGroup3 = $this->Database->insert('PermissionGroup', array('Description' => 'Zákazníci'));
      $PermissionGroup4 = $this->Database->insert('PermissionGroup', array('Description' => 'Správci sítě'));
      $PermissionGroup5 = $this->Database->insert('PermissionGroup', array('Description' => 'Systémoví správci'));

      $this->Database->insert('PermissionUserAssignment', array('User' => $UserId, 'AssignedGroup' => $PermissionGroup5));
    }
  }

  function DoStart(): void
  {
    if (isset($_SERVER['REMOTE_ADDR'])) $this->User->Check();
    Core::Cast($this->System)->RegisterPage(['userlist'], 'PageUserList');
    Core::Cast($this->System)->RegisterPage(['user'], 'PageUser');
    Core::Cast($this->System)->RegisterPageBarItem('Top', 'User', array($this, 'TopBarCallback'));
    Core::Cast($this->System)->FormManager->RegisterClass('UserLogin', array(
      'Title' => 'Přihlášení uživatele',
      'SubmitText' => 'Přihlásit',
      'Table' => '',
      'Items' => array(
        'Username' => array('Type' => 'String', 'Caption' => 'Přihlašovací jméno', 'Default' => ''),
        'Password' => array('Type' => 'Password', 'Caption' => 'Heslo', 'Default' => ''),
        'StayLogged' => array('Type' => 'Boolean', 'Caption' => 'Zůstat přihlášen', 'Default' => '0'),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('UserOptions', array(
      'Title' => 'Základní nastavení',
      'Table' => 'User',
      'SubmitText' => 'Uložit',
      'Items' => array(
        'Login' => array('Type' => 'String', 'Caption' => 'Přihlašovací jméno', 'Default' => ''),
        'Salt' => array('Type' => 'RandomHash', 'Caption' => 'Sůl', 'Default' => ''),
        'Password' => array('Type' => 'Password', 'Caption' => 'Heslo', 'Default' => ''),
        'Name' => array('Type' => 'String', 'Caption' => 'Zobrazované jméno', 'Default' => ''),
        'Email' => array('Type' => 'String', 'Caption' => 'E-mail', 'Default' => ''),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('UserRegister', array(
      'Title' => 'Registrace uživatele',
      'SubmitText' => 'Registrovat',
      'Table' => 'User',
      'Items' => array(
        'Login' => array('Type' => 'String', 'Caption' => 'Přihlašovací jméno', 'Default' => ''),
        'Password' => array('Type' => 'Password', 'Caption' => 'Heslo', 'Default' => ''),
        'Password2' => array('Type' => 'Password', 'Caption' => 'Potvrzení hesla', 'Default' => ''),
        'Name' => array('Type' => 'String', 'Caption' => 'Zobrazované jméno', 'Default' => ''),
        'Email' => array('Type' => 'String', 'Caption' => 'E-mail', 'Default' => ''),
        'IsHuman' => array('Type' => 'Boolean', 'Caption' => 'Jsi člověk?', 'Default' => 0),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('PasswordRecovery', array(
      'Title' => 'Obnova hesla',
      'SubmitText' => 'Obnovit',
      'Table' => '',
      'Items' => array(
        'Name' => array('Type' => 'String', 'Caption' => 'Přihlašovací jméno', 'Default' => ''),
        'Email' => array('Type' => 'String', 'Caption' => 'E-mail', 'Default' => ''),
        'IsHuman' => array('Type' => 'Boolean', 'Caption' => 'Jsi člověk?', 'Default' => 0),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('APIToken', array(
      'Title' => 'Přístupový token',
      'Table' => 'APIToken',
      'Items' => array(
        'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => ''),
        'Token' => array('Type' => 'String', 'Caption' => 'Token', 'Default' => ''),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('User', array(
      'Title' => 'Uživatelé',
      'Table' => 'User',
      'DefaultSortColumn' => 'Name',
      'Items' => array(
        'Login' => array('Type' => 'String', 'Caption' => 'Přihlašovací jméno', 'Default' => ''),
        'Name' => array('Type' => 'String', 'Caption' => 'Celé jméno', 'Default' => ''),
        'Salt' => array('Type' => 'RandomHash', 'Caption' => 'Sůl', 'Default' => '', 'NotInList' => true),
        'Password' => array('Type' => 'Password', 'Caption' => 'Heslo', 'Default' => '', 'Method' => 'DoubleSHA1', 'NotInList' => true),
        'Email' => array('Type' => 'String', 'Caption' => 'E-mail', 'Default' => ''),
        'LastIpAddress' => array('Type' => 'IPv4Address', 'Caption' => 'Poslední IP adresa', 'Default' => '', 'ReadOnly' => true),
        'LastLoginTime' => array('Type' => 'DateTime', 'Caption' => 'Poslední čas přihlášení', 'Default' => '', 'ReadOnly' => true),
        'RegistrationTime' => array('Type' => 'DateTime', 'Caption' => 'Čas registrace', 'Default' => ''),
        'Locked' => array('Type' => 'Boolean', 'Caption' => 'Uzamčen', 'Default' => ''),
        'UserRel' => array('Type' => 'TUserCustomerRelListUser', 'Caption' => 'Přístup k zákazníkům', 'Default' => ''),
        'Permission' => array('Type' => 'TPermissionUserAssignmentListUser', 'Caption' => 'Oprávnění', 'Default' => ''),
        'Contatcs' => array('Type' => 'TContactListUser', 'Caption' => 'Kontakty', 'Default' => ''),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('PermissionUserAssignment', array(
      'Title' => 'Oprávnění uživatelů',
      'Table' => 'PermissionUserAssignment',
      'Items' => array(
        'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => ''),
        'AssignedGroup' => array('Type' => 'TPermissionGroup', 'Caption' => 'Přiřazené skupiny', 'Default' => '', 'Null' => true),
        'AssignedOperation' => array('Type' => 'TPermissionOperation', 'Caption' => 'Přiřazené operace', 'Default' => '', 'Null' => true),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('PermissionGroup', array(
      'Title' => 'Skupiny oprávnění',
      'Table' => 'PermissionGroup',
      'Items' => array(
        'Description' => array('Type' => 'String', 'Caption' => 'Název', 'Default' => ''),
        'AssignedGroup' => array('Type' => 'TPermissionGroupAssignmentListGroup', 'Caption' => 'Přiřazené skupiny a operace', 'Default' => '', 'Null' => true),
        'AssignedGroup2' => array('Type' => 'TPermissionGroupAssignmentListAssignedGroup', 'Caption' => 'Použito ve skupinách', 'Default' => '', 'Null' => true),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('PermissionGroupAssignment', array(
      'Title' => 'Přiřazení skupin oprávnění',
      'Table' => 'PermissionGroupAssignment',
      'Items' => array(
        'Group' => array('Type' => 'TPermissionGroup', 'Caption' => 'Skupina', 'Default' => ''),
        'AssignedGroup' => array('Type' => 'TPermissionGroup', 'Caption' => 'Přiřazené skupiny', 'Default' => '', 'Null' => true),
        'AssignedOperation' => array('Type' => 'TPermissionOperation', 'Caption' => 'Přiřazené operace', 'Default' => '', 'Null' => true),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterClass('PermissionOperation', array(
      'Title' => 'Operace oprávnění',
      'Table' => 'PermissionOperation',
      'Items' => array(
        'Module' => array('Type' => 'TModule', 'Caption' => 'Modul', 'Default' => ''),
        'Operation' => array('Type' => 'String', 'Caption' => 'Operace', 'Default' => ''),
        'Item' => array('Type' => 'String', 'Caption' => 'Položka', 'Default' => ''),
        'ItemId' => array('Type' => 'Integer', 'Caption' => 'Index položky', 'Default' => ''),
        'AssignedGroup' => array('Type' => 'TPermissionGroupAssignmentListOperation', 'Caption' => 'Použito ve skupinách', 'Default' => '', 'Null' => true),
      ),
    ));
    Core::Cast($this->System)->FormManager->RegisterFormType('TUser', array(
      'Type' => 'Reference',
      'Table' => 'User',
      'Id' => 'Id',
      'Name' => 'Name',
      'Filter' => '1',
    ));
    Core::Cast($this->System)->FormManager->RegisterFormType('TPermissionGroup', array(
      'Type' => 'Reference',
      'Table' => 'PermissionGroup',
      'Id' => 'Id',
      'Name' => 'Description',
      'Filter' => '1',
    ));
    Core::Cast($this->System)->FormManager->RegisterFormType('TPermissionGroupAssignment', array(
      'Type' => 'Reference',
      'Table' => 'PermissionGroupAssignment',
      'Id' => 'Id',
      'Name' => 'Id',
      'Filter' => '1',
    ));
    Core::Cast($this->System)->FormManager->RegisterFormType('TPermissionOperation', array(
      'Type' => 'Reference',
      'Table' => 'PermissionOperation',
      'Id' => 'Id',
      'Name' => 'Id',
      'Filter' => '1',
    ));
    ModuleIS::Cast(Core::Cast($this->System)->GetModule('IS'))->RegisterDashboardItem('User',
      array($this, 'ShowDashboardItem'));
  }

  function ShowDashboardItem(): string
  {
    $DbResult = $this->Database->select('User', 'COUNT(*)', '1');
    $DbRow = $DbResult->fetch_row();
    $Output = 'Uživatelů: <a href="'.$this->System->Link('/is/?a=list&amp;t=User&amp;filter=1').'">'.$DbRow['0'].'</a><br/>';
    return $Output;
  }

  function TopBarCallback(): string
  {
    if ($this->User->User['Id'] == null)
    {
      $Output = '<a href="'.Core::Cast($this->System)->Link('/user/?Action=LoginForm').'">Přihlášení</a> '.
        '<a href="'.Core::Cast($this->System)->Link('/user/?Action=UserRegister').'">Registrace</a>';
    } else
    {
      $Output = $this->User->User['Name'].
        ' <a href="'.Core::Cast($this->System)->Link('/user/?Action=UserMenu').'">Nabídka</a>'.
        ' <a href="'.Core::Cast($this->System)->Link('/user/?Action=Logout').'">Odhlásit</a>';
      //   <a href="'.$this->System->Link('/?Action=UserOptions').'">Nastavení</a>';
    }
    return $Output;
  }

  static function Cast(Module $Module): ModuleUser
  {
    if ($Module instanceof ModuleUser)
    {
      return $Module;
    }
    throw new Exception('Expected ModuleUser type but got '.gettype($Module));
  }
}
