<?php
namespace App\Http\Controllers\Ecomtoacc\Ecomtodb\Amazon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Master\Sellers;
use App\Models\Amazon\Marketplace;
use App\Models\Amazon\Azsellers;
use App\Models\Amazon\Azlastsync;
use App\Models\Amazon\Azfinancialevents;
use App\Models\Amazon\Azorder;
use Log;
use DateTime;
use DateTimeZone;
use DB;
use File;

class FinancialeventsController extends Controller
{
    private $randomValue = 0;
    /*
    Manali Patel - 17-07-2023
    */

    public function getFinancialEvents(Request $request,$para = ''){

        set_time_limit(0);
        $sellerid = Helper::encryptor('decrypt',$request->get('sellerid'));
        $sellerid = 15;
        $seller = Azsellers::find($sellerid);
        
        $connection_name = '';
        $module = $seller->module;
        if(strpos($seller->module,'tl') !== false){
            $connection_name = env('DB_DATABASE_TALLY_MASTER').'.tally_connections';
        } 

        if($seller->sync_type == 'Summary'){
            if(strpos($seller->module,'tl') !== false)
            $setting_name = env('DB_DATABASE').'.tally_summary_setting';
        }
        else{
            if(strpos($seller->module,'tl') !== false)
            $setting_name = 'tally_sync_settings';
        }
        
        $sellerDetails = Azsellers::getSellerDetail($sellerid,$connection_name,$setting_name,$seller->module);
        
        $backdated_dates = array();
        if(!empty($sellerDetails) && count($sellerDetails) > 0){
            $sellerDetails = $sellerDetails->toArray()[0];            
            
            list($posted_after,$posted_before) = $this->getPostedDate($sellerDetails,$startDate = '',$endDate='',$backdated_dates = array());
            list($report_result,$next_token) = $this->getEventsFromAmazon($sellerDetails,$module,$posted_after,$posted_before);

            if(!empty($report_result)){
                $this->processData($sellerid,$report_result);
            }

            if($next_token != ''){
                $this->getNexttokenEvents($sellerid,$module,$next_token);
            }
            $azlastsync = Azlastsync::where('seller_id',$sellerDetails['seller_id'])->where('sync_type','Event')->first();
            if(empty($azlastsync)){
                $azlastsync = new Azlastsync();
            }
            $azlastsync->seller_id = $sellerid;
            $azlastsync->LastPurchaseDate = $posted_before;
            $azlastsync->sync_type = 'Event';
            $azlastsync->save();
        }

        if($para == '')
        return 'success';
        else
        return true;
    }

    private function getPostedDate($sellerDetails,$startDate = '',$endDate='',$backdated_dates = array()){
        $version = config('ecomtoacc.amazon.FINANCE_SPAPI_V2_REPORT');

        if(empty($backdated_dates)){
            $lastSyncData = Azlastsync::where('seller_id',$sellerDetails['seller_id'])->where('sync_type','Event')->first();
            
            if($startDate != ''){
                $posted_start_date = date("Y-m-d\TH:i:s\Z", strtotime($startDate));
            }else if($lastSyncData['LastPurchaseDate'] != ''){
                $posted_start_date = date("Y-m-d\TH:i:s\Z", strtotime($lastSyncData['LastPurchaseDate']));
            }else{
                $posted_start_date = date("Y-m-d\TH:i:s\Z", strtotime($sellerDetails['sync_start_date']));
            }
            
            if($endDate != ''){
                $posted_end_date = date("Y-m-d\TH:i:s\Z", strtotime($endDate));
            }else{
                if($posted_start_date != ''){
                    $posted_end_date = date('Y-m-d\TH:i:s\Z',strtotime($posted_start_date.' +180 days'));    
                    if(strtotime('now') < strtotime($posted_end_date)){
                        $posted_end_date = date('Y-m-d\TH:i:s\Z',strtotime('-30 minute'));
                    }    
                }else{
                    $posted_end_date = date('Y-m-d\TH:i:s\Z');
                }
            }
        }else{
            $posted_start_date = date('Y-m-d\TH:i:s\Z',strtotime('-180 days'));
            $posted_end_date = date('Y-m-d\TH:i:s\Z');
        }
        return array($posted_start_date,$posted_end_date);
    }

    public function getFinanceEventArray($data,$sequence){
        foreach ($sequence as $sk => $sequence_name) {
            $function_name = 'get'.$sequence_name;
            $Data1 = $data->$function_name();
            $finalData[$sequence_name] = $Data1;
            
        }
        return $finalData;
    }

    public function checkExist($seller_id,$order_id,$posted_date,$amount_type){
        return Azfinancialevents::where('seller_id',$seller_id)->where('order_id',$order_id)->where('posted_date',$posted_date)->where('amount_type',$amount_type)->first();
    }
    public function getEventsFromAmazon($sellerDetails,$module,$posted_after,$posted_before,$next_token = ''){
        $config = app('App\Http\Controllers\Ecomtoacc\Ecomtodb\Amazon\ApiController')->getCommonConfigDetails($sellerDetails,$module); 
        $apiInstance = new \ClouSale\AmazonSellingPartnerAPI\Api\FinancesApi($config);
        $max_results_per_page = 100;
        $next_token = '';
        
        $result = $apiInstance->listFinancialEvents($max_results_per_page, $posted_after, $posted_before, $next_token);
        if(is_string($result))
        {
          $report_result = $result;
        }else{
          $report_result = $result->getPayload();
          if(isset($report_result['next_token']))
            $next_token = $report_result['next_token']; 
        }
        return array($report_result,$next_token);
    }
    private function getNexttokenEvents($sellerDetails,$module,$next_token){
        for ($i=1; $i < config('app.maxPagePerCall'); $i++) {
            if($nextToken != ''){
                list($report_result,$next_token) = $this->getEventsFromAmazon($sellerDetails,$module,'','',$next_token);
                if(!empty($report_result)){
                    $this->processData($sellerid,$report_result);
                }
            }
        } 
    }

    public function processData($sellerid,$report_result){
        $shipingEventSequence = array('sequence'=>array('ItemChargeList','ItemFeeList','ItemTaxWithheldList','PromotionList'));

        $shipmentEventList = $report_result['financial_events']->getShipmentEventList();
        $finalData = array();
        foreach ($shipmentEventList as $key => $value) {
            $order_id = $value['amazon_order_id'];
            $posted_date = $value['posted_date'];
            $ShipmentItemList = $value->getShipmentItemList();
            foreach ($ShipmentItemList as $k => $v) {
                $finalData = $this->getFinanceEventArray($v,$shipingEventSequence['sequence']);
                $finalData['order_id'] = $order_id;
            }
            if(!empty($finalData)){
                $order_id = $finalData['order_id'];
                unset($finalData['order_id']);
                foreach ($finalData as $key => $value) {
                    if(!empty($value)){
                        $function_name = 'get'.$key;
                        $this->$function_name($sellerid,$order_id,$posted_date,$value);
                    }
                }
            }
        }

        $serviceFeeEventList = $report_result['financial_events']->getServiceFeeEventList();
        if(!empty($serviceFeeEventList)){
            foreach ($serviceFeeEventList as $key => $value) {
                $order_id = $value['amazon_order_id'];
                $function_name = $this->getFeeList($sellerid,$order_id,$value['fee_list']);
            }
        }

        $adjustmentEventList = $report_result['financial_events']->getAdjustmentEventList();
        if(!empty($adjustmentEventList)){
            foreach ($adjustmentEventList as $key => $value) {
                $order_id = '';
                $function_name = $this->getAdjustmentEvent($sellerid,$order_id,$value);
            }
        }
    }

    public function getItemChargeList($seller_id,$order_id,$posted_date,$data){
        
        foreach ($data as $key => $value) {
            $posted_date = date('Y-m-d H:i:s',strtotime($posted_date));
            $amount_type = $value['charge_type'];
            $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
            if(empty($checkExist)){
                $checkExist = new Azfinancialevents();
            }
            $checkExist->seller_id = $seller_id;
            $checkExist->order_id = $order_id;
            $checkExist->posted_date = $posted_date;
            $checkExist->amount_type = $amount_type;
            $checkExist->amount = $value['charge_amount']['currency_amount'];
            $checkExist->currency = $value['charge_amount']['currency_code'];
            $checkExist->save();
        }        
    }

    public function getItemFeeList($seller_id,$order_id,$posted_date,$data){
        foreach ($data as $key => $value) {
            $amount_type = $value['fee_type'];
            $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
            if(empty($checkExist)){
                $checkExist = new Azfinancialevents();
            }
            $checkExist->seller_id = $seller_id;
            $checkExist->order_id = $order_id;
            $checkExist->posted_date = date('Y-m-d H:i:s',strtotime($posted_date));
            $checkExist->amount_type = $amount_type;
            $checkExist->amount = $value['fee_amount']['currency_amount'];
            $checkExist->currency = $value['fee_amount']['currency_code'];
            $checkExist->save();
        }
    }

    public function getItemTaxWithheldList($seller_id,$order_id,$posted_date,$data){
        
        foreach ($data as $key => $value) {
            if(isset($value['taxes_withheld'][0])){
                foreach ($value['taxes_withheld'] as $k => $v) {
                    $amount_type = $v['charge_type'];
                    $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
                    if(empty($checkExist)){
                        $checkExist = new Azfinancialevents();
                    }
                    $checkExist->seller_id = $seller_id;
                    $checkExist->order_id = $order_id;
                    $checkExist->posted_date = date('Y-m-d H:i:s',strtotime($posted_date));
                    $checkExist->amount_type = $amount_type;
                    $checkExist->amount = $v['charge_amount']['currency_amount'];
                    $checkExist->currency = $v['charge_amount']['currency_code'];
                    $checkExist->save();
                }
            }else{
                $amount_type = $value['charge_type'];
                $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
                if(empty($checkExist)){
                    $checkExist = new Azfinancialevents();
                }
                $checkExist->seller_id = $seller_id;
                $checkExist->order_id = $order_id;
                $checkExist->posted_date = date('Y-m-d H:i:s',strtotime($posted_date));
                $checkExist->amount_type = $amount_type;
                $checkExist->amount = $value['charge_amount']['currency_amount'];
                $checkExist->currency = $value['charge_amount']['currency_code'];
                $checkExist->save();
            }
        }
    }

    public function getPromotionList($seller_id,$order_id,$posted_date,$data){
        //no proper data to handle
    }

    public function getFeeList($seller_id,$order_id,$data){
        foreach ($data as $key => $value) {
            $amount_type = $value['fee_type'];
            $posted_date = $this->getOrderPurchaseDate($seller_id,$order_id);
            $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
            if(empty($checkExist)){
                $checkExist = new Azfinancialevents();
            }
            $checkExist->seller_id = $seller_id;
            $checkExist->order_id = $order_id;
            $checkExist->posted_date = $posted_date;
            $checkExist->amount_type = $amount_type;
            $checkExist->amount = $value['fee_amount']['currency_amount'];
            $checkExist->currency = $value['fee_amount']['currency_code'];
            $checkExist->save();
        }
    }

    public function getAdjustmentEvent($seller_id,$order_id,$data){
        $amount_type = $data['adjustment_type'];
        $posted_date = $this->getOrderPurchaseDate($seller_id,$order_id);
        $checkExist = $this->checkExist($seller_id,$order_id,$posted_date,$amount_type);
        if(empty($checkExist)){
            $checkExist = new Azfinancialevents();
        }
        $checkExist->seller_id = $seller_id;
        $checkExist->order_id = $order_id;
        $checkExist->posted_date = $posted_date;
        $checkExist->amount_type = $amount_type;
        $checkExist->amount = $data['adjustment_amount']['currency_amount'];
        $checkExist->currency = $data['adjustment_amount']['currency_code'];
        $checkExist->save();
    }
    public function getOrderPurchaseDate($seller_id,$order_id){
        $posted_date = NULL;
        $azOrder = Azorder::fetchOrderSingleData('AmazonOrderId',$order_id,$seller_id);
        if(!empty($azOrder)){
            $posted_date = date('Y-m-d H:i:s',strtotime($azOrder->PurchaseDate));
        }else{
            $orderRequest = new \Illuminate\Http\Request();
            $orderRequest->replace(['sellerid' => Helper::encryptor('encrypt',$seller_id),'order_id' => $order_id]);
            app('App\Http\Controllers\Ecomtoacc\Ecomtodb\Amazon\OrderController')->updateOrdersFromAmazonSp($orderRequest,'return');
            $azOrder = Azorder::fetchOrderSingleData('AmazonOrderId',$order_id,$seller_id);
            if(!empty($azOrder)){
                $posted_date = date('Y-m-d H:i:s',strtotime($azOrder->PurchaseDate));
            }
        }
        return $posted_date;
    }
}