<?php
// /common/erp_api.php
include getenv("DOCUMENT_ROOT")."/include/session_include.php";

class ErpApi {

    private $baseUrl;
    private $token;
    private $enabled = false;

    public function __construct() {
        global $jdb;
        $row = $jdb->fQuery("SELECT cfg_erp_api_url, cfg_erp_api_token FROM tbl_config LIMIT 1", "config fetch error");

        $url   = isset($row['cfg_erp_api_url']) ? trim($row['cfg_erp_api_url']) : '';
        $token = isset($row['cfg_erp_api_token']) ? trim($row['cfg_erp_api_token']) : '';

        // URL 없으면 바로 예외 (서버 아직 준비 안됨)
        if ($url === '' || $url === null) {
            $this->enabled = false;
            $this->baseUrl = '';
            $this->token   = '';
            return;
        }

        $this->enabled = true;
        $this->baseUrl = rtrim($url, '/');
        $this->token   = $token;
    }


    /**
     * 공통 HTTP 요청 처리
     */
    private function request($method, $endpoint, $data = null) {
        // ERP 비활성화면 아무것도 하지 않고 조용히 반환
        if (!$this->enabled) {
            return [
                "disabled" => true,
                "skipped"  => true,
                "endpoint" => $endpoint,
            ];
        }

        $url = $this->baseUrl . $endpoint;

        $headers = [
            "Authorization: Bearer {$this->token}",
            "Content-Type: application/json"
        ];

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        if ($data !== null) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }

        $response  = curl_exec($ch);
        $httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if ($response === false) {
            $err = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL Error: $err");
        }

        curl_close($ch);

        $result = json_decode($response, true);
        if ($result === null && json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("JSON Decode Error: " . json_last_error_msg() . " - Response: $response");
        }

        if ($httpCode >= 400) {
            $msg = isset($result['message']) ? $result['message'] : $response;
            throw new Exception("HTTP $httpCode Error: $msg");
        }

        return $result;
    }

    // -------------------------------------------------------
    //  기본 Customer API
    // -------------------------------------------------------

    public function createCustomer($data) {
        return $this->request("POST", "/customer", $data);
    }

    public function updateCustomer($cusNo, $data) {
        return $this->request("PATCH", "/customer/no/" . $cusNo, $data);
    }

    public function deleteCustomer($cusNo) {
        return $this->request("DELETE", "/customer/no/" . $cusNo);
    }

    // -------------------------------------------------------
    //  공통 유틸
    // -------------------------------------------------------

    private function convertDate($dateStr) {
        if (!$dateStr || !is_string($dateStr)) {
            return null;
        }

        // YYYYMMDD (8)
        if (strlen($dateStr) === 8) {
            return substr($dateStr, 0, 4) . '-' .
                substr($dateStr, 4, 2) . '-' .
                substr($dateStr, 6, 2);
        }

        // YYYYMMDDHHIISS (14)
        if (strlen($dateStr) === 14) {
            return substr($dateStr,0,4)."-"
                . substr($dateStr,4,2)."-"
                . substr($dateStr,6,2)."T"
                . substr($dateStr,8,2).":"
                . substr($dateStr,10,2).":"
                . substr($dateStr,12,2);
        }

        // 지원하지 않는 포맷
        return null;
    }

    private function normalizeValue($value) {
        if ($value === '' || $value === false) return null;
        if (is_string($value) && trim($value) === '') return null;
        return $value;
    }

    private function getValue($columns, $values, $col) {
        $idx = array_search($col, $columns);
        return $idx !== false ? $values[$idx] : null;
    }

    // -------------------------------------------------------
    //  MIS → ERP Customer Payload 빌드 (완전 자동 변환)
    // -------------------------------------------------------

    public function buildCustomerPayload($columns, $values, $loginUser) {

        $payload = [];

        // MIS → ERP 매핑 규칙
        $map = [
            "cusNo"                 => "c_accountno",
            "cusName"               => "c_name",
            "cusStatus"             => "c_status",
            "cusAreaId"             => "c_area",
            "cusAddress1"           => "c_address",
            "cusAddress2"           => "c_mailingaddr",
            "cusPostalCode"         => "c_postal",
            "cusCity"               => "c_city",
            "cusProvince"           => "c_province",
            "cusEmail"              => "c_email",
            "cusPhone"              => "c_phone",
            "cusPhoneExt"           => "c_phoneext",
            "cusRate"               => "c_rate",
            "cusPayMethod"          => "c_paymenttype",
            "cusContractDate"       => "c_contractdate",
            "cusContractedBy"       => "c_contractby",
            "cusInstallDate"        => "c_installdate",
            // full cycle 필요하면 나중에 추가 2025-12-16
            // "cusFullCycle"          => "c_fullcycle",
            // "cusFullCycleFlag"      => "c_fullcycleflag",
            // "cusFullCycleForced"    => "c_fullcycleforced",
            // "cusFullCycleForcedDate"=> "c_forceddate",
            "cusSchedule"           => "c_schedule",
            "cusScheduledays"       => "c_scheduleday",
            "cusIsccDate"           => "c_form_eu",
            "cusCorsiaDate"         => "c_form_corsia",
            "cusHstNo"              => "c_hstno",
            "cusComment"            => "c_comment_ri",
            "cusContactComment"     => "c_comment_ci",
            "cusGeoLat"             => "c_geolat",
            "cusGeoLon"             => "c_geolon",
            "cusInstallLocation"    => "c_location",
        ];

        // 날짜 변환 필드 목록
        $dateCols = [
            "c_contractdate",
            "c_installdate",
            "c_forceddate",
            "c_form_eu",
            "c_form_corsia"
        ];

        // 기본 필드 채우기
        foreach ($map as $erpKey => $misCol) {
            $value = $this->getValue($columns, $values, $misCol);

            if ($value && in_array($misCol, $dateCols)) {
                $value = $this->convertDate($value);
            }

            $payload[$erpKey] = $value;
        }

        // 로그인 사용자
        $payload["cusLoginUser"] = $loginUser;

        return $payload;
    }

    // -------------------------------------------------------
    //  MIS → ERP Customer CREATE
    // -------------------------------------------------------
    public function createCustomerFromMis($columns, $values, $loginUser) {
        // 비활성화면 로그도 남기지 말고 바로 종료
        if (!$this->enabled) {
            return ["disabled" => true, "skipped" => true];
        }

        $payload = $this->buildCustomerPayload($columns, $values, $loginUser);

        try {
            // 테스트용
            // addLog("add"
            //     , "/customer"
            //     , "ERP - SUCCESS"
            //     , $loginUser
            //     , json_encode($payload, JSON_PRETTY_PRINT)
            //     , ''
            // );

            return $this->createCustomer($payload);

        } catch (Exception $e) {
            $logBody =
                "[EXCEPTION]\n" .
                $e->getMessage() . "\n\n" .
                "[PAYLOAD]\n" .
                json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

            addLog("add"
                , "/customer"
                , "ERP - FAILED"
                , $loginUser
                , $logBody
                , ''
            );

            // 사용자에게는 아무것도 안 알려줌
            return [
                "success" => false,
                "queued"  => true
            ];
        }
    }

    // -------------------------------------------------------
    //  MIS → ERP Customer UPDATE (cusNo 기준)
    // -------------------------------------------------------
    public function updateCustomerFromMis($columns, $values, $loginUser) {
        // 비활성화면 로그도 남기지 말고 바로 종료
        if (!$this->enabled) {
            return ["disabled" => true, "skipped" => true];
        }

        // accountno 찾기
        $cusNo = $this->getValue($columns, $values, "c_accountno");
        if (!$cusNo) {
            throw new Exception("updateCustomerFromMis: Missing c_accountno");
        }

        $payload = $this->buildCustomerPayload($columns, $values, $loginUser);
        try {
            // 테스트용
            // addLog("add"
            //     , "/customer/no/" . $cusNo
            //     , "ERP - SUCCESS"
            //     , $loginUser
            //     , json_encode($payload, JSON_PRETTY_PRINT)
            //     , $cusNo
            // );

            return $this->updateCustomer($cusNo, $payload);

        } catch (Exception $e) {
            $logBody =
                "[EXCEPTION]\n" .
                $e->getMessage() . "\n\n" .
                "[PAYLOAD]\n" .
                json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

            addLog("add"
                , "/customer/no/" . $cusNo
                , "ERP - FAILED"
                , $loginUser
                , $logBody
                , $cusNo
            );

            // 사용자에게는 아무것도 안 알려줌
            return [
                "success" => false,
                "queued"  => true
            ];
        }
    }

    // -------------------------------------------------------
    //  MIS → ERP Customer 단일필드 업데이트 (update_column.php 용)
    // -------------------------------------------------------
    public function updateCustomerFieldFromMis($cusNo, $field, $value, $loginUser) {
        if (!$this->enabled) {
            return ["disabled" => true, "skipped" => true];
        }

        $payload = [
            "cusLoginUser" => $loginUser,
            $field         => $value
        ];

        return $this->updateCustomer($cusNo, $payload);
    }

    // -------------------------------------------------------
    //  Customer Daily Order 관련 API (RAW 호출)
    // -------------------------------------------------------

    /**
     * POST /customer-daily-order
     */
    public function createOrder($data) {
        return $this->request("POST", "/customer-daily-order", $data);
    }

    /**
     * PATCH /customer-daily-order/customer/{customerNo}/{orderDate}
     *  - customerNo : ERP customer.cus_no
     *  - orderDate  : yyyy-MM-dd
     */
    public function updateOrder($customerNo, $orderDate, $data) {
        return $this->request(
            "PATCH",
            "/customer-daily-order/customer/" . $customerNo . "/" . $orderDate,
            $data
        );
    }

    /**
     * DELETE /customer-daily-order/{uuid}
     */
    public function deleteOrder($uuid) {
        return $this->request("DELETE", "/customer-daily-order/" . $uuid);
    }

    // -------------------------------------------------------
    //  Customer Daily Order - MIS 연동용 헬퍼
    //  (tbl_daily $columns / $values 기반으로 payload 생성)
    // -------------------------------------------------------

    /**
     * MIS 의 tbl_daily ( $columns, $values ) 를 ERP CustomerDailyOrderRequestDto 로 변환
     *
     * @param array  $columns  tbl_daily insert 시 사용한 컬럼명 배열
     * @param array  $values   각 컬럼에 대한 값 배열
     * @param string $loginUser MIS 로그인 사용자 ID
     * @return array ERP에 보낼 payload
     */
    public function buildDailyOrderPayload($columns, $values, $loginUser) {

        $payload = [];

        // MIS → ERP 매핑 규칙
        // (필요에 따라 계속 보강 가능)
        $map = [
            "cdoOrderDate"        => "d_orderdate",
            "cdoOrderType"        => "d_ordertype",
            "cdoRequestNote"      => "d_requestnote",
            "cdoCustomerNo"       => "d_accountno",
            "cdoCycle"            => "d_cycle",
            "cdoPaymentType"      => "d_paymenttype",
            "cdoRate"             => "d_rate",
            "cdoStatus"           => "d_status",
            "cdoEstimatedQty"     => "d_estquantity",
            "cdoQuantity"         => "d_quantity",
            "cdoSludge"           => "d_sludge",
            "cdoPayStatus"        => "d_paystatus",
            "cdoPayAmount"        => "d_payamount",
            "cdoPayeeName"        => "d_payeename",
            "cdoPayeeSign"        => "d_payeesign",
            "cdoExternalDriverId" => "d_driveruid",
            "cdoVisitFlag"        => "d_visit",
            "cdoPickupNote"       => "d_pickupnote",
            "cdoPickupAt"         => "d_inputdate",
        ];

        // 날짜 변환이 필요한 컬럼들
        $dateColumns = [
            "d_orderdate",
            "d_inputdate",
        ];

        // 로그인 사용자
        $payload["cdoLoginUser"] = $loginUser;

        // map 에 따라 값 채우기
        foreach ($map as $erpKey => $misCol) {
            $idx = array_search($misCol, $columns);
            $value = ($idx !== false) ? $values[$idx] : null;

            // 빈 문자열 → null
            if (is_string($value)) {
                $value = trim($value);
                if ($value === '') {
                    $value = null;
                }
            }

            // 날짜 변환
            if ($value !== null && in_array($misCol, $dateColumns, true)) {
                $value = $this->convertDate($value);
            }

            $payload[$erpKey] = $value;
        }

        /* Rule */
        // 연결 key 
        if (!$payload['cdoCustomerNo']) {
            throw new Exception("DailyOrder Error: Missing CustomerNo");
        }
        if (!$payload['cdoOrderDate']) {
            throw new Exception("DailyOrder Error: Missing OrderDate");
        }

        // quantity 있는데 sludge 없으면 sludge = 0
        if (
            array_key_exists('cdoQuantity', $payload)
            && $payload['cdoQuantity'] !== null
            && $payload['cdoSludge'] === null
        ) {
            $payload['cdoSludge'] = 0;
        }

        return $payload;
    }

    /**
     * MIS → ERP : Daily Order 신규 생성 편의 함수
     *
     * user_process.php 에서:
     *    $erp = new ErpApi();
     *    $payload = $erp->buildDailyOrderPayload($columns, $values, $lguserid);
     *    $erp->createOrder($payload);
     *
     * 또는:
     *    $erp->createDailyOrderFromMis($columns, $values, $lguserid);
     */
    public function createDailyOrderFromMis($columns, $values, $loginUser) {
        if (!$this->enabled) {
            return ["disabled" => true, "skipped" => true];
        }

        $payload = $this->buildDailyOrderPayload($columns, $values, $loginUser);

        try {
            // 테스트용
            // addLog("add"
            //     , "/customer-daily-order"
            //     , "ERP - SUCCESS"
            //     , $loginUser
            //     , json_encode($payload, JSON_PRETTY_PRINT)
            //     , ''
            // );

            return $this->createOrder($payload);

        } catch (Exception $e) {
            $logBody =
                "[EXCEPTION]\n" .
                $e->getMessage() . "\n\n" .
                "[PAYLOAD]\n" .
                json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

            addLog("add"
                , "/customer-daily-order"
                , "ERP - FAILED"
                , $loginUser
                , $logBody
                , ''
            );

            // 사용자에게는 아무것도 안 알려줌
            return [
                "success" => false,
                "queued"  => true
            ];
        }
    }

    /**
     * MIS → ERP : Daily Order 업데이트 (customerNo + orderDate 기준)
     */
    public function updateDailyOrderFromMis($columns, $values, $loginUser) {
        // 비활성화면 로그도 남기지 말고 바로 종료
        if (!$this->enabled) {
            return ["disabled" => true, "skipped" => true];
        }

        $payload = $this->buildDailyOrderPayload($columns, $values, $loginUser);

        // customerNo / orderDate 추출
        $customerNo = $payload['cdoCustomerNo'];
        $orderDate  = $payload['cdoOrderDate'];

        try {
            // 테스트용
            // addLog("add"
            //     , "/customer-daily-order/customer/" . $customerNo . "/" . $orderDate
            //     , "ERP - SUCCESS"
            //     , $loginUser
            //     , json_encode($payload, JSON_PRETTY_PRINT)
            //     , $customerNo
            // );

            return $this->updateOrder($customerNo, $orderDate, $payload);

        } catch (Exception $e) {
            $logBody =
                "[EXCEPTION]\n" .
                $e->getMessage() . "\n\n" .
                "[PAYLOAD]\n" .
                json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

            addLog("add"
                , "/customer-daily-order/customer/" . $customerNo . "/" . $orderDate
                , "ERP - FAILED"
                , $loginUser
                , $logBody
                , $customerNo
            );
            // 사용자에게는 아무것도 안 알려줌
            return [
                "success" => false,
                "queued"  => true
            ];
        }
    }
}
?>
