<?php
App::uses('Component', 'Controller');
use GuzzleHttp\Client;

require_once(APP . 'Controller' . DS . 'Traits' . DS . 'ImageUploadTrait.php');
class ImageUploadComponent extends Component
{

    use ImageUploadTrait;

    private $total_image = NUMBER_OF_EXPENSE_IMAGES ?? 3;
    public function AddImageBucket($imagesData, $id, $unique_url, $app_name)
    {
        $images = null;
        $imageCount = count($imagesData);
        $imageResponses = [];
        if ($imageCount >= 1) {

            $imageResponse = null;

            $message = "It is not valid format.";

            $firebasePath = $this->getRootFolder() . '/' . $app_name . '/' . $unique_url . '/' . $id . '/';

            foreach ($imagesData as $key => $image) {

                if ($key > ($this->total_image - 1)) {
                    break;
                }

                $message = "Image has not been provided.";

                if (!empty($image['data'])) {

                    $base64Image = $image['data'];

                    $decodedImage = base64_decode($base64Image);

                    $isImage = $this->checkImageFromBase64EncodedString($base64Image) || $this->checkImageFromBase64DecodedString($decodedImage);

                    $message = "Image is not valid format.";

                    if ($isImage) {

                        $no = $key + 1;

                        $filename = 'img' . $no . '.jpg';

                        $result = $this->uploadBase64Image($base64Image, $firebasePath . $filename);

                        if ($result['status']) {

                            if ($no == 1) {
                                $images = $filename;
                            } else {
                                $images = $images . ',' . $filename;
                            }
                        }

                        $message = $result['message'];
                    }
                }

                $imageResponse["img" . $key] = $message;
            }

            $imageResponses[$unique_url] = $imageResponse;
        }

        return ["images" => $images, "response" => $imageResponses];
    }

    public function DeleteImageBucket($Expanses, $unique_url, $app_name)
    {

        $deleteResponses = [];

        foreach ($Expanses as $item => $Expanse) {
            $firebasePath = $this->getRootFolder() . '/' . $app_name . '/' . $unique_url . '/' . $Expanse['id'] . '/';
            $response = $this->deleteFolder($firebasePath);
            $deleteResponses[$item] = $response['message'];
        }

        return $deleteResponses;
    }

    public function DeleteSingleImageBucket($dbimages, $id, $unique_url, $app_name, $deletedimages)
    {

        $images = explode(',', $dbimages);
        $firebasePath = $this->getRootFolder() . '/' . $app_name . '/' . $unique_url . '/' . $id . '/';
        $delete_image_responses = null;
        $message = "Image not found.";

        foreach ($deletedimages as $key => $deletedimage) {

            $image_name = $deletedimage['name'];

            if (in_array($image_name, $images)) {

                $result = $this->singleImageDelete($firebasePath . $image_name);
                $images = array_diff($images, array($image_name));

                // if image exist in db but not in firebase
                if (!$result['status']) {
                    $images = array_filter($images, function ($item) use ($image_name) {
                        return $item !== $image_name;
                    });
                }

                $message = $result['message'];
            }

            $delete_image_responses[$image_name] = $message;
        }

        return ['images' => implode(',', $images), 'response' => $delete_image_responses];
    }

    public function ModifyImageBucket($dbimages, $id, $unique_url, $app_name, $expanse_images)
    {

        $images = [];
        $imageResponse = null;

        if (!empty($dbimages)) {
            $images = explode(',', $dbimages);
        }

        if (!empty($expanse_images)) {

            $firebasePath = $this->getRootFolder() . '/' . $app_name . '/' . $unique_url . '/' . $id . '/';
            $image_count = count($expanse_images) + count($images);

            if ($image_count <= $this->total_image) {

                foreach ($expanse_images as $key => $image) {

                    $message = "Image has not been provided.";
                    $filename = $this->imageUniqueName($images);

                    if (!empty($image['data']) && !empty($filename)) {

                        $base64Image = $image['data'];
                        $result = $this->uploadBase64Image($base64Image, $firebasePath . $filename);

                        if ($result['status']) {
                            array_push($images, $filename);
                        }

                        $message = $result['message'];
                    }

                    $imageResponse["img" . $key] = $message;
                }
            }

            if ($image_count > $this->total_image) {
                $imageResponse['status'] = false;
                $imageResponse['message'] = "Should be maximum 3 images. Given {$image_count}";
            }
        }

        return ["images" => implode(',', $images), "response" => $imageResponse];
    }

    private function checkImageFromBase64EncodedString($base64String)
    {

        $result = false;
        if (preg_match('/^data:(.*?);base64,/', $base64String, $match)) {

            $mimeType = $match[1];
            if (strpos($mimeType, 'image') !== false) {
                $result = true;
            }
        }

        return $result;
    }

    private function checkImageFromBase64DecodedString($decodedData)
    {

        $result = false;
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $mimeType = $finfo->buffer($decodedData);

        if (strpos($mimeType, 'image') !== false) {
            $result = true;
        }
        return  $result;
    }

    private function imageUniqueName($dbImages)
    {

        $image_name = null;

        for ($i = 1; $i <= $this->total_image; $i++) {

            $filename = 'img' . $i . '.jpg';

            // check image exist or not
            if (!in_array($filename, $dbImages)) {
                $image_name = $filename;
                break;
            }
        }

        return $image_name;
    }

    public function getRootFolder()
    {
        if (strpos(HTTP_SITE_URL, "expensecount.com") !== false) {
            return "prod";
        } elseif (strpos(HTTP_SITE_URL, "localhost") !== false) {
            return "local";
        }
        return "dev";  
    }

    public function ExportImageBucket($unique_url, $app_name)
    {
        $firebasePath = $this->getRootFolder() . '/' . $app_name . '/' . $unique_url . '/' ;
        $expire_time='+2 days';
        $expiresAt = new DateTime($expire_time);
        $savePath = $this->getRootFolder() . '/' . $app_name . '/zip/'.$expiresAt->format('Y-m-d H:i:s').'/' . $unique_url . '/report.zip' ;
        return $this->downloadImage($firebasePath, $expire_time,$savePath);

    }
    public function ReceiptExportInsideFirebase($unique_url, $app_name)   {
        $url = 'https://us-central1-expensecount-312c7.cloudfunctions.net/generateGroupZip';
        $data = [
            "prefix"=> $this->getRootFolder() . '/' . $app_name . '/' ,
            "unique_url"=> $unique_url,
            "zip_file_prefix" => $this->getRootFolder() . '/' . $app_name . '/zip/'
        ];

        $client = new Client();
        try {
            $response = $client->post($url, [
                'headers' => [
                    'Content-Type' => 'application/json'
                ],
                'body' => json_encode($data)
            ]);

            $result = json_decode($response->getBody()->getContents(), true);

            if(!empty($result['zip_path'])) {
                $result['link'] = $this->downloadLink($result['zip_path']);
                $result['expire_time'] = new DateTime('+2 days');
            }
            return $result;

        } catch (\Exception $e) {
            return ["message"=> "Error: " . $e->getMessage(),"success"=>false];
        }
    }
}
