<?php
/**
 * 네이티브 앱 포인트 충전 API (무통장 입금 방식)
 * Actions: get_info, request_charge
 */
include_once('./_common.php');

header('Content-Type: application/json; charset=UTF-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('X-Content-Type-Options: nosniff');

define('SNPC_RATE_LIMIT_WINDOW', 60);
define('SNPC_MAX_REQUESTS_PER_WINDOW', 20);

// fx_data 테이블에서 최신 환율 조회 (1 Point=1 KRW 기준)
function snpc_get_fx_rates() {
    $code_map = array(
        'KRW' => 'KRWKRW', 'CNY' => 'KRWCNY', 'USD' => 'KRWUSD',
        'EUR' => 'KRWEUR', 'JPY' => 'KRWJPY', 'VND' => 'KRWVND',
    );
    $fallback = array(
        'KRW' => 1.0, 'CNY' => 0.0045, 'USD' => 0.00066,
        'EUR' => 0.00057, 'JPY' => 0.105, 'VND' => 17.1,
    );
    $rates     = array();
    $updated_at = '';
    foreach ($code_map as $cur => $fx_type) {
        $safe = snpc_escape($fx_type);
        $row  = sql_fetch(
            "SELECT fx_rate, datetime FROM fx_data
             WHERE fx_type='{$safe}' ORDER BY time_last_update_unix DESC LIMIT 1",
            false
        );
        if ($row && (float)$row['fx_rate'] > 0) {
            $rates[$cur] = (float)$row['fx_rate'];
            if (!$updated_at || $row['datetime'] > $updated_at) $updated_at = $row['datetime'];
        } else {
            $rates[$cur] = $fallback[$cur];
        }
    }
    return array('rates' => $rates, 'updated_at' => $updated_at);
}

function snpc_req($key, $default = '')
{
    return isset($_POST[$key]) ? trim((string)$_POST[$key]) : $default;
}

function snpc_out($arr)
{
    echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function snpc_fail($code, $message)
{
    snpc_out(array('result' => 'fail', 'code' => $code, 'message' => $message));
}

function snpc_escape($value)
{
    global $db;
    if (function_exists('sql_real_escape_string')) {
        return sql_real_escape_string($value);
    }
    return mysqli_real_escape_string($db, $value);
}

function snpc_to_int($value, $default = 0)
{
    $v = preg_replace('/[^0-9\-]/', '', (string)$value);
    return ($v === '' || $v === '-') ? $default : (int)$v;
}

/* 1회/1일/1월/1년 한도를 날짜 기준으로 초기화 후 최신 정보 반환 */
function snpc_reset_and_fetch_limits($mb_id)
{
    global $g5;
    $safe = snpc_escape($mb_id);
    $now  = date('Y-m-d H:i:s');
    $today = date('Y-m-d');

    $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe}' LIMIT 1", false);
    if (!$row) {
        return null;
    }
    $last = isset($row['point_limit_charge_used_last_date']) ? $row['point_limit_charge_used_last_date'] : '';
    $flag = false;
    $sets = array();

    if (!$last || date('Y', strtotime($last)) < date('Y', strtotime($today))) {
        $sets[] = "point_limit_charge_1year_used=0, point_limit_charge_1month_used=0, point_limit_charge_1day_used=0, point_limit_charge_1try_used=0";
        $flag = true;
    } elseif (date('Ym', strtotime($last)) < date('Ym', strtotime($today))) {
        $sets[] = "point_limit_charge_1month_used=0, point_limit_charge_1day_used=0, point_limit_charge_1try_used=0";
        $flag = true;
    } elseif (date('Ymd', strtotime($last)) < date('Ymd', strtotime($today))) {
        $sets[] = "point_limit_charge_1day_used=0, point_limit_charge_1try_used=0";
        $flag = true;
    }

    if ($flag) {
        $set_str = implode(', ', $sets);
        sql_query("UPDATE {$g5['member_table']} SET {$set_str}, point_limit_charge_used_last_date='{$now}' WHERE mb_id='{$safe}'", false);
        $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe}' LIMIT 1", false);
    }
    return $row;
}

/* 인증: mb_id + mb_password 검증 */
function snpc_authenticate($mb_id, $mb_password)
{
    if ($mb_id === '' || $mb_password === '') {
        return null;
    }
    // 이메일 형식이면 email로 검색
    if (filter_var($mb_id, FILTER_VALIDATE_EMAIL)) {
        $safe = snpc_escape($mb_id);
        $mb = sql_fetch("SELECT * FROM {$GLOBALS['g5']['member_table']} WHERE mb_email='{$safe}' LIMIT 1", false);
        if (!isset($mb['mb_id']) || !$mb['mb_id']) {
            $mb = get_member($mb_id);
        }
    } else {
        $mb = get_member($mb_id);
    }
    if (!isset($mb['mb_id']) || !$mb['mb_id']) {
        return null;
    }
    if (!function_exists('login_password_check') || !login_password_check($mb, $mb_password, $mb['mb_password'])) {
        return null;
    }
    if ($mb['mb_intercept_date'] && $mb['mb_intercept_date'] <= date('Ymd', G5_SERVER_TIME)) {
        return null;
    }
    if ($mb['mb_leave_date'] && $mb['mb_leave_date'] <= date('Ymd', G5_SERVER_TIME)) {
        return null;
    }
    return $mb;
}

/* 무통장 계좌 정보 파싱 — 통화별 */
function snpc_get_currency_accounts()
{
    global $default;
    $codes = array("KRW", "CNY", "USD", "EUR", "JPY", "VND");
    $result = array();
    foreach ($codes as $c) $result[$c] = array();
    $fallback = array();
    if (!isset($default["de_bank_account"]) || !$default["de_bank_account"]) return $result;
    $lines = explode("\n", trim($default["de_bank_account"]));
    foreach ($lines as $line) {
        $line = trim($line);
        if ($line === "") continue;
        $matched = false;
        foreach ($codes as $c) {
            if (stripos($line, "[" . $c . "]") !== false) {
                $result[$c][] = $line;
                $matched = true;
                break;
            }
        }
        if (!$matched) $fallback[] = $line;
    }
    if (empty($result["KRW"]) && !empty($fallback)) $result["KRW"] = $fallback;
    return $result;
}

/* 무통장 계좌 정보 파싱 */
function snpc_get_bank_accounts()
{
    global $default;
    $accounts = array();
    if (!isset($default['de_bank_account']) || !$default['de_bank_account']) {
        return $accounts;
    }
    $lines = explode("\n", trim($default['de_bank_account']));
    foreach ($lines as $line) {
        $line = trim($line);
        if ($line !== '') {
            $accounts[] = $line;
        }
    }
    return $accounts;
}

// ─────────────────────────────────────────────
// 요청 파라미터 수신
// ─────────────────────────────────────────────
$action      = snpc_req('action', 'get_info');
$mb_id_raw   = snpc_req('mb_id', snpc_req('username', ''));
$mb_password = snpc_req('mb_password', snpc_req('password', ''));

// 게스트 계정 차단
if (substr($mb_id_raw, 0, 8) === 'VpNgueSt') {
    snpc_fail('guest_not_allowed', '게스트 계정은 포인트 충전을 사용할 수 없습니다.');
}

// ─────────────────────────────────────────────
// 인증
// ─────────────────────────────────────────────
$mb = snpc_authenticate($mb_id_raw, $mb_password);
if (!$mb) {
    snpc_fail('auth_fail', '아이디 또는 비밀번호가 올바르지 않습니다.');
}
$mb_id = $mb['mb_id'];

// ─────────────────────────────────────────────
// action: get_info
// ─────────────────────────────────────────────
if ($action === 'get_info') {
    $row = snpc_reset_and_fetch_limits($mb_id);
    if (!$row) {
        snpc_fail('member_not_found', '회원 정보를 찾을 수 없습니다.');
    }

    $limit_try   = max(0, (int)$row['point_limit_charge_1try']);
    $limit_day   = max(0, (int)$row['point_limit_charge_1day']);
    $limit_month = max(0, (int)$row['point_limit_charge_1month']);
    $limit_year  = max(0, (int)$row['point_limit_charge_1year']);
    $used_try    = max(0, (int)$row['point_limit_charge_1try_used']);
    $used_day    = max(0, (int)$row['point_limit_charge_1day_used']);
    $used_month  = max(0, (int)$row['point_limit_charge_1month_used']);
    $used_year   = max(0, (int)$row['point_limit_charge_1year_used']);

    $fx_info      = snpc_get_fx_rates();
    $bank_accounts = snpc_get_bank_accounts();
    $company_name  = isset($default['de_admin_company_name']) ? trim($default['de_admin_company_name']) : '';

    snpc_out(array(
        'result'          => 'success',
        'mb_id'           => $mb_id,
        'mb_nick'         => $mb['mb_nick'],
        'mb_point'        => (int)$mb['mb_point'],
        'limit_try'       => $limit_try,
        'limit_day'       => $limit_day,
        'limit_month'     => $limit_month,
        'limit_year'      => $limit_year,
        'remain_try'      => max(0, $limit_try - $used_try),
        'remain_day'      => max(0, $limit_day - $used_day),
        'remain_month'    => max(0, $limit_month - $used_month),
        'remain_year'     => max(0, $limit_year - $used_year),
        'bank_accounts'   => $bank_accounts,
        'company_name'    => $company_name,
        'currency_accounts' => snpc_get_currency_accounts(),
        'fx_rates'          => $fx_info['rates'],
        'fx_rates_updated_at' => $fx_info['updated_at'],
    ));
}

// ─────────────────────────────────────────────
// action: request_charge
// ─────────────────────────────────────────────
if ($action === 'request_charge') {
    $amount = snpc_to_int(snpc_req('amount', '0'));
    $currency = strtoupper(preg_replace("/[^A-Za-z]/", "", snpc_req("currency", "KRW")));
    if (!in_array($currency, array("KRW","CNY","USD","EUR","JPY","VND"))) $currency = "KRW";

    if ($amount <= 0) {
        snpc_fail('invalid_amount', '충전 금액을 올바르게 입력해 주세요.');
    }
    if ($amount < 1000) {
        snpc_fail('amount_too_small', '최소 충전 금액은 1,000 포인트입니다.');
    }

    // 한도 초기화 및 재조회 (트랜잭션 내에서 FOR UPDATE로 잠금)
    sql_query("BEGIN", false);

    $safe_mb = snpc_escape($mb_id);
    $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe_mb}' LIMIT 1 FOR UPDATE", false);
    if (!$row) {
        sql_query("ROLLBACK", false);
        snpc_fail('member_not_found', '회원 정보를 찾을 수 없습니다.');
    }

    // 한도 날짜 기준 초기화
    $now   = date('Y-m-d H:i:s');
    $today = date('Y-m-d');
    $last  = isset($row['point_limit_charge_used_last_date']) ? $row['point_limit_charge_used_last_date'] : '';
    if (!$last || date('Y', strtotime($last)) < date('Y', strtotime($today))) {
        sql_query("UPDATE {$g5['member_table']} SET point_limit_charge_1year_used=0, point_limit_charge_1month_used=0, point_limit_charge_1day_used=0, point_limit_charge_1try_used=0, point_limit_charge_used_last_date='{$now}' WHERE mb_id='{$safe_mb}'", false);
        $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe_mb}' LIMIT 1 FOR UPDATE", false);
    } elseif (date('Ym', strtotime($last)) < date('Ym', strtotime($today))) {
        sql_query("UPDATE {$g5['member_table']} SET point_limit_charge_1month_used=0, point_limit_charge_1day_used=0, point_limit_charge_1try_used=0, point_limit_charge_used_last_date='{$now}' WHERE mb_id='{$safe_mb}'", false);
        $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe_mb}' LIMIT 1 FOR UPDATE", false);
    } elseif (date('Ymd', strtotime($last)) < date('Ymd', strtotime($today))) {
        sql_query("UPDATE {$g5['member_table']} SET point_limit_charge_1day_used=0, point_limit_charge_1try_used=0, point_limit_charge_used_last_date='{$now}' WHERE mb_id='{$safe_mb}'", false);
        $row = sql_fetch("SELECT * FROM {$g5['member_table']} WHERE mb_id='{$safe_mb}' LIMIT 1 FOR UPDATE", false);
    }

    $limit_try   = max(0, (int)$row['point_limit_charge_1try']);
    $limit_day   = max(0, (int)$row['point_limit_charge_1day']);
    $limit_month = max(0, (int)$row['point_limit_charge_1month']);
    $limit_year  = max(0, (int)$row['point_limit_charge_1year']);
    $used_try    = max(0, (int)$row['point_limit_charge_1try_used']);
    $used_day    = max(0, (int)$row['point_limit_charge_1day_used']);
    $used_month  = max(0, (int)$row['point_limit_charge_1month_used']);
    $used_year   = max(0, (int)$row['point_limit_charge_1year_used']);

    $remain_try   = $limit_try - $used_try;
    $remain_day   = $limit_day - $used_day;
    $remain_month = $limit_month - $used_month;
    $remain_year  = $limit_year - $used_year;

    if ($limit_try > 0 && $amount > $remain_try) {
        sql_query("ROLLBACK", false);
        snpc_fail('limit_exceeded_try', "1회 충전 잔여한도(" . number_format($remain_try) . " P)를 초과하였습니다.");
    }
    if ($limit_day > 0 && $amount > $remain_day) {
        sql_query("ROLLBACK", false);
        snpc_fail('limit_exceeded_day', "1일 충전 잔여한도(" . number_format($remain_day) . " P)를 초과하였습니다.");
    }
    if ($limit_month > 0 && $amount > $remain_month) {
        sql_query("ROLLBACK", false);
        snpc_fail('limit_exceeded_month', "1개월 충전 잔여한도(" . number_format($remain_month) . " P)를 초과하였습니다.");
    }
    if ($limit_year > 0 && $amount > $remain_year) {
        sql_query("ROLLBACK", false);
        snpc_fail('limit_exceeded_year', "1년 충전 잔여한도(" . number_format($remain_year) . " P)를 초과하였습니다.");
    }

    $safe_currency = snpc_escape($currency);
    // 주문번호 생성
    list($microseconds, $seconds) = explode(" ", microtime());
    $microseconds = str_pad((int)($microseconds * 1000), 3, '0', STR_PAD_LEFT);
    $od_id = get_uniqid() . $microseconds;

    $od_name_raw    = trim($mb['mb_name']);
    $od_name        = snpc_escape($od_name_raw);
    $od_deposit_name_raw = substr($od_id, -4) . $od_name_raw;
    $od_deposit_safe     = snpc_escape($od_deposit_name_raw);
    $od_email    = snpc_escape(trim($mb['mb_email']));
    $od_hp       = snpc_escape(trim($mb['mb_hp']));
    $remote_ip   = snpc_escape(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '');
    $od_id_safe  = snpc_escape($od_id);

    // 환율 조회 및 외화 금액 계산
    $_fx_info = snpc_get_fx_rates();
    $od_fx_rate_val   = isset($_fx_info['rates'][$currency]) ? $_fx_info['rates'][$currency] : 1.0;
    $od_fx_amount_val = ($currency !== 'KRW') ? round($amount * $od_fx_rate_val, 2) : (float)$amount;

    // g5_shoppoint_order 에 주문 생성 (무통장, 상태: '주문')
    $insert_sql = "INSERT INTO g5_shoppoint_order SET
        od_id            = '{$od_id_safe}',
        mb_id            = '{$safe_mb}',
        od_pwd           = '{$mb['mb_password']}',
        od_name          = '{$od_name}',
        od_email         = '{$od_email}',
        od_tel           = '',
        od_hp            = '{$od_hp}',
        od_zip1          = '',
        od_zip2          = '',
        od_addr1         = '',
        od_addr2         = '',
        od_addr3         = '',
        od_addr_jibeon   = '',
        od_b_name        = '',
        od_b_tel         = '',
        od_b_hp          = '',
        od_b_zip1        = '',
        od_b_zip2        = '',
        od_b_addr1       = '',
        od_b_addr2       = '',
        od_b_addr3       = '',
        od_b_addr_jibeon = '',
        od_deposit_name  = '{$od_deposit_safe}',
        od_memo          = '네이티브앱 포인트충전',
        od_cart_count    = 1,
        od_cart_price    = {$amount},
        od_cart_coupon   = 0,
        od_send_cost     = 0,
        od_send_coupon   = 0,
        od_send_cost2    = 0,
        od_coupon        = 0,
        od_receipt_price = 0,
        od_receipt_point = 0,
        od_bank_account  = '',
        od_receipt_time  = '',
        od_misu          = {$amount},
        od_pg            = 'native',
        od_tno           = '',
        od_app_no        = '',
        od_escrow        = 0,
        od_tax_flag      = 0,
        od_tax_mny       = 0,
        od_vat_mny       = 0,
        od_free_mny      = 0,
        od_status        = '주문',
        od_shop_memo     = '',
        od_hope_date     = '',
        od_time          = '" . G5_TIME_YMDHIS . "',
        od_ip            = '{$remote_ip}',
        od_settle_case   = '무통장',
        od_test          = '0',
        od_sns_name      = '',
        od_sns_id        = '',
        od_hp_nation     = '',
        od_fx_type       = 'KRW{$safe_currency}',
        od_fx_rate       = {$od_fx_rate_val},
        od_fx_amount     = {$od_fx_amount_val}";

    $result = sql_query($insert_sql, false);
    if (!$result) {
        sql_query("ROLLBACK", false);
        snpc_fail('db_error', '주문 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.');
    }

    // 한도 사용량 업데이트
    $new_used_try   = $used_try + $amount;
    $new_used_day   = $used_day + $amount;
    $new_used_month = $used_month + $amount;
    $new_used_year  = $used_year + $amount;

    $update_result = sql_query("UPDATE {$g5['member_table']} SET
        point_limit_charge_1try_used   = {$new_used_try},
        point_limit_charge_1day_used   = {$new_used_day},
        point_limit_charge_1month_used = {$new_used_month},
        point_limit_charge_1year_used  = {$new_used_year},
        point_limit_charge_used_last_date = '{$now}'
        WHERE mb_id='{$safe_mb}'", false);

    if (!$update_result) {
        sql_query("ROLLBACK", false);
        snpc_fail('db_error', '한도 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.');
    }

    sql_query("COMMIT", false);

    $all_curr = snpc_get_currency_accounts();
    $bank_accounts = (isset($all_curr[$currency]) && !empty($all_curr[$currency])) ? $all_curr[$currency] : snpc_get_bank_accounts();
    $company_name  = isset($default['de_admin_company_name']) ? trim($default['de_admin_company_name']) : '';

    $expire_time = date('Y-m-d H:i:s', strtotime(G5_TIME_YMDHIS) + 3 * 3600);
    snpc_out(array(
        'result'        => 'success',
        'order_id'      => $od_id,
        'expire_time'   => $expire_time,
        'deposit_name'  => $od_deposit_name_raw,
        'amount'        => $amount,
        'mb_nick'       => $mb['mb_nick'],
        'bank_accounts' => $bank_accounts,
        currency      => $currency,
        'company_name'  => $company_name,
        currency_accounts => snpc_get_currency_accounts(),
        'message'       => '포인트 충전 신청이 완료되었습니다. 아래 계좌로 입금하시면 관리자 확인 후 포인트가 충전됩니다.',
    ));
}

snpc_fail('unknown_action', '알 수 없는 요청입니다.');
