<?php

namespace App\Http\Controllers\Ecomtoacc\Shopify;

use App;
use App\Http\Controllers\Controller;
use App\Models\Shopify\Spycredential;
use App\Models\Shopify\Spysummarypayout;
use App\Models\Shopify\Spysummarypayouttransaction;
use App\Models\Shopify\Spysummaryrefund;
use App\Models\Shopify\Spysummaryorder;
use App\Models\Shopify\Spyreportsetting;
use App\Helpers\Helper;
use DateTime;
use DateTimeZone;
use Illuminate\Http\Request;

class PayoutController extends Controller
{    
    private $randomValue = 0;
    public function fetchSpyPayouts(Request $request){
        
        $seller_id = $request->get('seller_id');
        $type = $request->get('type');

        $seller_id=(!empty($seller_id))? Helper::encryptor('decrypt', $seller_id):"";
        $startdate = $request->get('startdate');
        $enddate = $request->get('enddate');
        $spyStoreDatas = Spycredential::fetchValidSpyStores($seller_id);
        
        $this->randomValue = rand(1111111111,9999999999);
        foreach ($spyStoreDatas as $key => $spyStoreData) {
           // $this->cronActionLog($seller_id, $module, 'Auto cron for fetch payouts- START', $this->randomValue);
            $shop = $spyStoreData['store_domain'];
            $settingsData = Spyreportsetting::fetchReportSettingData('seller_id', $spyStoreData->id);
            if(!empty($settingsData)){
                $this->syncPayoutData($shop,$spyStoreData,$settingsData,$startdate,$enddate);
            }
            //$this->cronActionLog($seller_id, $module, 'Auto cron for fetch payouts- END', $this->randomValue);
        }
        return 'success';
    }
    public function syncPayoutData($shop,$spyConnected,$settingsData, $startDate = '', $endDate = '')
    {
        ini_set('max_execution_time', 0);
        if (!empty($spyConnected)) {
            if (!empty($settingsData)) {
                if ($startDate != '' && $endDate != '') {
                    $payoutResponse = $this->fetchOldPayoutFromShopify($spyConnected, $shop, $startDate, $endDate);
                  
                } else {
                    $payoutResponse = $this->fetchPayoutFromShopify($spyConnected, $shop, $settingsData->sync_start_date);
                }
                
                if (!empty($payoutResponse['payouts'])) {
                    $i         = 1;
                    $startTime = time();
                    foreach ($payoutResponse['payouts'] as $key => $value) {
                        if ($value['status'] == "paid" || $value['status'] == "canceled") {
                            $paymentResponse = $this->fetchPayoutPaymentFromShopify($spyConnected, $value, $shop);
                            $spyStoreObj = $this->storePayoutDataInDb($spyConnected, $value, $paymentResponse,$settingsData,$startDate, $endDate);
                        }
                    }
                }
            }
        }
    }
    private function fetchPayoutFromShopify($spyConnected, $shop, $syncStartDate)
    {
        $spyOrderData = Spysummarypayout::fetchLastPayout($spyConnected['id']);
        if (empty($spyOrderData)) {
            //$syncStartDate = date('Y-m-d', strtotime('+1 day', strtotime($syncStartDate)));

            $shopUrl = "https://" . $shop . "/admin/" . config('app.shopify_version') . "/shopify_payments/payouts.json?since_id=1&date_min=" . $syncStartDate . "&limit=250";
        } else {
            $shopUrl = "https://" . $shop . "/admin/" . config('app.shopify_version') . "/shopify_payments/payouts.json?since_id=" . $spyOrderData['payout_id'] . "&limit=250";
        }
        $result         = app('App\Http\Controllers\Ecomtoacc\Shopify\ApiController')::shop_curl_request_call($shopUrl, $spyConnected['store_access_token']);
        $payoutResponse = json_decode($result, true);
        return $payoutResponse;
    }
    private function fetchPayoutPaymentFromShopify($spyConnected, $payoutsData, $shop)
    {
        $nextUrl = '';
        do {
            if ($nextUrl != '') {
                $shopUrl = $nextUrl;
            } else {
                $shopUrl = "https://" . $shop . "/admin/" . config('app.shopify_version') . "/shopify_payments/balance/transactions.json?&limit=250&payout_id=" . $payoutsData['id'];
            }
            $result                = app('App\Http\Controllers\Ecomtoacc\Shopify\ApiController')::shop_curl_request_call_header($shopUrl, $spyConnected['store_access_token']);
            $nextUrl               = $result['url'];
            $payoutPaymentResponse = json_decode($result['data'], true);
            $data[]                = $payoutPaymentResponse['transactions'];
        } while ($nextUrl != '');
        $data = call_user_func_array('array_merge', $data);
        return $data;
    }

    private function storePayoutDataInDb($spyConnected, $orderData, $paymentResponse,$settingsData,$startDate, $endDate)
    {
      $orderIdsArray= array();
      $RefundedorderIdsArray= array();
        $checkDuplicate = Spysummarypayout::fetchSpyPayoutSingleData("payout_id", $orderData['id'], $spyConnected['id'],$spyConnected['module']);
        $orderType= 'create';
        if ((empty($checkDuplicate)) || (!empty($startDate) && !empty($endDate))) {
            if (!empty($paymentResponse)) {
                foreach ($paymentResponse as $key => $value) {
                    $paymentTrascationObj = Spysummarypayouttransaction::fetchPayoutTrans($spyConnected['id'], $value['id'],$spyConnected['module']);
                        if (empty($paymentTrascationObj)) {
                            $paymentTrascationObj = new Spysummarypayouttransaction();
                        }
                        $paymentTrascationObj->seller_id             = $spyConnected['id'];
                        $paymentTrascationObj->module = $spyConnected['module'];
                        $paymentTrascationObj->transaction_id       = $value['id'];
                        $paymentTrascationObj->payout_id            = $value['payout_id'];
                        $paymentTrascationObj->order_id             = $value['source_order_id'];
                        $paymentTrascationObj->type                 = $value['type'];
                        $paymentTrascationObj->payout_status        = $value['payout_status'];
                        $paymentTrascationObj->currency             = $value['currency'];
                        $paymentTrascationObj->amount               = $value['amount'];
                        $paymentTrascationObj->fee                  = $value['fee'];
                        $paymentTrascationObj->net                  = $value['net'];
                        $paymentTrascationObj->source_id            = $value['source_id'];
                        $paymentTrascationObj->source_type          = $value['source_type'];
                        $paymentTrascationObj->order_transaction_id = $value['source_order_transaction_id'];
                        $paymentTrascationObj->processed_at         = (new DateTime($value['processed_at']))->setTimezone(new DateTimeZone($spyConnected['spy_timezone']))->format('Y-m-d H:i:s');
                        $paymentTrascationObj->save();
                    $orderIdsArray[] = $value['source_order_id'];
                    if ($value['type'] == 'refund') {
                        $RefundedorderIdsArray[] = $value['source_order_id'];
                    }
                }
                $update = Spysummarypayouttransaction::updatePayoutAmount($spyConnected['id'],$spyConnected['module'], 'payout_id', $orderData['id']);

                if(!empty($orderIdsArray)){
                  $orderDbdata = Spysummaryorder::select('order_id')->where('seller_id',$spyConnected['id'])->where('module',$spyConnected['module'])->whereIn('order_id',$orderIdsArray)->ToBase()->get();
                  $orderDbdata = json_decode(json_encode($orderDbdata),true);
                  if(!empty($orderDbdata)){
                    $orderIdsArray = array_filter($orderIdsArray);
                    $orderDbdata = array_map('array_values', $orderDbdata);
                    $orderDbdata = call_user_func_array('array_merge', $orderDbdata);
                    $orderIdsArray = array_diff($orderIdsArray,$orderDbdata);
                  }
                  if(!empty($orderIdsArray)){
                    $fetchBackDateData=true;
                    $spyOrderData = $this->getOrderFromShopify($spyConnected,$orderIdsArray);
                    if(!empty($spyOrderData)){
                      foreach ($spyOrderData as $keyOrd => $valueOrd) {
                        app('App\Http\Controllers\Ecomtoacc\Shopify\OrderController')->createUpdateOrderDataInDb($spyConnected,$valueOrd,$orderType,$settingsData,$fetchBackDateData);
                      }
                    }
                  }
                }
                if(!empty($RefundedorderIdsArray))
                {
                    foreach ($RefundedorderIdsArray as $valuerefdata) {
                        $refundData = $this->getRefundFromShopify($spyConnected, $valuerefdata);
                        $orderData1 = Spysummaryorder::where('seller_id',$spyConnected['id'])->where('module',$spyConnected['module'])->where('order_id',$valuerefdata)->first();
                        if(empty($orderData1)){
                            $orderIdAry = array($valuerefdata);
                            $spyOrderData = $this->getOrderFromShopify($spyConnected,$orderIdAry);
                            $orderData1=(isset($spyOrderData[0]))?$spyOrderData[0]:"";
                        }
                        app('App\Http\Controllers\Ecomtoacc\Shopify\OrderController')->storeRefundsDataInDb($spyConnected,$refundData,$orderData1,$settingsData->sync_start_date);
                      
                    }
                }
            }
            $spyStoreObj = Spysummarypayout::fetchSpyPayoutSingleData("payout_id", $orderData['id'], $spyConnected['id'],$spyConnected['module']);
            if(empty($spyStoreObj)){
                $spyStoreObj = new Spysummarypayout();
            }
            $spyStoreObj->module = $spyConnected['module'];
            // $spyStoreObj->id = generateUniqueId();

            $spyStoreObj->payout_id = $orderData['id'];

            if (!empty($orderData['status'])) {
                $spyStoreObj->payout_status = $orderData['status'];
            }

            if (!empty($orderData['date'])) {
                $spyStoreObj->date = $orderData['date'];
            }

            if (!empty($orderData['currency'])) {
                $spyStoreObj->currency = $orderData['currency'];
            }

            if (!empty($orderData['amount'])) {
                $spyStoreObj->amount = $orderData['amount'];
            }

            if (!empty($orderData['summary'])) {
                $spyStoreObj->summary = json_encode($orderData['summary']);
            }
            $spyStoreObj->seller_id = $spyConnected['id'];
            $spyStoreObj->save();

            return $spyStoreObj;

        } else {
            return false;
        }
    }

    public function fetchPayoutSpyToDb(Request $request)
    {
        $shop = Helper::encryptor('decrypt',$request->get('domain'));
        $shopenc = $request->get('domain');
        $module = $request->get('module');
        $spyConnected = Spycredential::checkConnection($shop,$module);
        $settingsData = Summarysetting::fetchSummarySettingData($spyConnected);

        $this->syncPayoutData($shop, $request->get('startDate'), $request->get('endDate'),$spyConnected,$settingsData);
        return 'success';
    }
    public function updatePayoutDbtoXr(Request $request)
    {
        $shop = Helper::encryptor('decrypt',$request->get('domain'));
        $shopenc = $request->get('domain');
        $this->updatePayoutData($shop);
        echo 'success';exit;
    }
    public function getRefundFromShopify($spyConnected, $order_id)
    {
        $shopUrl = "https://" . $spyConnected['store_domain'] . "/admin/" . config('app.shopify_version') . "/orders/" . $order_id . "/refunds.json?limit=250";

        $result                 = app('App\Http\Controllers\Ecomtoacc\Shopify\ApiController')::shop_curl_request_call($shopUrl, $spyConnected['store_access_token']);
        $inventoryLevelResponse = json_decode($result, true);

        return $inventoryLevelResponse;
    }
    public function getOrderFromShopify($spyConnected, $order_id)
    {
        $orderdata = array_chunk($order_id, 250);
        foreach ($orderdata as $key => $value) {
          $order_ids = implode(',', $value);
            $shopUrl = "https://" . $spyConnected['store_domain'] . "/admin/" . config('app.shopify_version') . "/orders.json?status=any&limit=250&ids=".$order_ids;

            $result                 = app('App\Http\Controllers\Ecomtoacc\Shopify\ApiController')::shop_curl_request_call($shopUrl, $spyConnected['store_access_token']);
            $inventoryLevelResponse = json_decode($result, true);
            $shopifyData[] = $inventoryLevelResponse['orders'];
        }
        $data = call_user_func_array('array_merge', $shopifyData);
        return $data;
    }
     private function fetchOldPayoutFromShopify($spyConnected,$shop,$startDate,$endDate)
    {
        //$endDate = date("Y-m-d",strtotime('+1 day', strtotime($endDate)));
        //$startDate = date('Y-m-d', strtotime('+1 day', strtotime($startDate)));

        $shopUrl = "https://" . $shop . "/admin/".config('app.shopify_version')."/shopify_payments/payouts.json?since_id=1&date_min=".$startDate."&date_max=".$endDate."&limit=250";
        $result = app('App\Http\Controllers\Ecomtoacc\Shopify\ApiController')::shop_curl_request_call($shopUrl,$spyConnected['store_access_token']);
        $payoutResponse = json_decode($result,true);
        return $payoutResponse;
    }
}
