<?php
namespace Ceetrox\Sidekick\Views\Limitless\Linechart\ChartManager;

Class ChartDataManager {

    private array    $categories;
    private Series   $series;
    private ?int     $numberOfCharts;
    private array    $titles;
    private array    $colors;
    private ?bool    $hasBoundaryGap;
    private ?bool    $isInverted;
    private ?bool    $hasDataZoom;
    private ?int     $animationDuration;
    private ?string  $yAxisLabelValueFormat;
    private ?string  $rawData;

    private ?bool    $showPointValues;
    private ?bool    $isStacked;
    private ?bool    $isArea;
    private ?bool    $markLine;

    public function __construct()
    {
        $this->categories = [];
        $this->series = new Series();
        $this->numberOfCharts = null;
        $this->colors = [];
        $this->titles = [];
        $this->hasBoundaryGap = null;
        $this->isInverted = null;
        $this->hasDataZoom = null;
        $this->animationDuration = null;
        $this->yAxisLabelValueFormat = null;
        $this->rawData = null;

        $this->showPointValues = null;
        $this->isStacked = null;
        $this->isArea = null;
        $this->markLine = null;
    }

    public static function getInstance(): ChartDataManager
    {
        return new self;
    }

    public static function getSeriesDataInstance(): SeriesData
    {
        return new SeriesData();
    }

    private function getNumberOfCharts() : int
    {
        return $this->series->numberOfCharts();
    }

    private function getTitles() : array
    {
        return $this->titles;
    }

    private function getColors() : array
    {
        return $this->colors;
    }

    private function getHasBoundaryGap() : ?bool
    {
        return $this->hasBoundaryGap;
    }

    private function getIsInverted() : ?bool
    {
        return $this->isInverted;
    }

    private function getHasDataZoom() : ?bool
    {
        return $this->hasDataZoom;
    }

    private function getAnimationDuration() : ?int
    {
        return $this->animationDuration;
    }

    private function getYAxisLabelValueFormat() : ?string
    {
        return $this->yAxisLabelValueFormat;
    }

    private function getRawData() : ?string
    {
        return $this->rawData;
    }

    private function getShowPointValues() : ?bool
    {
        return $this->showPointValues;
    }

    private function getIsStacked() : ?bool
    {
        return $this->isStacked;
    }

    private function getIsArea() : ?bool
    {
        return $this->isArea;
    }

    private function getMarkLine() : ?string
    {
        return $this->markLine;
    }

    public function setTitle($title) : ChartDataManager
    {
        if(is_array($title)) {
            $this->titles = array_merge($this->titles, $title);
        } else {
            $this->titles[] = $title;
        }

        return $this;
    }

    public function setColors($color) : ChartDataManager
    {
        if(is_array($color)) {
            $this->colors = array_merge($this->colors, $color);
        } else {
            $this->colors[] = $color;
        }

        return $this;
    }

    public function setHasBoundaryGap(bool $value) : ChartDataManager
    {
        $this->hasBoundaryGap = $value;
        return $this;
    }

    public function setIsInverted(bool $value) : ChartDataManager
    {
        $this->isInverted = $value;
        return $this;
    }

    public function setHasDataZoom(bool $value) : ChartDataManager
    {
        $this->hasDataZoom = $value;
        return $this;
    }

    public function setAnimationDuration(int $value) : ChartDataManager
    {
        $this->animationDuration = $value;
        return $this;
    }

    public function setYAxisLabelValueFormat(string $value) : ChartDataManager
    {
        $this->yAxisLabelValueFormat = $value;
        return $this;
    }

    public function setRawData(string $value) : ChartDataManager
    {
        $this->rawData = $value;
        return $this;
    }

    public function setShowPointValues(bool $value) : ChartDataManager
    {
        $this->showPointValues = $value;
        return $this;
    }

    public function setIsStacked(bool $value) : ChartDataManager
    {
        $this->isStacked = $value;
        return $this;
    }

    public function setIsArea(bool $value) : ChartDataManager
    {
        $this->isArea = $value;
        return $this;
    }

    public function setMarkLine(string $value) : ChartDataManager
    {
        $this->markLine = $value;
        return $this;
    }

    public function addCategories($category) : ChartDataManager
    {
        if(is_array($category)) {
            $this->categories = array_merge($this->categories, $category);
        } else {
            $this->categories[] = $category;
        }

        return $this;
    }

    public function addSeries(SeriesData $series) : ChartDataManager
    {
        $this->series->push($series);
        $this->numberOfCharts = $this->series->numberOfCharts();
        return $this;
    }

    public function toJson(): string
    {
        return json_encode($this->toArray());
    }

    public function toArray(): array
    {
        // set if conditions so we can only pass attributes that are set.
        // if attributes are not set then we can check and use the manual parameters of the charts.

        if(!is_null($this->numberOfCharts))             $data['charts'] = $this->numberOfCharts;

        if(count($this->series) > 0)                    $data['series'] = $this->series->toArray();
        if(count($this->categories) > 0)                $data['categories'] = $this->categories;
        if(count($this->titles) > 0)                    $data['titles'] = $this->titles;
        if(count($this->colors) > 0)                    $data['colors'] = $this->colors;

        if(!is_null($this->hasBoundaryGap))             $data['boundaryGap'] = $this->hasBoundaryGap;
        if(!is_null($this->isInverted))                 $data['inverted'] = $this->isInverted;
        if(!is_null($this->hasDataZoom))                $data['dataZoom'] = $this->hasDataZoom;
        if(!is_null($this->animationDuration))          $data['animationDuration'] = $this->animationDuration;
        if(!is_null($this->yAxisLabelValueFormat))      $data['yAxisLabelValueFormat'] = $this->yAxisLabelValueFormat;
        if(!is_null($this->rawData))                    $data['raw'] = json_encode(json_decode($this->rawData));

        if(!is_null($this->showPointValues))            $data['pointValues'] = $this->showPointValues;
        if(!is_null($this->isStacked))                  $data['stacked'] = $this->isStacked;
        if(!is_null($this->isArea))                     $data['isArea'] = $this->isArea;
        if(!is_null($this->markLine))                   $data['markLine'] = $this->markLine;

        return $data ?? [];
    }

}