<?php
namespace boru\boruai\Openai\Api\Responses;

use boru\dhttp\core\Response;

class ApiListResponse extends ApiBaseResponse implements \Iterator {
    private $className;
    private $firstId;
    private $lastId;
    private $hasMore = false;
    private $requestCallable;
    private $requestParams;
    private $dataObjects = [];
    private $index = 0;
    /**
     * @param \boru\dhutils\http\Response|array $response
     */
    public function __construct($response,$className,$requestCallable,$requestParams=[]) {
        $this->className = $className;
        $this->requestCallable = $requestCallable;
        $this->requestParams = $requestParams;
        parent::__construct($response);
        if(!isset($this->body["has_more"])) {
            $this->body["has_more"] = false;
        }
        $this->hasMore = $this->body["has_more"] ? true : false;
        $this->firstId = isset($this->body["first_id"]) ? $this->body["first_id"] : null;
        $this->lastId = isset($this->body["last_id"]) ? $this->body["last_id"] : null;
        $this->dataObjects = $this->body["data"];
    }

    /**
     * @param Response $response
     */
    public static function fromListResponse($resp,$className,$requestCallable,$requestParams=[]) {
        if($resp instanceof Response) {
            return new self($resp,$className,$requestCallable,$requestParams);
        } elseif(is_array($resp)) {
            return new self($resp,$className,$requestCallable,$requestParams);
        }
        return false;
    }

    public function current() {
        if(isset($this->dataObjects[$this->index])) {
            $cn = $this->className;
            return new $cn($this->dataObjects[$this->index]);
        }
        return false;
    }

    public function next() {
        $this->index++;
    }

    public function key() {
        return $this->index;
    }

    public function valid() {
        $valid = isset($this->dataObjects[$this->index]);
        if(!$valid && $this->hasMore) {
            $valid = $this->nextPage();
        }
        return $valid;
    }

    public function rewind() {
        $this->index = 0;
    }

    public function nextPage() {
        if($this->hasMore) {
            $this->requestParams[2]["after"] = $this->lastId;
            $response = call_user_func_array($this->requestCallable,$this->requestParams);
            $body = $response->asArray();
            $this->hasMore = $body["has_more"] ? true : false;
            $this->firstId = $body["first_id"];
            $this->lastId = $body["last_id"];
            foreach($body["data"] as $data) {
                $this->dataObjects[] = $data;
            }
            return true;
        }
        return false;
    }
}