<?php


namespace Modules\PrintSuppliers\Services;

use Illuminate\Support\Facades\DB;

class PrintifyService
{

    public static function getCharge($filter) {
        $filter['types'] = ['Charge'];
        return self::getCost($filter) * -1;
    }

    public static function getBonus($filter) {
        $filter['types'] = ['Top Up Balance'];
        $filter['methods'] = ['Sales credit'];
        $items = self::buildQuery($filter)->get(['amount']);
        $result = 0;
        if ($items) {
            foreach ($items as $item) {
                if ($item->amount%10000 == 0) {
                    continue;
                }
                $result += $item->amount/100;
            }
        }
        return $result;
    }


    public static function getRefund($filter) {
        $filter['types'] = ['Top Up Balance'];
        $filter['methods'] = ['Refund'];
        return self::getCost($filter);
    }

    public static function getCost($filter) {
        $report = self::buildQuery($filter)->first([
            DB::raw('SUM(amount)/100 as result')
        ]);
        return isset($report->result) ? $report->result : 0;
    }

    public static function buildQuery($filter) {
        $query = DB::table('payment_printify_transaction');
        if (array_key_exists('transaction_from', $filter)) {
            $query->where('transaction_created_at', '>=', $filter['transaction_from']);
        }
        if (array_key_exists('transaction_to', $filter)) {
            $query->where('transaction_created_at', '<=', $filter['transaction_to']);
        }
        if (array_key_exists('methods', $filter)) {
            $query->whereIn('method', $filter['methods']);
        }
        if (array_key_exists('types', $filter)) {
            $query->whereIn('type', $filter['types']);
        }
        return $query;
    }

    public static function handleTransaction($token, $limit) {
        $endPoint = "https://printify.com/api/v1/payment_transactions";
        $firstPage = 1;
        $result = [];
        do {
            $params = http_build_query([
                'page' => $firstPage,
                'limit' => 200,
                'sort' => '-created_at',
                'type' => 'all'
            ]);
            $response  = self::getData("$endPoint?$params", 'GET', [], [
                'Authorization: Bearer ' . $token
            ]);
            if (isset($response['error'])) {
                break;
            }
            PrintifyService::storeItems($response['data']);
            $result = array_merge($result, $response['data']);
            if ($limit > 0 && count($result) > $limit) {
                break;
            }
            $lastPage = $response['last_page'];
            $firstPage = $firstPage + 1;
        } while ($firstPage <= $lastPage);
        return $result;
    }

    public static function getData($url, $method = 'GET', $params = [], $headers = []) {
        $ch = curl_init();
        $timeout = 200;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        if ($method != 'GET') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        }

        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        $data = curl_exec($ch);
        curl_close($ch);
        return json_decode($data, true);
    }

    public static function storeItems($items) {
        if ($items) {
            foreach ($items as $item) {
                $data = self::buildTransactionInfo($item);
                if ($data) {
                    self::store($data);
                }
            }
        }

    }

    public static function buildTransactionInfo($item) {
        $result = [];
        try {
            $result = [
                'transaction_id' => $item['_id'],
                'user_id' => $item['user_id'],
                'amount' => $item['amount'],
                'transaction_type' => $item['transaction_type'],
                'balance' => $item['balance'],
                'complete' => $item['complete'],
                'amount_cost_tax' => isset($item['metadata']['amount_cost_tax']) ? $item['metadata']['amount_cost_tax'] : null,
                'amount_cost_shipping' => isset($item['metadata']['amount_cost_shipping']) ? $item['metadata']['amount_cost_shipping'] : null,
                'amount_cost_production' => isset($item['metadata']['amount_cost_production']) ? $item['metadata']['amount_cost_production'] : null,
                'order_id' => isset($item['metadata']['order_id']) ? $item['metadata']['order_id'] : null,
                'user_order_id' => isset($item['metadata']['user_order_id']) ? $item['metadata']['user_order_id'] : null,
                'type' => $item['type'],
                'method' => $item['method'],
                'after' => $item['after'],
                'currency' => $item['currency'],
                'transaction_created_at' => $item['created_at'],
                'transaction_updated_at' => $item['updated_at'],
            ];
        } catch (\Exception $e) {
            echo $e->getMessage();
            echo '<pre>';
            echo print_r($transactionInfo);
            echo '</pre>';
            exit;
        }
        return $result;
    }

    public static function store($item) {
        if (self::exists($item['transaction_id'])) {
            $item['updated_at'] = new \DateTime();
            DB::table('payment_printify_transaction')
                ->where('transaction_id', $item['transaction_id'])
                ->update($item);
        } else {
            $item['created_at'] = new \DateTime();
            DB::table('payment_printify_transaction')->insert($item);
        }
    }

    public static function exists($transactionId) {
        return DB::table('payment_printify_transaction')
            ->where('transaction_id', $transactionId)
            ->exists();
    }
}