<?php

namespace pictpostpersonal\model;

use Exception;
use pictpostpersonal\PPPDateTime;
use pictpostpersonal\SQL;
use pictpostpersonal\SQLiteCRUD;

/**
 * 通知用のActivityを扱うクラス。
 * 記事へのlike付与も扱う。
 */
class SystemActivity
{
    const ACTIVITY_DELETE_SPAN = '-30 days';
    public const SYSTEM_ACTION_LOGIN = 'login';
    public const SYSTEM_ACTION_LOGIN_FAIL = 'login_error';
    private SQLiteCRUD $sqlcrud;

    public function __construct($db)
    {
        $this->sqlcrud = new SQLiteCRUD($db);
    }

    public static function initialize(SQLiteCRUD $sql_crud)
    {
        $sql_crud->table('system_activity')->createTable(
            [
                SQL::Id('id'),
                SQL::DateTime('created_at'),
                SQL::Text('from_ip'),
                SQL::Text('action'),
                SQL::Text('message'),
            ]
        );
    }

    /**
     * 指定分以内のリトライ回数を取得する
     *
     * @param string $action アクションの種類。login, login_error
     * 
     * @return int
     * 
     */
    public function getActivityCount(string $action, $minute): int
    {
        date_default_timezone_set('Asia/Tokyo');
        $date = PPPDateTime::Date('Y-m-d H:i:s');
        $before_time = date('Y-m-d H:i:s', strtotime("-$minute minutes", strtotime($date)));  // 指定分前の日時を計算して取得
        $row_count = $this->sqlcrud->table(
            'system_activity'
        )->where(
            'action = :action and created_at > :beforeTime',
            [
                'action' => $action,
                'beforeTime' => $before_time
            ]
        )->count();
        return $row_count;
    }

    /**
     * アクティビティを記録する
     *
     * @param string $action    アクション内容。like, message等
     * @param int $article_id   対象記事ID。対象がない場合は-1。
     * @param bool $use_transaction トランザクションを使用するか。通常true。呼び出し元でトランザクションを使用している場合はfalse。
     *
     * @return void
     *
     */
    public function create(string $action): void
    {
        try {
            $this->sqlcrud->begin();
            date_default_timezone_set('Asia/Tokyo');
            $date = PPPDateTime::Date('Y-m-d H:i:s');
            $data = [
                'action' => $action,
                'from_ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknonw',
                'created_at' => $date
            ];
            $this->sqlcrud->table('system_activity')->create($data);

            //古いアクティビティを削除
            $beforedays = date('Y-m-d H:i:s', strtotime(self::ACTIVITY_DELETE_SPAN, strtotime($date)));  // 7日前の日時を計算して取得
            $this->sqlcrud->execute('delete from system_activity where created_at < :beforeTime', ['beforeTime' => $beforedays]);
            $this->sqlcrud->commit();
        } catch (Exception $e) {
            $this->sqlcrud->rollback();
            throw $e;
        }
    }
}
