<?php

namespace App\Support;

use App\Models\Setting;
use Illuminate\Support\Carbon;

class OfferProjectState
{
    public const KEY_ENABLED = 'offers_enabled';
    public const KEY_REOPEN_AT = 'offers_reopen_at';
    public const KEY_NOTICE = 'offers_closed_notice';

    public const DEFAULT_NOTICE = 'ড্রাইভ অফার প্রজেক্ট বর্তমানে বন্ধ।';

    /**
     * Get raw state from settings table without side effects.
     */
    public static function readRaw(): array
    {
        $rows = Setting::query()
            ->whereIn('key', [
                self::KEY_ENABLED,
                self::KEY_REOPEN_AT,
                self::KEY_NOTICE,
            ])
            ->pluck('value', 'key');

        $enabledRaw = (string) ($rows[self::KEY_ENABLED] ?? '1');
        $enabled = in_array(strtolower($enabledRaw), ['1', 'true', 'yes', 'on'], true);

        $reopenAt = self::parseDatetime($rows[self::KEY_REOPEN_AT] ?? null);

        $notice = trim((string) ($rows[self::KEY_NOTICE] ?? ''));
        if ($notice === '') {
            $notice = self::DEFAULT_NOTICE;
        }

        return [
            'enabled' => $enabled,
            'reopen_at' => $reopenAt,
            'notice' => $notice,
        ];
    }

    /**
     * Runtime state with optional auto-enable when reopen time is reached.
     */
    public static function resolveRuntimeState(bool $autoEnable = true): array
    {
        $state = self::readRaw();

        if (
            $autoEnable
            && !$state['enabled']
            && $state['reopen_at'] instanceof Carbon
            && now()->greaterThanOrEqualTo($state['reopen_at'])
        ) {
            self::setEnabled(true);
            self::setReopenAt(null);

            $state['enabled'] = true;
            $state['reopen_at'] = null;
        }

        return $state;
    }

    public static function updateFromAdmin(bool $enabled, ?string $reopenAtInput, ?string $notice): void
    {
        self::setEnabled($enabled);

        if ($enabled) {
            self::setReopenAt(null);
        } else {
            self::setReopenAt(self::parseDatetime($reopenAtInput));
        }

        $finalNotice = trim((string) $notice);
        if ($finalNotice === '') {
            $finalNotice = self::DEFAULT_NOTICE;
        }

        self::setNotice($finalNotice);
    }

    public static function formatForDisplay(?Carbon $datetime): ?string
    {
        if (!$datetime) {
            return null;
        }

        return $datetime->format('d M Y, h:i A');
    }

    private static function parseDatetime(?string $value): ?Carbon
    {
        $value = trim((string) $value);
        if ($value === '') {
            return null;
        }

        try {
            return Carbon::parse($value);
        } catch (\Throwable $e) {
            return null;
        }
    }

    private static function setEnabled(bool $enabled): void
    {
        Setting::updateOrCreate(
            ['key' => self::KEY_ENABLED],
            ['value' => $enabled ? '1' : '0']
        );
    }

    private static function setReopenAt(?Carbon $datetime): void
    {
        Setting::updateOrCreate(
            ['key' => self::KEY_REOPEN_AT],
            ['value' => $datetime?->format('Y-m-d H:i:s') ?? '']
        );
    }

    private static function setNotice(string $notice): void
    {
        Setting::updateOrCreate(
            ['key' => self::KEY_NOTICE],
            ['value' => $notice]
        );
    }
}
