<?php
require_once 'dao.php';

class PostHandler
{
    private $valid_types = ["article", "category", "article_categories", "image", "stock"];
    private $valid_actions = ["create", "update", "remove", "get", "buy", "sell"];

    private $action;
    private $type;
    private $postData;
    private $filesData;
    private $data;
    private $dao;
    private $uploadBaseDir = '../uploaded_images/';
    private $stockFile = "../data/stock-v2.json";
    private $imageBaseUrl = "https://etud.insa-toulouse.fr/~proximo/uploaded_images/";

    private $responseArray = array(
        "status" => 0,
        "message" => "Success",
        "data" => "",
    );

    public function __construct($post, $files)
    {
        $this->filesData = $files;
        $this->action = $this->get_action($post);
        $this->type = $this->get_type($post);
        $this->data = $this->get_data($post);
        $this->postData = $post;
        $this->dao = new Dao();
    }

    public function do_action()
    {
        $result = -1;
        if ($this->type == "image") {
            $result = $this->save_image();
        } else if ($this->type == "stock") {
            $result = $this->updateStock();
        } else if (count($this->data) > 0) {
            if ($this->action == "create")
                $result = $this->create();
            else if ($this->action == "update")
                $result = $this->update();
            else if ($this->action == "remove")
                $result = $this->remove();
            else
                $this->setUnknownActionResponse();
        } else if ($this->action == "get")
            $result = $this->get();
        else
            $this->setUnknownDataResponse();

        if ($this->responseArray["status"] == 0 && $result < 0) {
            $this->setProcessingErrorResponse();
            $result = -1;
        }
        $this->responseArray["data"] = $result;
        return $this->responseArray;
    }

    public function write_json()
    {
        $result = 0;
        $fp = fopen($this->stockFile, "w");
        $array = array(
            "types" => $this->dao->get_categories(),
            "articles" => $this->get_articles_json_list(),
        );
        fwrite($fp, json_encode($array));
        fclose($fp);

        $this->responseArray["data"] = $result;
        return $this->responseArray;
    }

    public function get_articles_json_list()
    {
        $articles = $this->dao->get_articles();
        $formatted_articles = [];
        foreach ($articles as $article) {
            $article["type"] = $this->dao->get_categories_of_article($article["id"]);
            $article["image"] = $this->imageBaseUrl . $article["id"] . ".jpg";
            array_push($formatted_articles, $article);
        }

        return $formatted_articles;
    }

    private function save_image()
    {
        $success = true;
        if ($this->filesData["image"]["size"] > 0 && $this->data != null) {
            $uploadPath = $this->uploadBaseDir . $this->data . ".jpg";

            if (move_uploaded_file($this->filesData["image"]["tmp_name"], $uploadPath)) {
                $this->responseArray["message"] = "Image upload success";
            } else {
                $this->responseArray["message"] = "Image upload failure: " . $uploadPath;
                $this->responseArray["status"] = 1;
                $success = false;
            }
        } else {
            $this->responseArray["message"] = "No valid file to send";
            $this->responseArray["status"] = 1;
            $success = false;
        }
        if ($success)
            return 0;
        else
            return json_encode($this->filesData) . "id: " . $this->data;
    }

    private function remove_image()
    {
        $uploadPath = $this->uploadBaseDir . $this->data["id"] . ".jpg";
        if (file_exists($uploadPath) && unlink($uploadPath)) {
            $this->responseArray["message"] = "Success: Deleted image";
        } else if (!file_exists($uploadPath)) {
            $this->responseArray["message"] = "Success: No image to delete";
        } else {
            $this->responseArray["message"] = "Success: Could not delete image";
        }
    }

    function create()
    {
        $result = -1;
        if ($this->type == "article") {
            $result = $this->dao->create_article($this->data);
        } else if ($this->type == "category") {
            $result = $this->dao->create_category($this->data);
        } else if ($this->type == "article_categories") {
            $result = $this->dao->remove_article_categories_of_article($this->data['id']);
            if ($result)
                $result = $this->dao->save_article_categories($this->data['id'], $this->data['categories']);
        } else
            $this->setUnknownTypeResponse();
        return $result;
    }

    function update()
    {
        $result = -1;
        if ($this->type == "article") {
            $result = $this->dao->update_article($this->data);
        } else if ($this->type == "category") {
            $result = $this->dao->update_category($this->data);
        } else
            $this->setUnknownTypeResponse();
        return $result;
    }

    function remove()
    {
        $result = -1;
        if ($this->type == "article") {
            $result = $this->dao->remove_article($this->data);
            if ($result != 0)
                $this->remove_image();
        } else if ($this->type == "category") {
            $result = $this->dao->remove_category($this->data);
        } else
            $this->setUnknownTypeResponse();
        if ($result == 0)
            return -1;
        else
            return 1;
    }

    function get()
    {
        $result = -1;
        if ($this->type == "article") {
            $result = $this->dao->get_articles();
        } else if ($this->type == "category") {
            $result = $this->dao->get_categories();
        } else if ($this->type == "article_categories") {
            $result = $this->dao->get_article_categories();
        } else
            $this->setUnknownTypeResponse();
        return $result;
    }

    function updateStock()
    {
        $result = 0;
        foreach ($this->data as $row) {
            $value = $row["value"];
            if ($this->action == "sell")
                $value = -$value;
            $result = $this->dao->update_article_stock($row["id"], $value);
            if (!$result)
                break;
        }
        return $result;
    }

    function setUnknownTypeResponse()
    {
        $this->responseArray["status"] = 1;
        $this->responseArray["message"] = "Error: Unknown type";
    }

    function setUnknownActionResponse()
    {
        $this->responseArray["status"] = 2;
        $this->responseArray["message"] = "Error: Unknown action";
    }

    function setUnknownDataResponse()
    {
        $this->responseArray["status"] = 3;
        $this->responseArray["message"] = "Error: Unknown data";
    }

    function setProcessingErrorResponse()
    {
        $this->responseArray["status"] = 4;
        $this->responseArray["message"] = "Error: Data processing error";
    }

    private function get_action($inputData)
    {
        if (!in_array($inputData["action"], $this->valid_actions))
            return "";
        else
            return $inputData["action"];
    }

    private function get_type($inputData)
    {
        if (!in_array($inputData["type"], $this->valid_types))
            return "";
        else
            return $inputData["type"];
    }

    private function get_data($inputData)
    {
        if ($inputData["data"] == null)
            return [];
        else
            return $inputData["data"];
    }

}
