<?php

namespace BitApps\PiPro\Services;

// Prevent direct script access
if (!\defined('ABSPATH')) {
    exit;
}


\define('strict_types', 1); // phpcs:ignore

use BitApps\PiPro\Config;
use BitApps\PiPro\Deps\BitApps\WPKit\Helpers\DateTimeHelper;
use BitApps\PiPro\Deps\BitApps\WPKit\Http\Client\HttpClient;
use Exception;

class CronService
{
    public const BASE_URL = 'https://wp-api.bitapps.pro/public/';

    public const WP_CRON_PATH = '/wp-cron.php';

    public static function createOrDeleteCloudCron(bool $useCloudCron)
    {
        if ($useCloudCron) {
            return self::createCloudCron();
        }

        return self::deleteCloudCron();
    }

    public static function createCloudCron()
    {
        return self::cloudCronRequest('wp-cron-activate');
    }

    public static function getCloudCronStatus()
    {
        return self::cloudCronRequest('get-cron-status');
    }

    public static function deleteCloudCron()
    {
        return self::cloudCronRequest('wp-cron-delete');
    }

    public static function cloudCronRequest(string $slug)
    {
        try {
            $url = self::BASE_URL . $slug;

            $body = [
                'link'       => Config::get('SITE_URL') . static::WP_CRON_PATH,
                'licenseKey' => base64_encode(Config::getOption('license_data')['key']),
            ];

            $httpClient = new HttpClient();

            return $httpClient->request($url, 'POST', $body);
        } catch (Exception $e) {
            return (object) [
                'success'  => false,
                'response' => 'Error making external cron request',
            ];
        }
    }

    public static function getInterValueByUnit($scheduleUnit, $scheduleItem)
    {
        $data = [];
        if ($scheduleUnit === 'minute') {
            $data['interval'] = $scheduleItem['xMinutes'] ?? null;
        }

        if ($scheduleUnit === 'hour') {
            $data['interval'] = $scheduleItem['xHours'] ?? null;
            $data['minute'] = $scheduleItem['minute'] ?? null;
        }

        if ($scheduleUnit === 'day') {
            $data['interval'] = $scheduleItem['xDays'] ?? null;
            $data['time'] = $scheduleItem['time'] ?? null;
        }

        if ($scheduleUnit === 'week') {
            $data['interval'] = $scheduleItem['xWeeks'] ?? null;
            $data['time'] = $scheduleItem['time'] ?? null;
            $data['day'] = (new self())->getDayNumber($scheduleItem['weekday'] ?? 'Monday') ?? null;
        }

        if ($scheduleUnit === 'month') {
            $data['interval'] = $scheduleItem['xMonths'] ?? null;
            $data['time'] = $scheduleItem['time'] ?? null;
            $data['dayOfMonth'] = $scheduleItem['dayOfMonth'] ?? null;
        }

        return $data;
    }

    public static function getScheduleRunTime($scheduleUnit, $scheduleItem)
    {
        $currentTime = current_time('timestamp');

        $scheduleRunTime = time();

        $time = $scheduleItem['time'] ?? '00:00';

        $timeZone = DateTimeHelper::wp_timezone_string();

        switch ($scheduleUnit) {
            case 'minute':
                break;

            case 'hour':
                $scheduleRunTime = strtotime(date('Y-m-d H:' . ($scheduleItem['minute'] ?? '00') . ':00 ' . $timeZone, $currentTime));

                if ($scheduleRunTime <= $currentTime) {
                    $scheduleRunTime = strtotime('+1 hour', $scheduleRunTime);
                }

                break;

            case 'day':
                $scheduleRunTime = strtotime('today ' . $time);

                if ($scheduleRunTime < $currentTime) {
                    $scheduleRunTime = strtotime('tomorrow ' . $time);
                }

                break;

            case 'week':
                $weekDay = $scheduleItem['weekday'] ?? 1;

                $scheduleRunTime = strtotime("next {$weekDay} {$time}");

                if ($scheduleRunTime <= $currentTime) {
                    $scheduleRunTime = strtotime("next week {$weekDay} {$time}");
                }

                break;

            case 'month':
                $dayOfMonth = $scheduleItem['dayOfMonth'] ?? 1;

                $scheduleRunTime = strtotime('first day of next month +' . ($dayOfMonth - 1) . " days {$time}");

                if ($scheduleRunTime <= current_time('timestamp')) {
                    $scheduleRunTime = strtotime('first day of +2 month +' . ($dayOfMonth - 1) . " days {$time}");
                }

                break;

            default:
                break;
        }

        return $scheduleRunTime;
    }

    private function getDayNumber($day)
    {
        $days = [
            'Sunday'    => 0,
            'Monday'    => 1,
            'Tuesday'   => 2,
            'Wednesday' => 3,
            'Thursday'  => 4,
            'Friday'    => 5,
            'Saturday'  => 6,
        ];

        return $days[$day] ?? null;
    }
}
