<?php
/**
 * 무료VPN 디바이스ID ↔ 쇼핑몰 회원 연관 매핑 라이브러리
 *
 * 앱의 무료(게스트) VPN ID는 디바이스 해시(예: 21f0845acfd59aaf)이며,
 * 동일 디바이스에서 회원 로그인 시 앱이 device_vpn_id 파라미터로 해시를 전송한다.
 * 이 매핑을 저장해 두면:
 *  - 무료VPN 계정 memo에 연관 회원(이름/ID)을 표기할 수 있고
 *  - 유료 주문 memo에 연관 무료VPN ID(디바이스)를 표기할 수 있으며
 *  - IKEv2 서버 관리페이지(vpn_users.php)가 이 테이블을 직접 조회해
 *    무료/유료 계정의 상호 연관을 표시할 수 있다.
 */

if (!defined('_GNUBOARD_')) {
    // gnuboard 외부에서 단독 실행 방지 (include 전용)
    if (!function_exists('sql_query')) {
        return;
    }
}

if (!function_exists('vpnlink_devmap_create_table')) {
    function vpnlink_devmap_create_table()
    {
        static $created = false;
        if ($created) {
            return;
        }
        $created = true;

        if (!function_exists('sql_query')) {
            return;
        }

        $sql = "CREATE TABLE IF NOT EXISTS `app_ikev2_device_member_map` (
            `device_id` varchar(64) NOT NULL,
            `mb_id` varchar(64) NOT NULL,
            `mb_name` varchar(128) NOT NULL DEFAULT '',
            `first_linked_at` datetime NOT NULL,
            `last_linked_at` datetime NOT NULL,
            PRIMARY KEY (`device_id`,`mb_id`),
            KEY `idx_devmap_mb_id` (`mb_id`,`last_linked_at`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";

        sql_query($sql, false);
    }
}

if (!function_exists('vpnlink_devmap_escape')) {
    function vpnlink_devmap_escape($value)
    {
        $value = (string)$value;
        if (function_exists('sql_real_escape_string')) {
            return sql_real_escape_string($value);
        }
        if (function_exists('sql_escape_string')) {
            return sql_escape_string($value);
        }
        return addslashes($value);
    }
}

if (!function_exists('vpnlink_devmap_normalize_device_id')) {
    /**
     * 앱이 보낸 device_vpn_id 정규화.
     * 'VpNgueSt' prefix가 붙어 있으면 제거하고, 디바이스 해시 형식만 허용한다.
     * 정상 형식이 아니면 '' 반환.
     */
    function vpnlink_devmap_normalize_device_id($raw)
    {
        $raw = trim((string)$raw);
        if ($raw === '') {
            return '';
        }
        if (strpos($raw, 'VpNgueSt') === 0) {
            $raw = substr($raw, 8);
        }
        if (!preg_match('/^[A-Za-z0-9]{8,64}$/', $raw)) {
            return '';
        }
        return strtolower($raw);
    }
}

if (!function_exists('vpnlink_devmap_upsert')) {
    /**
     * 디바이스↔회원 매핑 저장/갱신 (회원 인증된 요청 경로에서만 호출할 것)
     */
    function vpnlink_devmap_upsert($deviceIdRaw, $mbId, $mbName = '')
    {
        if (!function_exists('sql_query')) {
            return false;
        }

        $deviceId = vpnlink_devmap_normalize_device_id($deviceIdRaw);
        $mbId = trim((string)$mbId);
        $mbName = trim((string)$mbName);

        if ($deviceId === '' || $mbId === '') {
            return false;
        }
        // 게스트 계정 자체(mb_id가 디바이스 해시)는 매핑 대상이 아님
        if (strtolower($mbId) === $deviceId || strpos($mbId, 'VpNgueSt') === 0) {
            return false;
        }

        vpnlink_devmap_create_table();

        $safeDevice = vpnlink_devmap_escape($deviceId);
        $safeMbId = vpnlink_devmap_escape($mbId);
        $safeMbName = vpnlink_devmap_escape($mbName);

        $sql = "INSERT INTO `app_ikev2_device_member_map`
                    (`device_id`, `mb_id`, `mb_name`, `first_linked_at`, `last_linked_at`)
                VALUES ('{$safeDevice}', '{$safeMbId}', '{$safeMbName}', NOW(), NOW())
                ON DUPLICATE KEY UPDATE
                    `mb_name` = VALUES(`mb_name`),
                    `last_linked_at` = NOW()";

        sql_query($sql, false);
        return true;
    }
}

if (!function_exists('vpnlink_devmap_members_by_device')) {
    /**
     * 디바이스ID(=무료VPN ID)로 연관 회원 목록 조회 (최근 연결 순)
     * @return array [ ['mb_id'=>..., 'mb_name'=>...], ... ]
     */
    function vpnlink_devmap_members_by_device($deviceIdRaw, $limit = 3)
    {
        if (!function_exists('sql_query') || !function_exists('sql_fetch_array')) {
            return array();
        }

        $deviceId = vpnlink_devmap_normalize_device_id($deviceIdRaw);
        if ($deviceId === '') {
            return array();
        }

        $limit = max(1, min(10, (int)$limit));
        $safeDevice = vpnlink_devmap_escape($deviceId);

        $result = sql_query("SELECT mb_id, mb_name
                               FROM `app_ikev2_device_member_map`
                              WHERE device_id = '{$safeDevice}'
                           ORDER BY last_linked_at DESC
                              LIMIT {$limit}", false);

        $rows = array();
        if ($result) {
            while ($row = sql_fetch_array($result)) {
                if (!empty($row['mb_id'])) {
                    $rows[] = array(
                        'mb_id' => (string)$row['mb_id'],
                        'mb_name' => isset($row['mb_name']) ? (string)$row['mb_name'] : ''
                    );
                }
            }
        }
        return $rows;
    }
}

if (!function_exists('vpnlink_devmap_devices_by_member')) {
    /**
     * 회원ID로 연관 디바이스(=무료VPN ID) 목록 조회 (최근 연결 순)
     * @return array [ 'deviceid1', 'deviceid2', ... ]
     */
    function vpnlink_devmap_devices_by_member($mbId, $limit = 3)
    {
        if (!function_exists('sql_query') || !function_exists('sql_fetch_array')) {
            return array();
        }

        $mbId = trim((string)$mbId);
        if ($mbId === '') {
            return array();
        }

        $limit = max(1, min(10, (int)$limit));
        $safeMbId = vpnlink_devmap_escape($mbId);

        $result = sql_query("SELECT device_id
                               FROM `app_ikev2_device_member_map`
                              WHERE mb_id = '{$safeMbId}'
                           ORDER BY last_linked_at DESC
                              LIMIT {$limit}", false);

        $rows = array();
        if ($result) {
            while ($row = sql_fetch_array($result)) {
                if (!empty($row['device_id'])) {
                    $rows[] = (string)$row['device_id'];
                }
            }
        }
        return $rows;
    }
}

if (!function_exists('vpnlink_devmap_member_memo_suffix')) {
    /**
     * 무료VPN memo 뒤에 붙일 연관회원 표기 문자열 생성.
     * 예: ' Œ 연관회원:강호철(licoancer_1217)'
     */
    function vpnlink_devmap_member_memo_suffix($deviceIdRaw)
    {
        $members = vpnlink_devmap_members_by_device($deviceIdRaw, 2);
        if (empty($members)) {
            return '';
        }

        $parts = array();
        foreach ($members as $m) {
            $mbId = trim((string)$m['mb_id']);
            $mbName = trim((string)$m['mb_name']);
            if ($mbId === '') {
                continue;
            }
            $parts[] = ($mbName !== '') ? ($mbName . '(' . $mbId . ')') : $mbId;
        }
        if (empty($parts)) {
            return '';
        }
        return ' Œ 연관회원:' . implode(',', $parts);
    }
}
