<?php

namespace portalpeople\stripe\controllers\api;

use portalpeople\stripe\components\StripeClient;
use portalpeople\stripe\Module;
use RuntimeException;
use Yii;
use yii\web\Controller;
use yii\web\Response;

class ApiController extends Controller
{
    public $enableCsrfValidation = false;

    private ?StripeClient $client = null;
    private ?string $clientInitError = null;

    public function init(): void
    {
        parent::init();
        /** @var Module $module */
        $module = $this->module;
        try {
            $this->client = StripeClient::fromModule($module);
        } catch (RuntimeException $e) {
            $this->clientInitError = $e->getMessage();
        }
    }

    public function actionCustomers(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        try {
            return $this->client->listCustomers(Yii::$app->request->get());
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionCustomer(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        $id = trim((string) Yii::$app->request->get('id', ''));
        if ($id === '') {
            return $this->errorResponse('Query parameter "id" is required.', 400);
        }

        try {
            return $this->client->retrieveCustomer($id);
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionPaymentIntentCreate(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        if (!Yii::$app->request->isPost) {
            return $this->errorResponse('POST required.', 405);
        }

        $payload = Yii::$app->request->post();
        $idempotencyKey = (string) Yii::$app->request->headers->get('Idempotency-Key', '');

        try {
            return $this->client->createPaymentIntent($payload, $idempotencyKey !== '' ? $idempotencyKey : null);
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionPaymentIntent(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        $id = trim((string) Yii::$app->request->get('id', ''));
        if ($id === '') {
            return $this->errorResponse('Query parameter "id" is required.', 400);
        }

        try {
            return $this->client->retrievePaymentIntent($id);
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionRefunds(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        try {
            return $this->client->listRefunds(Yii::$app->request->get());
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionRefundCreate(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        if (!Yii::$app->request->isPost) {
            return $this->errorResponse('POST required.', 405);
        }

        $payload = Yii::$app->request->post();
        $idempotencyKey = (string) Yii::$app->request->headers->get('Idempotency-Key', '');

        try {
            return $this->client->createRefund($payload, $idempotencyKey !== '' ? $idempotencyKey : null);
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    public function actionBalance(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($this->clientInitError !== null) {
            return $this->errorResponse($this->clientInitError, 500);
        }

        try {
            return $this->client->retrieveBalance();
        } catch (RuntimeException $e) {
            return $this->errorResponse($e->getMessage(), 502);
        }
    }

    private function errorResponse(string $message, int $statusCode): array
    {
        Yii::$app->response->statusCode = $statusCode;
        return ['error' => $message];
    }
}
