<?php

namespace GriffinForms\Frontend\Security\Guards;

class SubmissionEditWindowGuard implements GuardInterface
{
    public function getKey(): string
    {
        return 'submission_edit_window';
    }

    public function getPriority(): int
    {
        return 25;
    }

    public function check(int $form_id, array $context = []): array
    {
        if ($form_id <= 0 || empty($context['is_edit'])) {
            return ['blocked' => false];
        }

        $form = new \GriffinForms\Items\Form();
        if (!$form->loadItem($form_id)) {
            return ['blocked' => false];
        }

        $policy = $form->getProp('submission_edit');
        if (!is_array($policy) || empty($policy['toggle'])) {
            return ['blocked' => false];
        }

        $time = isset($policy['time']) && is_array($policy['time']) ? $policy['time'] : [];
        $mode = isset($time['mode']) ? sanitize_key((string) $time['mode']) : 'none';
        if (!in_array($mode, array('none', 'window', 'duration'), true) || $mode === 'none') {
            return ['blocked' => false];
        }

        $now = current_time('timestamp', true);

        if ($mode === 'window') {
            $start_ts = isset($time['start_ts']) ? absint($time['start_ts']) : 0;
            $end_ts = isset($time['end_ts']) ? absint($time['end_ts']) : 0;
            $pre_message = isset($time['pre_message']) ? (string) $time['pre_message'] : '';
            $post_message = isset($time['post_message']) ? (string) $time['post_message'] : '';

            if ($start_ts > 0 && $now < $start_ts) {
                return [
                    'blocked' => true,
                    'message' => $pre_message !== '' ? $pre_message : __('This submission is not editable yet. Please check back later.', 'griffinforms-form-builder'),
                ];
            }

            if ($end_ts > 0 && $now > $end_ts) {
                return [
                    'blocked' => true,
                    'message' => $post_message !== '' ? $post_message : __('This submission can no longer be edited.', 'griffinforms-form-builder'),
                ];
            }
        } elseif ($mode === 'duration') {
            $duration_days = isset($time['duration_days']) ? absint($time['duration_days']) : 0;
            $duration_hours = isset($time['duration_hours']) ? absint($time['duration_hours']) : 0;
            $post_message = isset($time['post_message']) ? (string) $time['post_message'] : '';
            $duration_seconds = ($duration_days * DAY_IN_SECONDS) + ($duration_hours * HOUR_IN_SECONDS);

            if ($duration_seconds <= 0) {
                return ['blocked' => false];
            }

            $created_ts = $this->getSubmissionCreatedTimestamp($context);
            if ($created_ts <= 0) {
                return [
                    'blocked' => true,
                    'message' => __('This submission cannot be edited right now.', 'griffinforms-form-builder'),
                ];
            }

            if ($now > ($created_ts + $duration_seconds)) {
                return [
                    'blocked' => true,
                    'message' => $post_message !== '' ? $post_message : __('This submission can no longer be edited.', 'griffinforms-form-builder'),
                ];
            }
        }

        return ['blocked' => false];
    }

    private function getSubmissionCreatedTimestamp(array $context): int
    {
        $submission = isset($context['submission_context']['submission']) && is_array($context['submission_context']['submission'])
            ? $context['submission_context']['submission']
            : [];

        $created = isset($submission['created']) ? (string) $submission['created'] : '';
        if ($created === '') {
            $submission_meta = isset($context['submission_context']['submission_meta']) && is_array($context['submission_context']['submission_meta'])
                ? $context['submission_context']['submission_meta']
                : [];
            $created = isset($submission_meta['created']) ? (string) $submission_meta['created'] : '';
        }

        if ($created === '') {
            return 0;
        }

        try {
            return (new \DateTimeImmutable($created, new \DateTimeZone('UTC')))->getTimestamp();
        } catch (\Exception $exception) {
            return 0;
        }
    }
}
