<?php
namespace boru\boruai\Openai;

use boru\boruai\BoruAI;
use boru\boruai\Openai\Api\Endpoints\FilesAPI;
use boru\boruai\Openai\Models\BaseModel;
use Exception;

class OpenAIFile extends BaseModel {
    /** @var string */
    private $id;
    /** @var string */
    private $object = "file";
    /** @var int */
    private $createdAt;
    /** @var string|null */
    private $filename;
    /** @var int|null */
    private $bytes;
    /** @var string */
    private $md5;
    /** @var string */
    private $purpose;
   
    public function id($id=null) {
        if ($id) {
            $this->id = $id;
        }
        return $this->id;
    }
    public function object($object=null) {
        if ($object) {
            $this->object = $object;
        }
        return $this->object;
    }
    public function createdAt($created=null) {
        if ($created) {
            $this->createdAt = $created;
        }
        return $this->createdAt;
    }
    public function filename($filename=null) {
        if ($filename) {
            $this->filename = $filename;
        }
        return $this->filename;
    }
    public function bytes($bytes=null) {
        if ($bytes) {
            $this->bytes = $bytes;
        }
        return $this->bytes;
    }
    public function md5($md5=null) {
        if ($md5) {
            $this->md5 = $md5;
        }
        return $this->md5;
    }
    public function purpose($purpose=null) {
        if ($purpose) {
            $this->purpose = $purpose;
        }
        return $this->purpose;
    }

    public function delete() {
        $result = FilesAPI::delete($this->id());
        return $result;
    }
    public function content() {
        return FilesAPI::content($this->id());
    }

    public function asJpg($base64=false) {
        $fileId = $this->id();
        $content = $this->content();
        $maxFileSizeMegs = BoruAI::config("ocrspace.max_file_size_megs", 1);
        $maxFileSize = $maxFileSizeMegs * 1024 * 1024;
        $inputFile = BoruAI::outputDir().$fileId.'.webp';
        file_put_contents($inputFile, $content);
        $outFile = BoruAI::outputDir().$fileId.'.jpg';
        $fileImage = new \Imagick();
        $fileImage->setResolution(300,300);
        $fileImage->readimage($inputFile);
        $fileImage->setImageFormat('JPEG');
        $fileImage->setImageAlphaChannel(\imagick::ALPHACHANNEL_ACTIVATE);
        $fileImage->setBackgroundColor(new \ImagickPixel('#ffffff'));
        $fileImage->writeImage($outFile);
        $quality = 95;
        while(strlen($fileImage->getImageBlob()) > $maxFileSize) {
            $quality -= 5;
            $fileImage->setImageCompressionQuality($quality);
            if($quality < 5) {
                throw new \Exception("File size too large");
            }
            $fileImage->writeImage($outFile);
        }
        $imageContents = file_get_contents($outFile);
        unlink($inputFile);
        unlink($outFile);

        if($base64) {
           return base64_encode($imageContents);
        }
        return $fileImage;
    }

    public function toArray() {
        return [
            "id" => $this->id(),
            "object" => $this->object(),
            "created_at" => $this->createdAt(),
            "filename" => $this->filename(),
            "purpose" => $this->purpose(),
            "bytes" => $this->bytes(),
            "md5" => $this->md5(),
        ];
    }

    public static function fromId($id) {
        $result = FilesAPI::get($id);
        if(isset($result["id"])) {
            $result = new OpenAIFile($result);
        } else {
            return false;
        }
        return $result;
    }

    public static function upload($fileNameOrStream,$purpose="") {
        $parameters = [
            "purpose" => $purpose
        ];
        if(is_string($fileNameOrStream)) {
            if(!file_exists($fileNameOrStream)) {
                throw new Exception("File not found: ".$fileNameOrStream);
            }
            $parameters["file"] = fopen($fileNameOrStream,"r");
        } elseif(is_resource($fileNameOrStream)) {
            $parameters["file"] = $fileNameOrStream;
        } else {
            throw new Exception("Invalid file type");
        }
        $result = FilesAPI::upload($parameters);
        if(isset($result["id"])) {
            $file = new OpenAIFile($result);
            return $file;
        }
        return $result;
    }
}