<?php

include_once(dirname(__FILE__).'/User.php');
include_once(dirname(__FILE__).'/PageUserList.php');
include_once(dirname(__FILE__).'/PageUser.php');

class ModuleUser extends Module
{
  var $UserPanel;

  function __construct($System)
  {
    parent::__construct($System);
    $this->Name = 'User';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'User management';
    $this->Dependencies = array();
    $this->UserPanel = array();
  }

  function DoInstall(): void
  {
    $this->Database->query('CREATE TABLE IF NOT EXISTS `User` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`Login` varchar(64) NOT NULL,'.
      '`Name` varchar(128) NOT NULL,'.
      '`Password` varchar(255) NOT NULL,'.
      '`Salt` varchar(255) NOT NULL,'.
      '`Email` varchar(128) NOT NULL DEFAULT "",'.
      '`BirthDate` date NULL,'.
      '`LastIpAddress` varchar(45) NOT NULL DEFAULT "",'.
      '`LastLoginTime` datetime NULL,'.
      '`RegistrationTime` datetime NULL,'.
      '`Locked` tinyint(1) NOT NULL DEFAULT "0",'.
      'PRIMARY KEY (`Id`),'.
      'UNIQUE KEY `Name` (`Login`),'.
      'UNIQUE KEY `Nick` (`Name`)'.
      ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `UserOnline` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`User` int(11) DEFAULT NULL,'.
      '`ActivityTime` datetime NULL,'.
      '`LoginTime` datetime NULL,'.
      '`SessionId` varchar(255) NOT NULL DEFAULT "",'.
      '`IpAddress` varchar(45) NOT NULL DEFAULT "",'.
      '`HostName` varchar(255) NOT NULL DEFAULT "",'.
      '`ScriptName` varchar(255) NOT NULL,'.
      '`StayLogged` int(11) DEFAULT NULL,'.
      '`StayLoggedHash` varchar(255) NOT NULL DEFAULT "",'.
      'PRIMARY KEY (`Id`),'.
      'KEY `User` (`User`)'.
      ') ENGINE=MEMORY  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `PermissionGroup` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`Description` varchar(255) NOT NULL DEFAULT "",'.
      'PRIMARY KEY (`Id`)'.
      ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `PermissionGroupAssignment` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`Group` int(11) NOT NULL DEFAULT "0",'.
      '`AssignedGroup` int(11) DEFAULT NULL,'.
      '`AssignedOperation` int(11) DEFAULT NULL,'.
      'PRIMARY KEY (`Id`),'.
      'KEY `Group` (`Group`),'.
      'KEY `AssignedGroup` (`AssignedGroup`),'.
      'KEY `AssignedOperation` (`AssignedOperation`)'.
      ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `PermissionOperation` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`Module` int(11) NOT NULL,'.
      '`Operation` varchar(128) NOT NULL DEFAULT "",'.
      '`Item` varchar(64) NOT NULL DEFAULT "",'.
      '`ItemId` int(11) NOT NULL DEFAULT 0,'.
      'PRIMARY KEY (`Id`),'.
      'KEY `Module` (`Module`),'.
      'KEY `Operation` (`Operation`),'.
      'KEY `Item` (`Item`),'.
      'KEY `ItemId` (`ItemId`)'.
      ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `PermissionUserAssignment` ('.
      '`Id` int(11) NOT NULL AUTO_INCREMENT,'.
      '`User` int(11) DEFAULT NULL,'.
      '`AssignedGroup` int(11) DEFAULT NULL,'.
      '`AssignedOperation` int(11) DEFAULT NULL,'.
      'PRIMARY KEY (`Id`),'.
      'KEY `User` (`User`),'.
      'KEY `AssignedGroup` (`AssignedGroup`),'.
      'KEY `AssignedOperation` (`AssignedOperation`)'.
      ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');

    $this->Database->query("ALTER TABLE `PermissionGroupAssignment`
      ADD CONSTRAINT `PermissionGroupAssignment_ibfk_1` FOREIGN KEY (`Group`) REFERENCES `PermissionGroup` (`Id`),
      ADD CONSTRAINT `PermissionGroupAssignment_ibfk_2` FOREIGN KEY (`AssignedGroup`) REFERENCES `PermissionGroup` (`Id`),
      ADD CONSTRAINT `PermissionGroupAssignment_ibfk_3` FOREIGN KEY (`AssignedOperation`) REFERENCES `PermissionOperation` (`Id`);");

    $this->Database->query("ALTER TABLE `PermissionOperation`
      ADD CONSTRAINT `PermissionOperation_ibfk_1` FOREIGN KEY (`Module`) REFERENCES `Module` (`Id`);");

    $this->Database->query("ALTER TABLE `PermissionUserAssignment`
      ADD CONSTRAINT `PermissionUserAssignment_ibfk_2` FOREIGN KEY (`AssignedGroup`) REFERENCES `PermissionGroup` (`Id`),
      ADD CONSTRAINT `PermissionUserAssignment_ibfk_3` FOREIGN KEY (`AssignedOperation`) REFERENCES `PermissionOperation` (`Id`),
      ADD CONSTRAINT `PermissionUserAssignment_ibfk_4` FOREIGN KEY (`User`) REFERENCES `User` (`Id`);");

    $this->Database->query('INSERT INTO `PermissionGroup` (`Id`, `Description`) VALUES (NULL, "Uživatelé");');
  }

  function DoUninstall(): void
  {
    $this->Database->query('DROP TABLE `PermissionUserAssignment`');
    $this->Database->query('DROP TABLE `PermissionGroupAssignment`');
    $this->Database->query('DROP TABLE `PermissionGroup`');
    $this->Database->query('DROP TABLE `PermissionOperation`');
    $this->Database->query('DROP TABLE `UserOnline`');
    $this->Database->query('DROP TABLE `User`');
  }

  function DoUpgrade(): string
  {
    /*

     if ($this->InstalledVersion == '1.0') {
      $this->System->Database->Query('SELECT * FROM User WHERE Id=1');
      $this->InstalledVersion = '1.1';
    }
    */
    return '';
  }

  function DoStart(): void
  {
    Core::Cast($this->System)->User = new User($this->System);
    if (isset($_SERVER['REMOTE_ADDR'])) Core::Cast($this->System)->User->Check();
    $this->System->RegisterPage(['userlist'], 'PageUserList');
    $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' => ''),
      ),
    ));
    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' => ''),
      ),
    ));
    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',
    ));
  }

  function ShowDashboardItem()
  {
    $DbResult = $this->Database->select('User', 'COUNT(*)', '1');
    $DbRow = $DbResult->fetch_row();
    $Output = 'Uživatelů: '.$DbRow['0'].'<br/>';
    return $Output;
  }

  function DoStop(): void
  {
  }

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