<?php

class PageEmailQueueProcess extends Page
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Title = 'Fronta pošty';
    $this->Description = 'Odeslání pošty z fronty';
    $this->ParentClass = 'PagePortal';
  }

  function Show(): string
  {
    $Output = ModuleEmailQueue::Cast($this->System->GetModule('EmailQueue'))->Process();
    $Output = $this->SystemMessage('Zpracování fronty emailů', 'Nové emaily byly odeslány').$Output;
    return $Output;
  }
}

class EmailQueue extends Model
{
  static function GetModelDesc(): ModelDesc
  {
    $Desc = new ModelDesc(self::GetClassName());
    $Desc->AddDateTime('Time');
    $Desc->AddString('To');
    $Desc->AddString('Subject');
    $Desc->AddText('Content');
    $Desc->AddString('Headers');
    $Desc->AddBoolean('Archive');
    $Desc->AddString('From');
    $Desc->AddReference('AttachmentFile', File::GetClassName());
    return $Desc;
  }
}

class ModuleEmailQueue extends Module
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'EmailQueue';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'Queue for delayed email sending and history';
    $this->Dependencies = array(ModuleLog::GetName());
    $this->Models = array(EmailQueue::GetClassName());
  }

  function DoStart(): void
  {
    $this->System->RegisterPage(['fronta-posty'], 'PageEmailQueueProcess');
    $this->System->FormManager->RegisterClass('Email', array(
        'Title' => 'Nový email',
        'Table' => 'EmailQueue',
        'SubmitText' => 'Odeslat',
        'Items' => array(
            'Address' => array('Type' => 'String', 'Caption' => 'Adresa', 'Default' => ''),
            'Subject' => array('Type' => 'String', 'Caption' => 'Předmět', 'Default' => ''),
            'Content' => array('Type' => 'Text', 'Caption' => 'Obsah', 'Default' => ''),
        ),
    ));
    $this->System->FormManager->RegisterClass('EmailQueue', array(
        'Title' => 'Fronta e-mailů',
        'Table' => 'EmailQueue',
        'DefaultSortColumn' => 'Time',
        'DefaultSortOrder' => 1,
        'Items' => array(
            'Time' => array('Type' => 'DateTime', 'Caption' => 'Vytvořeno'),
            'To' => array('Type' => 'String', 'Caption' => 'Příjemce', 'Default' => ''),
            'Subject' => array('Type' => 'String', 'Caption' => 'Předmět', 'Default' => ''),
            'Content' => array('Type' => 'Text', 'Caption' => 'Obsah', 'Default' => ''),
            'Headers' => array('Type' => 'String', 'Caption' => 'Hlavička', 'Default' => ''),
            'Archive' => array('Type' => 'Boolean', 'Caption' => 'Odesláno', 'Default' => '0'),
            'From' => array('Type' => 'String', 'Caption' => 'Odesílatel', 'Default' => ''),
            'AttachmentFile' => array('Type' => 'TFile', 'Caption' => 'Příloha', 'Default' => '', 'Null' => true),
        ),
        'Actions' => array(
            array('Caption' => 'Odeslat nové', 'URL' => '/fronta-posty/'),
        ),
    ));
  }

  function AddItem(string $To, string $Subject, string $Content, string $From, string $AttachmentFileId = ''): void
  {
    $Values = array('To' => $To,
      'Subject' => $Subject, 'Content' => $Content, 'Time' => 'NOW()', 'Headers' => '',
      'From' => $From);
    if ($AttachmentFileId != '') $Values['AttachmentFile'] = $AttachmentFileId;
    $this->Database->insert('EmailQueue', $Values);
  }

  function Process(): string
  {
    $Output = '';
    $DbResult = $this->Database->select('EmailQueue', '*', 'Archive=0');
    while ($DbRow = $DbResult->fetch_assoc())
    {
      $Mail = new Mail();
      $Mail->AddToCombined($DbRow['To']);
      $Mail->Subject = $DbRow['Subject'];
      $Mail->From = $DbRow['From'];
      $Mail->AddBody(strip_tags($DbRow['Content']), 'text/plain');
      $Mail->AddBody($DbRow['Content'], 'text/html');
      if ($DbRow['AttachmentFile'] != '')
      {
        $DbResult2 = $this->Database->select('File', '*', 'Id='.$DbRow['AttachmentFile']);
        while ($File = $DbResult2->fetch_assoc())
          $Mail->AttachFile($this->Config['Web']['FileRootFolder'].$File['DrivePath'], $File['MimeType']);
      }
      $Mail->Send();
      $this->Database->update('EmailQueue', 'Id='.$DbRow['Id'], array('Archive' => 1));
      ModuleLog::Cast($this->System->GetModule('Log'))->NewRecord('System', 'SendEmail', $DbRow['Id']);
      $Output .= 'To: '.$DbRow['To'].'  Subject: '.$DbRow['Subject'].'<br />';
    }
    return $Output;
  }

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