<?php

namespace Main\Controllers\Tebex;

use Main\Core\Controller;
use PDO;

class WebhookController extends Controller
{
    public function webhook()
    {
        $json = file_get_contents("php://input");
        $data = json_decode($json, true);
        $secret = modules('tebex_store')->settings('secretKey');
        $signature = hash_hmac('sha256', hash('sha256', $json), $secret);
        if ($signature != $_SERVER["HTTP_X_SIGNATURE"])
            response()->json([
                'success' => false,
                'error' => 'INVALID_SIGNATURE'
            ]);

        $dataId = $data["id"];
        $dataType = $data["type"];
        if ($dataType == "validation.webhook")
            response()->json([
                'id' => $dataId
            ]);

        $events = [
            'payment.completed',
            'recurring-payment.started',
            'recurring-payment.renewed',
        ];
        if (!in_array($dataType, $events))
            response()->json([
                'status' => false,
                'error' => 'INVALID_TYPE'
            ]);

        $data = $data["subject"];

        if ($dataType == "payment.completed") {
            $check = db()->prepare("SELECT * FROM Orders WHERE paymentID = ?");
            $check->execute([$data["transaction_id"]]);
            $check = $check->fetch();
            if ($check)
                response()->json([
                    'status' => false,
                    'error' => 'ORDER_ALREADY_EXISTS'
                ]);

            $searchAccount = db()->prepare("SELECT id FROM Accounts WHERE realname = ?");
            $searchAccount->execute([$data["customer"]["username"]["username"]]);
            $searchAccount = $searchAccount->fetch();
            if (!$searchAccount)
                response()->json([
                    'status' => false,
                    'error' => 'USER_NOT_FOUND'
                ]);

            $couponCode = null;
            if (!empty($data["coupons"])) {
                $couponCode = $data["coupons"][0]["code"];
            }

            $basketPrice = 0;
            foreach ($data["products"] as $package) {
                $basketPrice += $package["base_price"]["amount"] * $package["quantity"];
            }
            $basketPrice += $data["fees"]["tax"]["amount"];

            $createOrder = db()->prepare("INSERT INTO Orders (accountID, coupon, total, discount, subtotal, paymentID, paymentAPI, status, type, credit, earnings, creationDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
            $createOrder->execute(array(
                $searchAccount["id"],
                $couponCode,
                $data["price_paid"]["amount"],
                $basketPrice - $data["price_paid"]["amount"],
                $basketPrice,
                $data["transaction_id"],
                'tebex_checkout',
                1,
                1,
                0,
                $data["price_paid"]["amount"],
                $data["created_at"],
            ));
            $orderID = db()->lastInsertId();
            $updateOrInsertTebexProducts = db()->prepare("INSERT INTO TebexProducts (id, name) VALUES (?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name)");
            foreach ($data["products"] as $package) {
                $createOrderProduct = db()->prepare("INSERT INTO OrderProducts (orderID, productID, quantity, unitPrice) VALUES (?, ?, ?, ?)");
                $createOrderProduct->execute(array(
                    $orderID,
                    $package["id"],
                    $package["quantity"],
                    $package["base_price"]["amount"],
                ));

                // Update or insert tebex product
                $updateOrInsertTebexProducts->execute([
                    $package["id"],
                    $package["name"]
                ]);
            }
        }

        if ($dataType == "recurring-payment.started") {
            $searchAccount = db()->prepare("SELECT id FROM Accounts WHERE realname = ?");
            $searchAccount->execute([$data["last_payment"]["customer"]["username"]["username"]]);
            $searchAccount = $searchAccount->fetch();
            if (!$searchAccount)
                response()->json([
                    'status' => false,
                    'error' => 'USER_NOT_FOUND'
                ]);

            $insertSubscriptions = db()->prepare("INSERT INTO Subscriptions (accountID, productID, reference, endsAt, startsAt, updatedDate, creationDate) VALUES (?, ?, ?, ?, ?, ?, ?)");
            $insertSubscriptions->execute([
                $searchAccount["id"],
                $data["last_payment"]["products"][0]["id"],
                $data["reference"],
                $data["next_payment_at"],
                $data["created_at"],
                $data["created_at"],
                $data["created_at"],
            ]);
        }

        if ($dataType == "recurring-payment.renewed") {
            $searchAccount = db()->prepare("SELECT id FROM Accounts WHERE realname = ?");
            $searchAccount->execute([$data["last_payment"]["customer"]["username"]["username"]]);
            $searchAccount = $searchAccount->fetch();
            if (!$searchAccount)
                response()->json([
                    'status' => false,
                    'error' => 'USER_NOT_FOUND'
                ]);

            $checkSubscriptions = db()->prepare("SELECT * FROM Subscriptions WHERE reference = ?");
            $checkSubscriptions->execute([$data["reference"]]);
            $checkSubscriptions = $checkSubscriptions->fetch();
            if ($checkSubscriptions) {
                $updateSubscriptions = db()->prepare("UPDATE Subscriptions SET endsAt = ?, updatedDate = ? WHERE reference = ?");
                $updateSubscriptions->execute([
                    $data["next_payment_at"],
                    datetime(),
                    $data["reference"]
                ]);
            } else {
                $insertSubscriptions = db()->prepare("INSERT INTO Subscriptions (accountID, productID, reference, endsAt, startsAt, updatedDate, creationDate) VALUES (?, ?, ?, ?, ?, ?, ?)");
                $insertSubscriptions->execute([
                    $searchAccount["id"],
                    $data["last_payment"]["products"][0]["id"],
                    $data["reference"],
                    $data["next_payment_at"],
                    $data["created_at"],
                    $data["created_at"],
                    $data["created_at"],
                ]);
            }
        }

        response()->json([
            'id' => $dataId
        ]);
    }
}