<?php
include_once('./_common.php');
include_once(G5_PATH . '/mylib/ikev2_provision.lib.php');

if (!function_exists('oi_hist_norm_dt')) {
    function oi_hist_norm_dt($dt)
    {
        $dt = trim((string)$dt);
        if ($dt === '' || $dt === '0000-00-00 00:00:00') {
            return '';
        }
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $dt)) {
            return $dt;
        }

        $ts = strtotime($dt);
        if ($ts === false || $ts <= 0) {
            return '';
        }
        return date('Y-m-d H:i:s', $ts);
    }
}

if (!function_exists('oi_hist_build_row')) {
    function oi_hist_build_row($source, $createdAt, $eventType, $eventStatus, $httpCode, $protocol, $serverIp, $vpnUserId, $nextRetryAt, $errorMessage, $responseBody, $rawId)
    {
        return array(
            'history_id' => (string)$rawId,
            'source' => (string)$source,
            'created_at' => (string)$createdAt,
            'event_type' => (string)$eventType,
            'event_status' => (string)$eventStatus,
            'http_code' => ($httpCode === null || $httpCode === '') ? null : (int)$httpCode,
            'protocol' => (string)$protocol,
            'server_ip' => (string)$serverIp,
            'vpn_user_id' => (string)$vpnUserId,
            'next_retry_at' => (string)$nextRetryAt,
            'error_message' => (string)$errorMessage,
            'response_body' => (string)$responseBody
        );
    }
}

if (!function_exists('oi_hist_split_lines')) {
    function oi_hist_split_lines($text)
    {
        $text = trim((string)$text);
        if ($text === '') {
            return array();
        }

        $parts = preg_split('/\r\n|\n|\r/', $text);
        $out = array();
        foreach ((array)$parts as $p) {
            $p = trim((string)$p);
            if ($p !== '') {
                $out[] = $p;
            }
        }

        if (count($out) < 1) {
            $out[] = $text;
        }

        return $out;
    }
}

if (!isset($member['mb_id']) || $member['mb_id'] === '' || !isset($is_admin) || !$is_admin) {
    http_response_code(403);
    echo json_encode(array('ok' => false, 'error' => 'admin_only'));
    exit;
}

vpnlink_ikev2_create_tables();

$itId = isset($_GET['it_id']) ? trim((string)$_GET['it_id']) : '';
$odId = isset($_GET['od_id']) ? trim((string)$_GET['od_id']) : '';
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 200;

if ($limit < 1) $limit = 1;
if ($limit > 1000) $limit = 1000;

$where = ' WHERE 1=1 ';
if ($itId !== '') {
    $where .= " AND h.it_id = '" . sql_escape_string($itId) . "' ";
}
if ($odId !== '') {
    $where .= " AND h.od_id = '" . sql_escape_string($odId) . "' ";
}

$timeline = array();

// 1) Provisioning history
$sql = "SELECT h.history_id, h.queue_id, h.od_id, h.it_id, h.event_type, h.attempt_no, h.event_status,
               h.http_code, h.error_message, h.response_body, h.next_retry_at, h.created_at,
               q.protocol, q.server_ip, q.vpn_user_id
          FROM app_ikev2_provision_history h
          LEFT JOIN app_ikev2_provision_queue q ON h.queue_id = q.queue_id
        {$where}
         ORDER BY h.history_id DESC
         LIMIT {$limit}";

$res = sql_query($sql, false);
for ($i = 0; $row = sql_fetch_array($res); $i++) {
    $timeline[] = oi_hist_build_row(
        'provision',
        isset($row['created_at']) ? $row['created_at'] : '',
        isset($row['event_type']) ? $row['event_type'] : '',
        isset($row['event_status']) ? $row['event_status'] : '',
        isset($row['http_code']) ? $row['http_code'] : null,
        isset($row['protocol']) ? $row['protocol'] : '',
        isset($row['server_ip']) ? $row['server_ip'] : '',
        isset($row['vpn_user_id']) ? $row['vpn_user_id'] : '',
        isset($row['next_retry_at']) ? $row['next_retry_at'] : '',
        isset($row['error_message']) ? $row['error_message'] : '',
        isset($row['response_body']) ? $row['response_body'] : '',
        'p:' . (isset($row['history_id']) ? $row['history_id'] : '0')
    );
}

if ($odId !== '') {
    // 2) Order-level change history from od_mod_history + key timestamps
    $orderSql = "SELECT od_id, od_status, od_time, od_receipt_time, od_mod_history
                   FROM {$g5['g5_shop_order_table']}
                  WHERE od_id = '" . sql_escape_string($odId) . "'
                  LIMIT 1";
    $order = sql_fetch($orderSql);
    if ($order && isset($order['od_id'])) {
        $orderBaseMsg = '주문상태: ' . trim((string)$order['od_status']);

        $odTime = oi_hist_norm_dt(isset($order['od_time']) ? $order['od_time'] : '');
        if ($odTime !== '') {
            $timeline[] = oi_hist_build_row('order', $odTime, 'order_created', isset($order['od_status']) ? $order['od_status'] : '', null, '', '', '', '', $orderBaseMsg, '', 'o:created:' . $odId);
        }

        $rcptTime = oi_hist_norm_dt(isset($order['od_receipt_time']) ? $order['od_receipt_time'] : '');
        if ($rcptTime !== '' && $rcptTime !== $odTime) {
            $timeline[] = oi_hist_build_row('order', $rcptTime, 'order_receipt', '입금', null, '', '', '', '', '주문 결제/입금 시각', '', 'o:receipt:' . $odId);
        }

        $modHistoryLines = oi_hist_split_lines(isset($order['od_mod_history']) ? $order['od_mod_history'] : '');
        foreach ($modHistoryLines as $idx => $line) {
            $created = '';
            $msg = $line;
            if (preg_match('/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s*(.*)$/', $line, $m)) {
                $created = oi_hist_norm_dt($m[1]);
                $msg = trim((string)$m[2]);
            }
            if ($created === '') {
                $created = $odTime !== '' ? $odTime : date('Y-m-d H:i:s');
            }

            $timeline[] = oi_hist_build_row(
                'order',
                $created,
                'order_mod_history',
                isset($order['od_status']) ? $order['od_status'] : '',
                null,
                '',
                '',
                '',
                '',
                ($msg !== '' ? $msg : $line),
                $line,
                'o:mod:' . $odId . ':' . $idx
            );
        }
    }

    // 3) Item/cart level change history from ct_history
    $cartWhere = " WHERE od_id = '" . sql_escape_string($odId) . "' ";
    if ($itId !== '') {
        $cartWhere .= " AND it_id = '" . sql_escape_string($itId) . "' ";
    }

    $cartSql = "SELECT ct_id, od_id, it_id, ct_status, ct_history, ct_time
                  FROM {$g5['g5_shop_cart_table']}
                {$cartWhere}
                 ORDER BY ct_id DESC
                 LIMIT {$limit}";
    $cartRes = sql_query($cartSql, false);
    for ($i = 0; $ct = sql_fetch_array($cartRes); $i++) {
        $ctId = isset($ct['ct_id']) ? (int)$ct['ct_id'] : 0;
        $ctLines = oi_hist_split_lines(isset($ct['ct_history']) ? $ct['ct_history'] : '');

        if (count($ctLines) < 1) {
            $ctTime = oi_hist_norm_dt(isset($ct['ct_time']) ? $ct['ct_time'] : '');
            if ($ctTime !== '') {
                $timeline[] = oi_hist_build_row(
                    'cart',
                    $ctTime,
                    'cart_status',
                    isset($ct['ct_status']) ? $ct['ct_status'] : '',
                    null,
                    '',
                    '',
                    '',
                    '',
                    'ct_id=' . $ctId . ', it_id=' . (isset($ct['it_id']) ? $ct['it_id'] : ''),
                    '',
                    'c:' . $ctId . ':base'
                );
            }
            continue;
        }

        foreach ($ctLines as $j => $line) {
            $parts = explode('|', $line);
            $st = isset($parts[0]) ? trim((string)$parts[0]) : '';
            $actor = isset($parts[1]) ? trim((string)$parts[1]) : '';
            $dt = isset($parts[2]) ? oi_hist_norm_dt($parts[2]) : '';
            $memo = isset($parts[3]) ? trim((string)$parts[3]) : '';

            if ($dt === '') {
                $dt = oi_hist_norm_dt(isset($ct['ct_time']) ? $ct['ct_time'] : '');
            }
            if ($dt === '') {
                $dt = date('Y-m-d H:i:s');
            }

            $msg = 'ct_id=' . $ctId
                 . ', it_id=' . (isset($ct['it_id']) ? $ct['it_id'] : '')
                 . ($actor !== '' ? ', actor=' . $actor : '')
                 . ($memo !== '' ? ', memo=' . $memo : '');

            $timeline[] = oi_hist_build_row(
                'cart',
                $dt,
                'cart_history',
                ($st !== '' ? $st : (isset($ct['ct_status']) ? $ct['ct_status'] : '')),
                null,
                '',
                '',
                '',
                '',
                $msg,
                $line,
                'c:' . $ctId . ':' . $j
            );
        }
    }

    // 4) Point in/out history tied to this order
    $pointCond = array();
    $pointCond[] = "(po_rel_action like '" . sql_escape_string($odId) . "%')";
    $pointCond[] = "(po_rel_id = '" . sql_escape_string($odId) . "')";
    $pointCond[] = "(po_content like '%주문번호 " . sql_escape_string($odId) . "%')";
    if ($itId !== '') {
        $pointCond[] = "(po_rel_action like '" . sql_escape_string($odId . '|' . $itId) . "%')";
        $pointCond[] = "(po_content like '%상품명 RPC-" . sql_escape_string($itId) . "%')";
    }

    $pointSql = "SELECT po_id, mb_id, po_datetime, po_point, po_content, po_rel_table, po_rel_id, po_rel_action
                   FROM {$g5['point_table']}
                  WHERE " . implode(' OR ', $pointCond) . "
                  ORDER BY po_id DESC
                  LIMIT {$limit}";
    $pointRes = sql_query($pointSql, false);
    for ($i = 0; $po = sql_fetch_array($pointRes); $i++) {
        $poId = isset($po['po_id']) ? (int)$po['po_id'] : 0;
        $poDt = oi_hist_norm_dt(isset($po['po_datetime']) ? $po['po_datetime'] : '');
        if ($poDt === '') {
            $poDt = date('Y-m-d H:i:s');
        }

        $poPoint = isset($po['po_point']) ? (int)$po['po_point'] : 0;
        $poStatus = ($poPoint >= 0) ? 'point_plus' : 'point_minus';
        $poMsg = '포인트 ' . (($poPoint >= 0) ? '+' : '') . number_format($poPoint) . ' / ' . (isset($po['po_content']) ? (string)$po['po_content'] : '');
        $poBody = 'mb_id=' . (isset($po['mb_id']) ? (string)$po['mb_id'] : '')
                . ', rel_table=' . (isset($po['po_rel_table']) ? (string)$po['po_rel_table'] : '')
                . ', rel_id=' . (isset($po['po_rel_id']) ? (string)$po['po_rel_id'] : '')
                . ', rel_action=' . (isset($po['po_rel_action']) ? (string)$po['po_rel_action'] : '');

        $timeline[] = oi_hist_build_row(
            'point',
            $poDt,
            'point_change',
            $poStatus,
            null,
            '',
            '',
            '',
            '',
            $poMsg,
            $poBody,
            'po:' . $poId
        );
    }
}

usort($timeline, function($a, $b) {
    $ta = strtotime((string)(isset($a['created_at']) ? $a['created_at'] : ''));
    $tb = strtotime((string)(isset($b['created_at']) ? $b['created_at'] : ''));

    if ($ta === $tb) {
        return strcmp((string)$b['history_id'], (string)$a['history_id']);
    }
    return ($tb <=> $ta);
});

if (count($timeline) > $limit) {
    $timeline = array_slice($timeline, 0, $limit);
}

echo json_encode(array(
    'ok' => true,
    'count' => count($timeline),
    'filters' => array('it_id' => $itId, 'od_id' => $odId, 'limit' => $limit),
    'history' => $timeline
), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
