<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-5-20
 */

header('Content-Type: application/json; charset=utf-8');
header('X-Content-Type-Options: nosniff');
header('Cache-Control: no-store');

$requestOrigin = trim((string) ($_SERVER['HTTP_ORIGIN'] ?? ''));
if ($requestOrigin !== '') {
    $originHost = strtolower((string) parse_url($requestOrigin, PHP_URL_HOST));
    $requestHost = strtolower((string) preg_replace('/:\d+$/', '', $_SERVER['HTTP_HOST'] ?? ''));
    if ($originHost === '' || $originHost !== $requestHost) {
        http_response_code(403);
        exit(json_encode(['code' => 403, 'msg' => '跨域请求已拒绝'], JSON_UNESCAPED_UNICODE));
    }
}

// 处理预检请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit(0);
}

require_once dirname(__DIR__) . '/core/lib/session.php';
cmsStartSession();
require_once dirname(__DIR__) . '/core/db/db.php';
require_once dirname(__DIR__) . '/core/lib/common.php';
require_once dirname(__DIR__) . '/core/lib/login_security.php';

$db = \Core\Db\DB::getInstance();
$result = ['code' => 0, 'msg' => ''];

function cmsApiClientIp()
{
    return substr((string) ($_SERVER['REMOTE_ADDR'] ?? ''), 0, 45);
}

function cmsApiRateAllowed($scope, $limit, $window)
{
    $dir = dirname(__DIR__) . '/data/cache/api-rate';
    if (!is_dir($dir) && !@mkdir($dir, 0700, true) && !is_dir($dir)) return true;
    $path = $dir . '/' . hash('sha256', $scope . '|' . cmsApiClientIp()) . '.json';
    $handle = @fopen($path, 'c+');
    if (!$handle || !flock($handle, LOCK_EX)) {
        if ($handle) fclose($handle);
        return true;
    }
    $raw = stream_get_contents($handle);
    $state = json_decode((string) $raw, true);
    if (!is_array($state) || intval($state['started_at'] ?? 0) <= time() - $window) {
        $state = ['started_at' => time(), 'count' => 0];
    }
    $state['count']++;
    ftruncate($handle, 0);
    rewind($handle);
    fwrite($handle, json_encode($state));
    fflush($handle);
    flock($handle, LOCK_UN);
    fclose($handle);
    return intval($state['count']) <= $limit;
}

// 提交留言
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    
    if ($action === 'submit') {
        $title = trim($_POST['title'] ?? '');
        $content = trim($_POST['content'] ?? '');
        $name = trim($_POST['name'] ?? '');
        $phone = trim($_POST['phone'] ?? '');
        $email = trim($_POST['email'] ?? '');
        $company = trim($_POST['company'] ?? '');
        $memberId = intval($_SESSION['member_id'] ?? 0);
        
        if (!cmsApiRateAllowed('guestbook', 5, 60)) {
            $result = ['code' => 429, 'msg' => '提交过于频繁，请稍后重试'];
        } elseif (empty($title) || empty($content)) {
            $result = ['code' => 400, 'msg' => '标题和内容不能为空'];
        } elseif (mb_strlen($title, 'UTF-8') > 200 || mb_strlen($content, 'UTF-8') > 2000
            || mb_strlen($name, 'UTF-8') > 50 || strlen($phone) > 50 || strlen($company) > 120
            || ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL))) {
            $result = ['code' => 400, 'msg' => '留言字段格式或长度不正确'];
        } else {
            $ip = cmsApiClientIp();
            $db->insert('guestbook', [
                'member_id' => $memberId,
                'title' => $title,
                'content' => $content,
                'name' => $name,
                'phone' => $phone,
                'email' => $email,
                'company' => $company,
                'ip' => $ip,
                'status' => 0,
                'create_time' => time()
            ]);
            sendAdminMessage('新留言：' . ($title ?: '无标题'), "姓名：{$name}\n联系方式：{$phone}\n邮箱：{$email}\n公司：{$company}\nIP：{$ip}\n内容：{$content}", $name);
            $result = ['code' => 200, 'msg' => '提交成功，我们会尽快回复您！'];
        }
    }
    
    // 搜索
    elseif ($action === 'search') {
        $keyword = trim($_POST['keyword'] ?? '');
        $type = in_array(($_POST['type'] ?? 'article'), ['article', 'product', 'image', 'video'], true) ? $_POST['type'] : 'article';
        
        if (!cmsApiRateAllowed('search', 30, 60)) {
            $result = ['code' => 429, 'msg' => '搜索过于频繁，请稍后重试'];
        } elseif (empty($keyword) || mb_strlen($keyword, 'UTF-8') > 100) {
            $result = ['code' => 400, 'msg' => '请输入搜索关键词'];
        } else {
            $keyword = '%' . $keyword . '%';
            
            if ($type === 'article') {
                $list = $db->fetchAll(
                    "SELECT a.*, c.channel_name FROM {$db->table('article')} a 
                     LEFT JOIN {$db->table('channel')} c ON a.channel_id = c.id 
                     WHERE a.status = 1 AND (a.title LIKE ? OR a.summary LIKE ?) 
                     ORDER BY a.create_time DESC LIMIT 10",
                    [$keyword, $keyword]
                );
            } else {
                $list = $db->fetchAll(
                    "SELECT * FROM {$db->table('product')} WHERE status = 1 AND (title LIKE ? OR summary LIKE ?) 
                     ORDER BY create_time DESC LIMIT 10",
                    [$keyword, $keyword]
                );
            }
            
            $result = ['code' => 200, 'msg' => '搜索成功', 'data' => $list];
        }
    }
    
    // 获取评论
    elseif ($action === 'get_comments') {
        $target_id = intval($_POST['target_id'] ?? 0);
        $type = in_array(($_POST['type'] ?? 'article'), ['article', 'product', 'image', 'video'], true) ? $_POST['type'] : 'article';
        if (!cmsApiRateAllowed('get_comments', 60, 60)) {
            $result = ['code' => 429, 'msg' => '请求过于频繁，请稍后重试'];
        } else {
            $comments = $db->fetchAll(
                "SELECT * FROM {$db->table('comment')} WHERE content_id = ? AND content_type = ? AND is_check = 1 AND is_show = 1 ORDER BY id DESC LIMIT 20",
                [$target_id, $type]
            );
            $result = ['code' => 200, 'msg' => '', 'data' => $comments];
        }
    }
    
    // 提交评论
    elseif ($action === 'add_comment') {
        $target_id = intval($_POST['target_id'] ?? 0);
        $type = in_array(($_POST['type'] ?? 'article'), ['article', 'product', 'image', 'video'], true) ? $_POST['type'] : 'article';
        $content = trim($_POST['content'] ?? '');
        $author = trim($_POST['author'] ?? '游客');
        
        if (!cmsApiRateAllowed('comment', 10, 60)) {
            $result = ['code' => 429, 'msg' => '评论过于频繁，请稍后重试'];
        } elseif (empty($content) || mb_strlen($content, 'UTF-8') > 2000 || mb_strlen($author, 'UTF-8') > 50) {
            $result = ['code' => 400, 'msg' => '评论内容不能为空'];
        } elseif ($target_id <= 0) {
            $result = ['code' => 400, 'msg' => '参数错误'];
        } else {
            $db->insert('comment', [
                'content_id' => $target_id,
                'content_type' => $type,
                'content' => $content,
                'name' => $author,
                'ip' => cmsApiClientIp(),
                'is_check' => 0,
                'is_show' => 0,
                'create_time' => time()
            ]);
            sendAdminMessage('新评论来自：' . $author, "评论对象ID：{$target_id}（类型：{$type}）\n评论者：{$author}\nIP：" . cmsApiClientIp() . "\n内容：{$content}", $author);
            $result = ['code' => 200, 'msg' => '评论成功'];
        }
    }
    
    // 会员注册
    elseif ($action === 'register') {
        $username = trim($_POST['username'] ?? '');
        $password = trim($_POST['password'] ?? '');
        $email = trim($_POST['email'] ?? '');
        
        if (!cmsApiRateAllowed('register', 3, 3600)) {
            $result = ['code' => 429, 'msg' => '注册过于频繁，请稍后重试'];
        } elseif (empty($username) || empty($password)) {
            $result = ['code' => 400, 'msg' => '用户名和密码不能为空'];
        } elseif (strlen($username) < 4 || strlen($username) > 20) {
            $result = ['code' => 400, 'msg' => '用户名长度必须在4-20个字符之间'];
        } elseif (strlen($password) < 6 || strlen($password) > 72 || ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL))) {
            $result = ['code' => 400, 'msg' => '密码或邮箱格式不正确'];
        } else {
            // 检查是否已存在
            $exists = $db->fetch("SELECT id FROM {$db->table('member')} WHERE username = ?", [$username]);
            if ($exists) {
                $result = ['code' => 400, 'msg' => '用户名已被注册'];
            } else {
                $defaultGroup = $db->fetch("SELECT id FROM {$db->table('member_group')} WHERE is_default = 1 LIMIT 1");
                $groupId = $defaultGroup ? $defaultGroup['id'] : 1;
                
                $db->insert('member', [
                    'username' => $username,
                    'password' => password_hash($password, PASSWORD_DEFAULT),
                    'email' => $email,
                    'group_id' => $groupId,
                    'reg_ip' => cmsApiClientIp(),
                    'reg_time' => time(),
                    'is_enabled' => 1
                ]);
                
                $result = ['code' => 200, 'msg' => '注册成功'];
            }
        }
    }
    
    // 会员登录
    elseif ($action === 'login') {
        $username = trim($_POST['username'] ?? '');
        $password = trim($_POST['password'] ?? '');
        $clientIp = cmsLoginClientIp();
        $securityDir = dirname(__DIR__) . '/data/cache/member-login-security';
        $loginLock = cmsGetLoginLock($username, $clientIp, $securityDir);
        
        if ($loginLock['locked']) {
            $result = ['code' => 429, 'msg' => '登录尝试过于频繁，请稍后重试'];
        } elseif (empty($username) || empty($password)) {
            $result = ['code' => 400, 'msg' => '请输入用户名和密码'];
        } else {
            cmsRecordLoginFailure($username, $clientIp, $securityDir);
            $member = $db->fetch("SELECT * FROM {$db->table('member')} WHERE username = ? AND is_enabled = 1", [$username]);
            if (!$member) {
                $result = ['code' => 400, 'msg' => '用户不存在或已被禁用'];
            } elseif (!password_verify($password, $member['password']) && md5($password) !== $member['password']) {
                $result = ['code' => 400, 'msg' => '密码错误'];
            } else {
                if (!password_verify($password, $member['password']) && md5($password) === $member['password']) {
                    $db->update('member', [
                        'password' => password_hash($password, PASSWORD_DEFAULT)
                    ], 'id = ?', [$member['id']]);
                }
                cmsClearLoginFailures($username, $clientIp, $securityDir);
                session_regenerate_id(true);
                $_SESSION['member_id'] = $member['id'];
                $_SESSION['member_name'] = $member['username'];
                $_SESSION['member_nickname'] = $member['nickname'];
                $_SESSION['member_group_id'] = $member['group_id'];
                
                $db->update('member', [
                    'last_login_time' => time(),
                    'last_login_ip' => cmsApiClientIp()
                ], 'id = ?', [$member['id']]);
                
                $result = ['code' => 200, 'msg' => '登录成功'];
            }
        }
    }
    
    // 退出登录
    elseif ($action === 'logout') {
        unset($_SESSION['member_id']);
        unset($_SESSION['member_name']);
        unset($_SESSION['member_nickname']);
        unset($_SESSION['member_group_id']);
        session_regenerate_id(true);
        
        $result = ['code' => 200, 'msg' => '退出成功'];
    }
    
    else {
        $result = ['code' => 404, 'msg' => '未知操作'];
    }
} else {
    $result = ['code' => 405, 'msg' => '请求方法不允许'];
}

echo json_encode($result, JSON_UNESCAPED_UNICODE);
