<?php

namespace App\Campaigns;

use Illuminate\Support\Collection;

class PerformanceChart
{
    /**
     * Dual-axis line graph of spend and clicks. Uses every Whale day.
     *
     * @param  Collection<int, PerformanceDay>  $days
     * @return array<string, mixed>
     */
    public static function fromDays(Collection $days): array
    {
        $sorted = $days
            ->sortBy(fn (PerformanceDay $row): int => $row->stat_date->timestamp)
            ->values();

        $height = 260;
        $padL = 52;
        $padR = 52;
        $padT = 20;
        $padB = 48;
        $count = $sorted->count();
        $width = (int) max(720, $padL + $padR + max(1, $count) * 42);
        $innerW = $width - $padL - $padR;
        $innerH = $height - $padT - $padB;
        $baseY = $padT + $innerH;

        if ($sorted->isEmpty()) {
            return [
                'empty' => true,
                'day_count' => 0,
                'width' => $width,
                'height' => $height,
                'pad_l' => $padL,
                'pad_r' => $padR,
                'pad_t' => $padT,
                'base_y' => $baseY,
                'days' => [],
                'points_spend' => '',
                'points_clicks' => '',
                'area' => '',
                'dots_spend' => [],
                'dots_clicks' => [],
                'x_ticks' => [],
                'max_spend' => 0.0,
                'max_clicks' => 0,
                'y_spend' => ['$0', '$0', '$0', '$0'],
                'y_clicks' => [0, 0, 0, 0],
                'first_date' => null,
                'last_date' => null,
            ];
        }

        $maxSpend = max(1.0, (float) $sorted->max('spend'));
        $maxClicks = max(1, (int) $sorted->max('clicks'));
        $slot = $innerW / $count;

        $series = [];
        $spendPoints = [];
        $clickPoints = [];
        $dotsSpend = [];
        $dotsClicks = [];
        $ticks = [];

        foreach ($sorted->values() as $index => $day) {
            $center = round($padL + ($slot * $index) + ($slot / 2), 1);
            $spend = round((float) $day->spend, 2);
            $clicks = (int) $day->clicks;
            $impressions = (int) $day->impressions;
            $cpc = $day->cpc !== null ? round((float) $day->cpc, 2) : ($clicks > 0 ? round($spend / $clicks, 2) : null);
            $spendY = round($padT + $innerH - ($spend / $maxSpend) * $innerH, 1);
            $clickY = round($padT + $innerH - ($clicks / $maxClicks) * $innerH, 1);

            $series[] = [
                'center' => $center,
                'date' => $day->stat_date->toDateString(),
                'label' => $day->stat_date->format('j M'),
                'spend' => $spend,
                'clicks' => $clicks,
                'impressions' => $impressions,
                'cpc' => $cpc,
                'hit_x' => round($padL + ($slot * $index), 1),
                'hit_width' => round($slot, 1),
            ];
            $spendPoints[] = $center.','.$spendY;
            $clickPoints[] = $center.','.$clickY;
            $dotsSpend[] = ['x' => $center, 'y' => $spendY];
            $dotsClicks[] = ['x' => $center, 'y' => $clickY];
            $ticks[] = [
                'x' => $center,
                'label' => $day->stat_date->format('j M'),
            ];
        }

        $firstX = $dotsSpend[0]['x'];
        $lastX = $dotsSpend[array_key_last($dotsSpend)]['x'];
        $area = 'M '.$firstX.' '.$baseY.' L '.str_replace(',', ' ', implode(' L ', $spendPoints)).' L '.$lastX.' '.$baseY.' Z';

        return [
            'empty' => false,
            'day_count' => $count,
            'width' => $width,
            'height' => $height,
            'pad_l' => $padL,
            'pad_r' => $padR,
            'pad_t' => $padT,
            'base_y' => $baseY,
            'days' => $series,
            'points_spend' => implode(' ', $spendPoints),
            'points_clicks' => implode(' ', $clickPoints),
            'area' => $area,
            'dots_spend' => $dotsSpend,
            'dots_clicks' => $dotsClicks,
            'x_ticks' => $ticks,
            'max_spend' => round($maxSpend, 2),
            'max_clicks' => $maxClicks,
            'y_spend' => [
                '$'.number_format($maxSpend, 0),
                '$'.number_format($maxSpend * 0.66, 0),
                '$'.number_format($maxSpend * 0.33, 0),
                '$0',
            ],
            'y_clicks' => [
                $maxClicks,
                (int) round($maxClicks * 0.66),
                (int) round($maxClicks * 0.33),
                0,
            ],
            'first_date' => $sorted->first()?->stat_date->toDateString(),
            'last_date' => $sorted->last()?->stat_date->toDateString(),
        ];
    }
}
