<?php

namespace traits;

use statistics\bookings_s;
use statistics\economic_s;
use statistics\orders_s;

trait statistic_t
{
    public array $default_background_colors = [
        '#FF0000',
        '#00FF00',
        '#0000FF',
        '#FFFF00',
        '#00FFFF',
        '#FF00FF',
        '#000000',
        '#FFFFFF',
        '#FFA500',
        '#FFC0CB',
        '#FF1493',
        '#FF4500',
        '#FFD700',
        '#FF6347',
        '#FF69B4',
        '#FF8C00',
        '#FFA07A',
        '#FFB6C1',
        '#FFDAB9',
        '#FFDEAD',
        '#FFE4B5',
        '#FFE4C4',
        '#FFE4E1',
        '#FFEBCD',
        '#FFEFD5',
        '#FFFAF0',
        '#FFFAFA',
        '#FFFF00',
        '#FFFFE0',
        '#FFFFF0',
        '#FFFFFF',
    ];
    public array $data_sets = [];
    public array $labels = [];
    public array $years = [];
    /**
     * The start date of the date range
     * This is set by the set_date_range method, and is used to filter the data.
     * All dates are in the format 'YYYY-MM-DD'
     * If the start date is not set, the default is fetched from self::get_default_start_date()
     * @var string
     */
    public string $start; // The raw data for the statistics, this is used to merge the data sets.
    /**
     * The end date of the date range
     * This is set by the set_date_range method, and is used to filter the data.
     * All dates are in the format 'YYYY-MM-DD'
     * If the end date is not set, the default is fetched from self::get_default_end_date()
     * @var string
     */
    public string $end;
    protected array $raw_data = [];

    public function __construct()
    {
        // Set the date range
        $this->set_date_range();
    }

    /**
     * Set the date range for the statistics
     */
    public function set_date_range(string $start = null, string $end = null): self
    {
        // If the start and end dates are not set, use the default values
        $this->start = $start ?? $this->get_default_start_date();
        $this->end = $end ?? $this->get_default_end_date();
        // set the years
        $this->years = range(date('Y', strtotime($this->start)), date('Y', strtotime($this->end)));
        return $this;
    }

    /**
     * Get the default start date for the statistics
     */
    public function get_default_start_date(): string
    {
        // Check if the date is set in the request
        if (isset($_GET['start_date'])) {
            return $_GET['start_date'];
        }
        // Return the default start date
        return date('Y-m-d', strtotime('-1 month'));
    }

    /**
     * Get the default end date for the statistics
     */
    public function get_default_end_date(): string
    {
        // Check if the date is set in the request
        if (isset($_GET['end_date'])) {
            return $_GET['end_date'];
        }
        // Return the default end date
        return date('Y-m-d');
    }


    /**
     * Add a data set to the statistics
     * @param string $label The label for the data set (e.g. 'January')
     * @param array $data_set The data set to add to the statistics (e.g. [1, 2, 3, 4])
     * @param array $options The options for the data set (e.g. ['backgroundColor' => '#FF0000'])
     * @return bookings_s|statistic_t
     */
    public function add_data_set(string $label, array $data_set, array $options = []): self
    {
        // Apply the default options
        $options = array_merge([
            'label' => 'Dataset ' . (count($this->data_sets) + 1),
            'backgroundColor' => $this->default_background_colors[count($this->data_sets) % count($this->default_background_colors)]
        ], $options);
        // Add the data set
        $this->data_sets[] = [
            'label' => $label,
            'backgroundColor' => $options['backgroundColor'],
            'data' => $data_set
        ];
        return $this;
    }

    /**
     * Get the response for the statistics
     * @return array
     */
    public function get_response(): array
    {
        return [
            'labels' => $this->labels,
            'datasets' => $this->data_sets,
            'timeline' => [
                'start' => $this->start,
                'end' => $this->end,
                'years' => $this->years
            ]
        ];
    }

    /**
     * Get the years for the statistics
     * @return array
     */
    public function get_years(): array
    {
        return $this->years;
    }

    /**
     * Add the labels for the months covered by the time range (e.g. January 2021, February 2021, March 2021, etc.)
     */
    public function add_monthly_labels(): self
    {
        // For each year, add the months covered
        foreach ( $this->get_yearly_months_covered() as $year => $months ) {
            foreach ( $months as $month ) {
                $this->add_label($month . ' ' . $year);
            }
        }
        return $this;
    }

    /**
     * Get yearly months covered by the time range
     * @return array
     * @example ['2021' => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], '2022' => ['January', 'February']]
     */
    public function get_yearly_months_covered(): array
    {
        // Get the start and end dates
        $start = strtotime($this->start);
        $end = strtotime($this->end);
        // Get the years
        $years = range(date('Y', $start), date('Y', $end));
        // Loop through the years, and add the months that are covered between the start and end dates for each year
        $months = [];
        foreach ( $years as $year ) {
            $months[$year] = [];
            $start_month = $year == date('Y', $start) ? date('n', $start) : 1;
            $end_month = $year == date('Y', $end) ? date('n', $end) : 12;
            for ( $month = $start_month; $month <= $end_month; $month++ ) {
                $months[$year][] = date('F', mktime(0, 0, 0, $month, 1));
            }
        }
        return $months;
    }

    /**
     * Add a label to the statistics
     * @param string $label The label to add to the statistics (e.g. 'January')
     * @return bookings_s|statistic_t
     */
    public function add_label(string $label): self
    {
        $this->labels[] = $label;
        return $this;
    }

    /**
     * Get the raw data for the statistics
     * @return array
     */
    public function get_raw_data(): array
    {
        return $this->raw_data;
    }

    /**
     * Set the raw data for the statistics
     * @param string $key
     * @param array $raw_data The raw data for the statistics
     * @return bookings_s|economic_s|orders_s|statistic_t
     */
    public function set_raw_data(string $key, array $raw_data): self
    {
        $this->raw_data[$key] = $raw_data;
        return $this;
    }


}