<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\repository\admin;

use app\repository\BaseRepository;
use think\facade\Db;


/**
 * 操作日志仓储
 * @package app\repository\admin
 */
class OperationLogRepository extends BaseRepository
{
    /**
     * 分页查询操作日志
     * @param array $filters
     * @param int $limit
     * @return mixed
     */
    public function paginate(array $filters, int $limit)
    {
        $query = Db::name('sys_admin_operation_logs')->order('id', 'desc');

        $keyword = trim((string)($filters['keyword'] ?? ''));
        if ($keyword !== '') {
            $query->where('admin_username|action|path|ip', 'like', "%{$keyword}%");
        }

        $method = strtoupper(trim((string)($filters['method'] ?? '')));
        if (in_array($method, ['GET', 'POST', 'PUT', 'DELETE'], true)) {
            $query->where('method', $method);
        }

        $createdStart = $this->parseTimeToInt($filters['created_start'] ?? null, false);
        $createdEnd = $this->parseTimeToInt($filters['created_end'] ?? null, true);
        if ($createdStart !== null) {
            $query->where('create_time', '>=', $createdStart);
        }
        if ($createdEnd !== null) {
            $query->where('create_time', '<=', $createdEnd);
        }

        return $query->paginate($limit);
    }


    /**
     * 统计指定时间之前的操作日志数量
     * @param int $cutoff 截止时间戳
     * @return int
     */
    public function countOlderThan(int $cutoff): int
    {
        if ($cutoff <= 0) {
            return 0;
        }

        return (int)Db::name('sys_admin_operation_logs')
            ->where('create_time', '<', $cutoff)
            ->count();
    }


    /**
     * 删除指定时间之前的操作日志
     * @param int $cutoff 截止时间戳
     * @param int $limit  单次最大删除条数
     * @return int 实际删除条数
     */
    public function deleteOlderThan(int $cutoff, int $limit): int
    {
        if ($cutoff <= 0) {
            return 0;
        }

        if ($limit <= 0) {
            $limit = 1000;
        }
        if ($limit > 20000) {
            $limit = 20000;
        }

        $ids = Db::name('sys_admin_operation_logs')
            ->where('create_time', '<', $cutoff)
            ->order('id', 'asc')
            ->limit($limit)
            ->column('id');

        if (empty($ids)) {
            return 0;
        }

        return (int)Db::name('sys_admin_operation_logs')->whereIn('id', $ids)->delete();
    }

    /**
     * 将时间原始值解析为Unix时间戳
     * @param mixed $raw 原始值（时间戳/日期字符串）
     * @param bool $isEnd 是否为结束时间（日期字符串末尾加23:59:59）
     * @return int|null 时间戳或null
     */
    private function parseTimeToInt($raw, bool $isEnd): ?int
    {
        if ($raw === null) {
            return null;
        }
        if (is_int($raw) || is_float($raw)) {
            $value = (int)$raw;
            return $value > 0 ? $value : null;
        }

        $string = trim((string)$raw);
        if ($string === '') {
            return null;
        }
        if (is_numeric($string)) {
            $value = (int)$string;
            return $value > 0 ? $value : null;
        }
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $string)) {
            $string .= $isEnd ? ' 23:59:59' : ' 00:00:00';
        }

        $timestamp = strtotime($string);
        if ($timestamp === false || $timestamp <= 0) {
            return null;
        }

        return (int)$timestamp;
    }
}