<?php

namespace App\Services\Coocon;

use App\Models\Coocon\CooconConfig;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * 쿠콘 API 서비스
 * 나이스평가정보 연동 API
 */
class CooconService
{
    private ?CooconConfig $config = null;

    private bool $isTestMode = true;

    /**
     * API ID 상수
     */
    public const API_COMPANY_INFO = 'OA08';             // 기업 기본정보

    public const API_CREDIT_SUMMARY = 'OA12';           // 신용요약정보

    public const API_SHORT_TERM_OVERDUE = 'OA13';       // 단기연체정보 (한국신용정보원)

    public const API_NEGATIVE_INFO_KCI = 'OA14';        // 신용도판단정보 (한국신용정보원)

    public const API_NEGATIVE_INFO_CB = 'OA15';         // 신용도판단정보 (신용정보사)

    public const API_SUSPENSION_INFO = 'OA16';          // 당좌거래정지정보 (금융결제원)

    public const API_WORKOUT_INFO = 'OA17';             // 법정관리/워크아웃정보

    /**
     * API 이름 목록
     */
    public const API_NAMES = [
        self::API_COMPANY_INFO => '기업 기본정보',
        self::API_CREDIT_SUMMARY => '신용요약정보',
        self::API_SHORT_TERM_OVERDUE => '단기연체정보 (한국신용정보원)',
        self::API_NEGATIVE_INFO_KCI => '신용도판단정보 (한국신용정보원)',
        self::API_NEGATIVE_INFO_CB => '신용도판단정보 (신용정보사)',
        self::API_SUSPENSION_INFO => '당좌거래정지정보 (금융결제원)',
        self::API_WORKOUT_INFO => '법정관리/워크아웃정보',
    ];

    /**
     * 기본 URL
     */
    private const BASE_URL_TEST = 'https://dev2.coocon.co.kr:8443/sol/gateway/oapi_relay.jsp';

    private const BASE_URL_PRODUCTION = 'https://sgw.coocon.co.kr/sol/gateway/oapi_relay.jsp';

    public function __construct(bool $isTestMode = true)
    {
        $this->isTestMode = $isTestMode;
        $this->loadConfig();
    }

    /**
     * 설정 로드
     */
    private function loadConfig(): void
    {
        $this->config = CooconConfig::getActive($this->isTestMode);
    }

    /**
     * 설정 재로드
     */
    public function reloadConfig(): self
    {
        $this->loadConfig();

        return $this;
    }

    /**
     * 테스트 모드 설정
     */
    public function setTestMode(bool $isTestMode): self
    {
        $this->isTestMode = $isTestMode;
        $this->loadConfig();

        return $this;
    }

    /**
     * 설정 존재 여부
     */
    public function hasConfig(): bool
    {
        return $this->config !== null;
    }

    /**
     * 현재 설정 조회
     */
    public function getConfig(): ?CooconConfig
    {
        return $this->config;
    }

    /**
     * API URL 조회
     */
    private function getBaseUrl(): string
    {
        if ($this->config && $this->config->base_url) {
            return $this->config->base_url;
        }

        return $this->isTestMode ? self::BASE_URL_TEST : self::BASE_URL_PRODUCTION;
    }

    /**
     * API 호출 공통 메서드
     */
    private function callApi(string $apiId, array $params = []): array
    {
        if (! $this->config) {
            return [
                'success' => false,
                'error' => '쿠콘 API 설정이 없습니다. 설정을 먼저 등록해주세요.',
                'code' => 'NO_CONFIG',
            ];
        }

        $url = $this->getBaseUrl();
        $trSeq = $this->generateTransactionSequence();

        $requestData = array_merge([
            'API_KEY' => $this->config->api_key,
            'API_ID' => $apiId,
            'TR_SEQ' => $trSeq,
        ], $params);

        Log::info('쿠콘 API 호출', [
            'api_id' => $apiId,
            'tr_seq' => $trSeq,
            'url' => $url,
            'params' => array_merge($params, ['API_KEY' => '***masked***']),
        ]);

        try {
            $response = Http::timeout(30)
                ->withHeaders([
                    'Content-Type' => 'application/json',
                ])
                ->post($url, $requestData);

            $result = $response->json();

            Log::info('쿠콘 API 응답', [
                'api_id' => $apiId,
                'tr_seq' => $trSeq,
                'rslt_cd' => $result['RSLT_CD'] ?? 'N/A',
                'rslt_msg' => $result['RSLT_MSG'] ?? 'N/A',
            ]);

            if (! $response->successful()) {
                return [
                    'success' => false,
                    'error' => 'HTTP 오류: '.$response->status(),
                    'code' => 'HTTP_ERROR',
                    'http_status' => $response->status(),
                ];
            }

            $rsltCode = $result['RSLT_CD'] ?? '';
            if ($rsltCode === '00000000') {
                return [
                    'success' => true,
                    'data' => $result['RSLT_DATA'] ?? [],
                    'tr_seq' => $result['TR_SEQ'] ?? $trSeq,
                    'message' => $result['RSLT_MSG'] ?? '정상처리되었습니다.',
                    'raw' => $result,
                ];
            }

            return [
                'success' => false,
                'error' => $result['RSLT_MSG'] ?? '알 수 없는 오류',
                'code' => $rsltCode,
                'raw' => $result,
            ];
        } catch (\Exception $e) {
            Log::error('쿠콘 API 호출 실패', [
                'api_id' => $apiId,
                'tr_seq' => $trSeq,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'error' => '쿠콘 API 호출 중 오류가 발생했습니다: '.$e->getMessage(),
                'code' => 'EXCEPTION',
            ];
        }
    }

    /**
     * 거래일련번호 생성
     */
    private function generateTransactionSequence(): string
    {
        return date('YmdHis').substr(microtime(), 2, 6);
    }

    /**
     * 기업 기본정보 조회 (OA08)
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     * @param  string  $idscdcg  식별자구분코드 (기본값: 09-사업자등록번호)
     */
    public function getCompanyInfo(string $companyKey, string $idscdcg = '09'): array
    {
        return $this->callApi(self::API_COMPANY_INFO, [
            'Companykey' => $companyKey,
            'idscdcg' => $idscdcg,
        ]);
    }

    /**
     * 신용요약정보 조회 (OA12)
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     */
    public function getCreditSummary(string $companyKey): array
    {
        return $this->callApi(self::API_CREDIT_SUMMARY, [
            'Companykey' => $companyKey,
        ]);
    }

    /**
     * 단기연체정보 조회 (OA13) - 한국신용정보원
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     * @param  string|null  $reqDate  기준일자 (YYYYMMDD), 미입력시 현재 날짜
     */
    public function getShortTermOverdueInfo(string $companyKey, ?string $reqDate = null): array
    {
        $params = ['Companykey' => $companyKey];

        if ($reqDate) {
            $params['reqDate'] = $reqDate;
        }

        return $this->callApi(self::API_SHORT_TERM_OVERDUE, $params);
    }

    /**
     * 신용도판단정보 조회 (OA14) - 한국신용정보원 (공공정보 포함)
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     */
    public function getNegativeInfoKCI(string $companyKey): array
    {
        return $this->callApi(self::API_NEGATIVE_INFO_KCI, [
            'Companykey' => $companyKey,
        ]);
    }

    /**
     * 신용도판단정보 조회 (OA15) - 신용정보사
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     */
    public function getNegativeInfoCB(string $companyKey): array
    {
        return $this->callApi(self::API_NEGATIVE_INFO_CB, [
            'Companykey' => $companyKey,
        ]);
    }

    /**
     * 당좌거래정지정보 조회 (OA16) - 금융결제원
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     */
    public function getSuspensionInfo(string $companyKey): array
    {
        return $this->callApi(self::API_SUSPENSION_INFO, [
            'Companykey' => $companyKey,
        ]);
    }

    /**
     * 법정관리/워크아웃정보 조회 (OA17)
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     * @param  int  $pageNo  페이지 번호
     * @param  int  $pageSize  페이지 사이즈
     */
    public function getWorkoutInfo(string $companyKey, int $pageNo = 1, int $pageSize = 10): array
    {
        return $this->callApi(self::API_WORKOUT_INFO, [
            'Companykey' => $companyKey,
            'pageNo' => (string) $pageNo,
            'pageSize' => (string) $pageSize,
        ]);
    }

    /**
     * 전체 신용정보 조회 (모든 API 호출)
     *
     * @param  string  $companyKey  사업자번호, 법인번호, 업체코드 중 하나
     */
    public function getAllCreditInfo(string $companyKey): array
    {
        $results = [];

        // 기업 기본정보
        $results['companyInfo'] = $this->getCompanyInfo($companyKey);

        // 신용요약정보
        $results['summary'] = $this->getCreditSummary($companyKey);

        // 단기연체정보
        $results['shortTermOverdue'] = $this->getShortTermOverdueInfo($companyKey);

        // 신용도판단정보 (한국신용정보원)
        $results['negativeInfoKCI'] = $this->getNegativeInfoKCI($companyKey);

        // 신용도판단정보 (신용정보사)
        $results['negativeInfoCB'] = $this->getNegativeInfoCB($companyKey);

        // 당좌거래정지정보
        $results['suspensionInfo'] = $this->getSuspensionInfo($companyKey);

        // 법정관리/워크아웃정보
        $results['workoutInfo'] = $this->getWorkoutInfo($companyKey);

        return $results;
    }
}
