<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;

class XCXApiController extends Controller
{
  public static $request;
  public static $appid = "13a159e438a742dd932c9bddbfaa41e5";//appid
  public static $signType = "OPENAPI-SHA256-RSA2048";//签名认证类型
  public static $baseUrl = "https://xdfe-api.hnxdfe.com/hisminitest";


  public static function Api($url_code)
  {
    $api['就诊人列表'] = "/jeecg-boot/hospital/openapi/archive/list";
    $api['订单查询'] = "/jeecg-boot/hospital/openapi/order/query";
    $api['订单退款'] = "/jeecg-boot/hospital/openapi/order/refund";
    return $api["{$url_code}"] ?? $url_code;
  }

  public static function Post($url_code, $data)
  {

    $url_address = self::Api($url_code);
    self::RequestLog(self::$baseUrl . $url_address, $data, $url_code, '小程序接口');
    $timestamp = time();
    $nonce = md5(uniqid(rand(), true));
    $base64Signature = self::Sign($url_address, $data, $nonce, $timestamp);
    $response = Http::withHeaders([
      'Authorization' => self::BuildAuthorization($nonce, $timestamp, $base64Signature)
    ])->post(self::$baseUrl . $url_address, $data);

    // dd(self::BuildAuthorization($nonce, $timestamp, $base64Signature));
    if ($response->successful()) {
      // 处理成功的响应
      $res_string = json_encode($response->json(), JSON_UNESCAPED_UNICODE);
      // dd($res_string);
      $str_len = mb_strlen($res_string, 'utf-8');
      $str_size = $str_len / 1024;
      $save_res = $res_string;
      if ($str_size > 10) $save_res = '{"data":"Row size too large"}';
      self::$request->response_data = $save_res;
      self::$request->save();

      $res = json_decode($res_string, true);
      if (!$res['success']) {
        throw new HttpResponseException(\Yz::echoError1("小程序接口提示：" . $res['message']));
      }
      return [
        'code' => $res['code'],
        'message' => $res['message'],
        'data' => $res['result']
      ];
    } else {
      // 处理失败的响应
      self::$request->response_data = "请求小程序接口失败";
      self::$request->save();
      throw new HttpResponseException(\Yz::echoError1("请求小程序接口失败"));
    }
  }

  public static function RequestLog($url, $post_data, $mark, $code = 0)
  {
    self::CheckTableName();
    foreach ($post_data as $key => $post_datum) {
      $str_len = mb_strlen(json_encode($post_datum, JSON_UNESCAPED_UNICODE), 'utf-8');
      $str_size = $str_len / 1024;
      if ($str_size > 10) {
        $post_data["$key"] = 'Row size too large';
      }
    }
    $post_data = json_encode($post_data, JSON_UNESCAPED_UNICODE);
    self::$request->code = $code;
    self::$request->mark = $mark;
    self::$request->post_data = $post_data == '[]' ? '{}' : $post_data;
    self::$request->request_url = $url;
    self::$request->save();
  }

  public static function CheckTableName()
  {
    $table_name = 'zz_peis_log_' . date('ym');
    $table_count = DB::select('select count(1) as c from information_schema.TABLES where table_schema = ? and table_name = ?', [env('DB_DATABASE'), $table_name])[0];
    if ($table_count->c === 0) {
      Schema::create($table_name, function (Blueprint $table) {
        $table->id();
        $table->string('code', 50)->index();
        $table->string('mark', 50)->index();
        $table->text('post_data');
        $table->text('response_data')->nullable();
        $table->string('request_url', 300);
        $table->timestamps();
      });
    }
    self::$request = new \App\Models\PEISLog();
    self::$request->setTable($table_name);
  }

  //构造请求报文主体 首先将请求报文的参数名按照字典序进行排序，然后用&拼接各个参数
  public static function buildSortedQueryString($params)
  {
    // 1. 按照参数名排序
    ksort($params);
    // 2. 拼接参数名和参数值
    $queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986);

    return $queryString;
  }

  //计算签名和 Authorization
  public static function Sign($url, $data, $nonce, $timestamp, $is_urlencode = false)
  {

    $body = self::buildSortedQueryString($data);
    $method = 'POST';

    // $method = 'POST';
    //  $url = '/jeecg-boot/hospital/openapi/order/create';
   //    $timestamp = "1727231032";
   //   $nonce = 'km4W4cjDqwNee1Tw';
   //  $body = 'amount=1&appid=13a159e438a742dd932c9bddbfaa41e5&ghzid=c5ce8410ba854d879a0abf689923ca0d&order_desc=单位团检&orderid=20240915183440999WMp2yu&sub_org_code=6';
//dd($body);
    $private_key = Storage::get('keys/private_key.pem');
    $SignStr = $method . "\n" .
      $url . "\n" .
      $timestamp . "\n" .
      $nonce . "\n" .
      urldecode($body) . "\n";


    // 使用私钥进行 RSA 签名
    openssl_sign($SignStr, $signature, $private_key, OPENSSL_ALGO_SHA256);


    // 对签名结果进行 Base64 编码
    $base64Signature = base64_encode($signature);

    if ($is_urlencode) {
      $base64Signature = urlencode($base64Signature);
    }

    //  dd($SignStr,$base64Signature);
    return $base64Signature;
  }

  //构建Authorization
  public static function BuildAuthorization($nonce, $currentTimestamp, $base64Signature)
  {

    $signInfo = "appid=\"" . self::$appid . "\",nonce=\"" . $nonce . "\",timestamp=\"" . $currentTimestamp . "\",signature=\"" . $base64Signature . "\"";
//dd($signInfo);
    return self::$signType . ' ' . $signInfo;
  }

  //解密
  public static function XCXDecode($str)
  {
    $private_key = Storage::get('keys/private_key.pem');
    $str = base64_decode($str);
    //  dd($str);
    if (openssl_private_decrypt($str, $decryptedData, $private_key, OPENSSL_PKCS1_OAEP_PADDING)) {

      return $decryptedData;

    } else {
      throw new HttpResponseException(\Yz::echoError1("解密数据失败"));
    }
  }


}
