<?php
/**
 * 바로빌 카드 API 설정 파일
 * 
 * ⚠️ 중요: 바로빌은 SOAP 웹서비스를 사용합니다 (REST API가 아님)
 * 
 * 카드 사용내역 조회를 위해서는 바로빌 웹사이트(https://www.barobill.co.kr)에서
 * 카드를 먼저 등록해야 합니다.
 * 
 * 설정 파일:
 * 1. apikey/barobill_cert_key.txt - CERTKEY (인증서 키)
 * 2. apikey/barobill_corp_num.txt - 사업자번호
 * 3. apikey/barobill_test_mode.txt - 테스트 모드 설정 (선택)
 */

// 인증서 키(CERTKEY) 파일 경로
// load .env file
require_once __DIR__ . '/../../lib/DotEnv.php';
(new DotEnv(__DIR__ . '/../../.env'))->load();

// 인증서 키(CERTKEY) 파일 경로
$documentRoot = getenv('DOCUMENT_ROOT');
$certKeyFile = $documentRoot . '/apikey/barobill_cert_key.txt';
$legacyApiKeyFile = $documentRoot . '/apikey/barobill_api_key.txt';
$corpNumFile = $documentRoot . '/apikey/barobill_corp_num.txt';
$testModeFile = $documentRoot . '/apikey/barobill_test_mode.txt';

// CERTKEY 읽기
$barobillCertKey = '';
if (file_exists($certKeyFile)) {
    $content = trim(file_get_contents($certKeyFile));
    // 설명 텍스트가 아닌 실제 키만 추출 (대괄호 안의 내용 제외, =로 시작하는 경우 제외)
    if (!empty($content) && !preg_match('/^\[여기에/', $content) && !preg_match('/^=/', $content) && strpos($content, '바로빌 CERTKEY') === false) {
        $barobillCertKey = $content;
    }
}
if (empty($barobillCertKey) && file_exists($legacyApiKeyFile)) {
    $barobillCertKey = trim(file_get_contents($legacyApiKeyFile));
}

// 사업자번호 읽기
$barobillCorpNum = '';
if (file_exists($corpNumFile)) {
    $content = trim(file_get_contents($corpNumFile));
    if (!empty($content) && !preg_match('/^\[여기에/', $content)) {
        $barobillCorpNum = str_replace('-', '', $content);
    }
}

// 테스트 모드 확인
$isTestMode = false;
if (file_exists($testModeFile)) {
    $testMode = trim(file_get_contents($testModeFile));
    $isTestMode = (strtolower($testMode) === 'test' || strtolower($testMode) === 'true');
}

// 바로빌 사용자 ID (카드 사용내역 조회에 필요)
// 빈 값이면 전체 카드 조회, 특정 사용자만 조회하려면 사용자 ID 입력
$barobillUserIdFile = getenv('DOCUMENT_ROOT') . '/apikey/barobill_user_id.txt';
$barobillUserId = '';
if (file_exists($barobillUserIdFile)) {
    $content = trim(file_get_contents($barobillUserIdFile));
    if (!empty($content) && !preg_match('/^\[여기에/', $content)) {
        $barobillUserId = $content;
    }
}

/**
 * 바로빌 사용자 ID 반환
 */
function getBarobillUserId() {
    global $barobillUserId;
    return $barobillUserId;
}

// 바로빌 카드 SOAP 웹서비스 URL
$barobillCardSoapUrl = $isTestMode 
    ? 'https://testws.baroservice.com/CARD.asmx?WSDL'  // 테스트 환경
    : 'https://ws.baroservice.com/CARD.asmx?WSDL';    // 운영 환경

// SOAP 클라이언트 초기화
$barobillCardSoapClient = null;
if (!empty($barobillCertKey) || $isTestMode) {
    try {
        $barobillCardSoapClient = new SoapClient($barobillCardSoapUrl, [
            'trace' => true,
            'encoding' => 'UTF-8',
            'exceptions' => true,
            'connection_timeout' => 30
        ]);
    } catch (Throwable $e) {
        error_log('바로빌 카드 SOAP 클라이언트 생성 실패: ' . $e->getMessage());
    }
}

/**
 * 바로빌 카드 SOAP 웹서비스 호출 함수
 * 
 * @param string $method SOAP 메서드명
 * @param array $params SOAP 메서드 파라미터
 * @return array 응답 데이터
 */
function callBarobillCardSOAP($method, $params = []) {
    global $barobillCardSoapClient, $barobillCertKey, $barobillCorpNum, $isTestMode;
    
    if (!$barobillCardSoapClient) {
        return [
            'success' => false,
            'error' => '바로빌 카드 SOAP 클라이언트가 초기화되지 않았습니다. CERTKEY를 확인하세요.',
            'error_detail' => [
                'cert_key_file' => getenv('DOCUMENT_ROOT') . '/apikey/barobill_cert_key.txt',
                'soap_url' => $isTestMode ? 'https://testws.baroservice.com/CARD.asmx?WSDL' : 'https://ws.baroservice.com/CARD.asmx?WSDL'
            ]
        ];
    }
    
    if (empty($barobillCertKey) && !$isTestMode) {
        return [
            'success' => false,
            'error' => 'CERTKEY가 설정되지 않았습니다. apikey/barobill_cert_key.txt 파일을 확인하세요.'
        ];
    }
    
    if (empty($barobillCorpNum)) {
        return [
            'success' => false,
            'error' => '사업자번호가 설정되지 않았습니다. apikey/barobill_corp_num.txt 파일을 확인하세요.'
        ];
    }
    
    // CERTKEY와 CorpNum 자동 추가
    if (!isset($params['CERTKEY'])) {
        $params['CERTKEY'] = $barobillCertKey;
    }
    if (!isset($params['CorpNum'])) {
        $params['CorpNum'] = $barobillCorpNum;
    }
    
    try {
        error_log('바로빌 카드 API 호출 - Method: ' . $method . ', CorpNum: ' . $barobillCorpNum);
        
        $result = $barobillCardSoapClient->$method($params);
        
        $resultProperty = $method . 'Result';
        if (isset($result->$resultProperty)) {
            $resultData = $result->$resultProperty;
            
            // 에러 코드 체크 (음수 값)
            if (is_numeric($resultData) && $resultData < 0) {
                return [
                    'success' => false,
                    'error' => '바로빌 카드 API 오류 코드: ' . $resultData,
                    'error_code' => $resultData
                ];
            }
            
            return [
                'success' => true,
                'data' => $resultData
            ];
        }
        
        return [
            'success' => true,
            'data' => $result
        ];
        
    } catch (SoapFault $e) {
        return [
            'success' => false,
            'error' => 'SOAP 오류: ' . $e->getMessage(),
            'error_code' => $e->getCode()
        ];
    } catch (Throwable $e) {
        return [
            'success' => false,
            'error' => 'API 호출 오류 (치명적): ' . $e->getMessage()
        ];
    }
}

/**
 * 등록된 카드 목록 조회 (GetCardEx2 API 사용)
 * API 레퍼런스: https://dev.barobill.co.kr/docs/references/카드조회-API#GetCardEx2
 * 
 * @param int $availOnly 0: 전체, 1: 사용가능한 카드만
 * @return array 카드 목록
 */
function getCardList($availOnly = 0) {
    $result = callBarobillCardSOAP('GetCardEx2', [
        'AvailOnly' => $availOnly
    ]);
    
    if (!$result['success']) {
        return $result;
    }
    
    $cards = [];
    $data = $result['data'];
    
    // GetCardEx2는 CardEx 배열을 반환
    if (!isset($data->CardEx)) {
        return ['success' => true, 'data' => []];
    }
    
    if (!is_array($data->CardEx)) {
        $cards = [$data->CardEx];
    } else {
        $cards = $data->CardEx;
    }
    
    // 에러 체크: CardNum이 음수면 에러 코드
    if (count($cards) == 1 && isset($cards[0]->CardNum) && $cards[0]->CardNum < 0) {
        return [
            'success' => false,
            'error' => '카드 목록 조회 실패',
            'error_code' => $cards[0]->CardNum
        ];
    }
    
    return ['success' => true, 'data' => $cards];
}

/**
 * 기간별 카드 사용내역 조회
 * 
 * @param string $cardNum 카드번호 (빈값이면 전체)
 * @param string $startDate 시작일 (YYYYMMDD)
 * @param string $endDate 종료일 (YYYYMMDD)
 * @param int $countPerPage 페이지당 건수
 * @param int $currentPage 현재 페이지
 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순)
 * @param string $userId 바로빌 사용자 ID (빈값이면 전체)
 * @return array 사용내역
 */
function getPeriodCardUsage($cardNum = '', $startDate = '', $endDate = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') {
    global $barobillCorpNum;
    
    // 바로빌 사용자 ID 파일에서 읽기 (없으면 빈값)
    $barobillUserId = getBarobillUserId();
    if (!empty($userId)) {
        $barobillUserId = $userId;
    }
    
    $result = callBarobillCardSOAP('GetPeriodCardApprovalLog', [
        'ID' => $barobillUserId,
        'CardNum' => $cardNum,
        'StartDate' => $startDate,
        'EndDate' => $endDate,
        'CountPerPage' => $countPerPage,
        'CurrentPage' => $currentPage,
        'OrderDirection' => $orderDirection
    ]);
    
    if (!$result['success']) {
        return $result;
    }
    
    return parseCardUsageResult($result['data']);
}

/**
 * 일별 카드 사용내역 조회
 * 
 * @param string $cardNum 카드번호 (빈값이면 전체)
 * @param string $baseDate 기준일 (YYYYMMDD)
 * @param int $countPerPage 페이지당 건수
 * @param int $currentPage 현재 페이지
 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순)
 * @param string $userId 바로빌 사용자 ID (빈값이면 전체)
 * @return array 사용내역
 */
function getDailyCardUsage($cardNum = '', $baseDate = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') {
    $barobillUserId = getBarobillUserId();
    if (!empty($userId)) {
        $barobillUserId = $userId;
    }
    
    $result = callBarobillCardSOAP('GetDailyCardApprovalLog', [
        'ID' => $barobillUserId,
        'CardNum' => $cardNum,
        'BaseDate' => $baseDate,
        'CountPerPage' => $countPerPage,
        'CurrentPage' => $currentPage,
        'OrderDirection' => $orderDirection
    ]);
    
    if (!$result['success']) {
        return $result;
    }
    
    return parseCardUsageResult($result['data']);
}

/**
 * 월별 카드 사용내역 조회
 * 
 * @param string $cardNum 카드번호 (빈값이면 전체)
 * @param string $baseMonth 기준월 (YYYYMM)
 * @param int $countPerPage 페이지당 건수
 * @param int $currentPage 현재 페이지
 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순)
 * @param string $userId 바로빌 사용자 ID (빈값이면 전체)
 * @return array 사용내역
 */
function getMonthlyCardUsage($cardNum = '', $baseMonth = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') {
    $barobillUserId = getBarobillUserId();
    if (!empty($userId)) {
        $barobillUserId = $userId;
    }
    
    $result = callBarobillCardSOAP('GetMonthlyCardApprovalLog', [
        'ID' => $barobillUserId,
        'CardNum' => $cardNum,
        'BaseMonth' => $baseMonth,
        'CountPerPage' => $countPerPage,
        'CurrentPage' => $currentPage,
        'OrderDirection' => $orderDirection
    ]);
    
    if (!$result['success']) {
        return $result;
    }
    
    return parseCardUsageResult($result['data']);
}

/**
 * 카드 사용내역 결과 파싱
 * 
 * @param object $data SOAP 응답 데이터
 * @return array 파싱된 결과
 */
function parseCardUsageResult($data) {
    // 에러 체크
    if (isset($data->CurrentPage) && $data->CurrentPage < 0) {
        $errorCode = $data->CurrentPage;
        
        // -24005: 조회 데이터 없음 (정상 케이스로 처리)
        // -24001: 등록된 카드 없음
        // -24002: 조회 기간 오류
        if ($errorCode == -24005 || $errorCode == -24001) {
            // 데이터 없음 - 빈 배열 반환 (에러가 아님)
            return [
                'success' => true,
                'data' => [
                    'currentPage' => 1,
                    'countPerPage' => 50,
                    'maxPageNum' => 1,
                    'maxIndex' => 0,
                    'logs' => []
                ]
            ];
        }
        
        return [
            'success' => false,
            'error' => '카드 사용내역 조회 실패',
            'error_code' => $errorCode
        ];
    }
    
    $logs = [];
    if (isset($data->CardLogList) && isset($data->CardLogList->CardApprovalLog)) {
        if (!is_array($data->CardLogList->CardApprovalLog)) {
            $logs = [$data->CardLogList->CardApprovalLog];
        } else {
            $logs = $data->CardLogList->CardApprovalLog;
        }
    }
    
    return [
        'success' => true,
        'data' => [
            'currentPage' => $data->CurrentPage ?? 1,
            'countPerPage' => $data->CountPerPage ?? 50,
            'maxPageNum' => $data->MaxPageNum ?? 1,
            'maxIndex' => $data->MaxIndex ?? 0,
            'logs' => $logs
        ]
    ];
}

/**
 * 카드 등록
 * 
 * @param array $cardData 카드 데이터
 * @return array 응답 데이터
 */
function registerCard($cardData) {
    return callBarobillCardSOAP('RegistCardEx', [
        'CollectCycle' => $cardData['collectCycle'] ?? '1', // 수집주기 (1: 1일 1회)
        'CardCompany' => $cardData['cardCompany'] ?? '',    // 카드사 코드
        'CardType' => $cardData['cardType'] ?? '1',         // 카드 종류 (1: 개인, 2: 법인)
        'CardNum' => $cardData['cardNum'] ?? '',            // 카드번호
        'WebId' => $cardData['webId'] ?? '',                // 카드사 웹 ID
        'WebPwd' => $cardData['webPwd'] ?? '',              // 카드사 웹 비밀번호
        'Alias' => $cardData['alias'] ?? '',                // 카드 별칭
        'Usage' => $cardData['usage'] ?? '1'                // 용도 (1: 세금계산서, 2: 기타)
    ]);
}

?>

