<?php

namespace GriffinForms\Admin\Secure;

class Form extends \GriffinForms\Admin\Secure\Format
{
    protected function secureFolder($id)
    {
        return $this->secureId($id);
    }
    
    protected function secureAutofill($value)
    {
        return $this->secureToggle($value);
    }

    protected function secureComplianceMode($value): int
    {
        return $this->secureToggle($value);
    }

    protected function secureComplianceProfile($value): string
    {
        $val = is_string($value) ? sanitize_text_field($value) : '';
        $allowed = $this->choices->getChoices('compliance_profile', false);
        if (!in_array($val, $allowed, true)) {
            $val = 'standard';
        }
        return $val;
    }

    protected function secureComplianceFlags($value): array
    {
        if (!is_array($value)) {
            return array(
                'mode' => 'inherit',
                'store_ip' => 0,
                'store_user_agent' => 0,
                'retention_days' => 0
            );
        }

        $mode_raw = isset($value['mode']) ? sanitize_text_field($value['mode']) : '';
        if (!in_array($mode_raw, array('inherit', 'custom'), true)) {
            $mode_raw = empty($value) ? 'inherit' : 'custom';
        }

        $store_ip = !empty($value['store_ip']) ? 1 : 0;
        $store_user_agent = !empty($value['store_user_agent']) ? 1 : 0;
        $retention_days = isset($value['retention_days']) ? absint($value['retention_days']) : 0;

        return array(
            'mode' => $mode_raw,
            'store_ip' => $store_ip,
            'store_user_agent' => $store_user_agent,
            'retention_days' => max(0, $retention_days)
        );
    }
    
    protected function secureLimitEntries($value)
    {
        if (is_array($value)) {
            
            if (isset($value['toggle'])) {
                $secured_value['toggle'] = $this->secureToggle($value['toggle']);
            } else {
                $secured_value['toggle'] = false;
            }
            
            if (isset($value['limit'])) {
                $secured_value['limit'] = absint($value['limit']);
            } else {
                $secured_value['limit'] = 0;
            }
            
            if (isset($value['message'])) {
                $secured_value['message'] = sanitize_textarea_field($value['message']);
            } else {
                $secured_value['message'] = '';
            }
                        
        } else {
            $secured_value = array('toggle' => false, 'limit' => 0, 'message' => '');
        }
        
        return $secured_value;
    }

    protected function secureAvailabilityWindow($value)
    {
        $defaults = array(
            'toggle' => false,
            'start_utc' => '',
            'end_utc' => '',
            'pre_message' => '',
            'post_message' => ''
        );

        if (!is_array($value)) {
            return $defaults;
        }

        $secured = $defaults;
        $secured['toggle'] = isset($value['toggle']) ? $this->secureToggle($value['toggle']) : false;

        if ($secured['toggle']) {
            $start_date = isset($value['start_date']) ? sanitize_text_field($value['start_date']) : '';
            $start_time = isset($value['start_time']) ? sanitize_text_field($value['start_time']) : '';
            $end_date = isset($value['end_date']) ? sanitize_text_field($value['end_date']) : '';
            $end_time = isset($value['end_time']) ? sanitize_text_field($value['end_time']) : '';

            $secured['start_utc'] = $this->convertLocalToUtc($start_date, $start_time, 'start');
            $secured['end_utc'] = $this->convertLocalToUtc($end_date, $end_time, 'end');

            $pre_message = isset($value['pre_message']) ? sanitize_textarea_field($value['pre_message']) : '';
            $post_message = isset($value['post_message']) ? sanitize_textarea_field($value['post_message']) : '';

            $secured['pre_message'] = $pre_message !== '' ? $pre_message : __('This form is not accepting submissions yet. Please check back later.', 'griffinforms-form-builder');
            $secured['post_message'] = $post_message !== '' ? $post_message : __('This form is no longer accepting submissions.', 'griffinforms-form-builder');
        }

        return $secured;
    }

    protected function secureProgressBar($value): array
    {
        $defaults = array(
            'toggle' => false,
            'style' => 'stepper',
            'show_page_headings' => true
        );

        if (!is_array($value)) {
            return $defaults;
        }

        $style = isset($value['style']) ? sanitize_text_field($value['style']) : 'stepper';
        if (!in_array($style, array('stepper', 'tabs'), true)) {
            $style = 'stepper';
        }

        return array(
            'toggle' => !empty($value['toggle']),
            'style' => $style,
            'show_page_headings' => isset($value['show_page_headings']) ? (bool) $value['show_page_headings'] : true
        );
    }

    private function convertLocalToUtc(string $date, string $time, string $boundary): string
    {
        $date = trim($date);
        if ($date === '') {
            return '';
        }

        $time = trim($time);
        if ($time === '') {
            $time = $boundary === 'end' ? '23:59' : '00:00';
        }

        $timezone = wp_timezone();
        $formats = array('m/d/Y H:i', 'm/d/y H:i');
        foreach ($formats as $format) {
            $dt = \DateTimeImmutable::createFromFormat($format, $date . ' ' . $time, $timezone);
            if ($dt instanceof \DateTimeImmutable) {
                return $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
            }
        }

        return '';
    }

    private function convertLocalDateTimeToUtcTimestamp(string $date, string $time, string $boundary): int
    {
        $date = trim($date);
        if ($date === '') {
            return 0;
        }

        $time = trim($time);
        if ($time === '') {
            $time = $boundary === 'end' ? '23:59' : '00:00';
        }

        $timezone = wp_timezone();
        $formats = array('m/d/Y H:i', 'm/d/y H:i');
        foreach ($formats as $format) {
            $dt = \DateTimeImmutable::createFromFormat($format, $date . ' ' . $time, $timezone);
            if ($dt instanceof \DateTimeImmutable) {
                return $dt->setTimezone(new \DateTimeZone('UTC'))->getTimestamp();
            }
        }

        return 0;
    }
    
    protected function secureAccessLevel($value)
    {
        $secured_value = array();
        $valid_public_access_choices = array_keys($this->choices->getChoices('toggle_public_access'));

        if (is_array($value)) {
            
            if (isset($value['access'])) {
                                
                if (in_array($value['access'], $valid_public_access_choices)) {
                    
                    $secured_value['access'] = $value['access'];
                    
                } else {
                    
                    $secured_value['access'] = $valid_public_access_choices[0];
                    
                }
                
            } else {
                
                $secured_value['access'] = $valid_public_access_choices[0];
            }
            
            if (isset($value['role_access'])) {
                
                $secured_value['role_access'] = $this->secureToggle($value['role_access']);
                
            } else {
                
                $secured_value['role_access'] = 0;
            }
            
            if (isset($value['roles'])) {
                
                $secured_value['roles'] = $value['roles'];
                
            } else {
                
                $secured_value['roles'] = '';
            }
                        
        } else {
            
            $secured_value = array(
                'public_access' => $valid_public_access_choices[0],
                'role_access' => 0, 
                'message' => ''
            );
        }
        
        return $secured_value;
    }

    protected function secureSubmissionEdit($value): array
    {
        $defaults = array(
            'toggle' => false,
            'original_submitters' => false,
            'email_owners' => false,
            'role_access' => false,
            'user_access' => false,
            'email_fields' => array(),
            'roles' => array(),
            'users' => array(),
            'max_edits' => 0,
            'time' => array(
                'mode' => 'none',
                'start_ts' => 0,
                'end_ts' => 0,
                'duration_days' => 0,
                'duration_hours' => 0,
                'pre_message' => '',
                'post_message' => '',
            ),
        );

        if (!is_array($value)) {
            return $defaults;
        }

        $secured = $defaults;
        $secured['toggle'] = $this->secureToggle($value['toggle'] ?? false);

        if (!$secured['toggle']) {
            return $secured;
        }

        $secured['original_submitters'] = $this->secureToggle($value['original_submitters'] ?? false);
        $secured['email_owners'] = $this->secureToggle($value['email_owners'] ?? false);
        $secured['role_access'] = $this->secureToggle($value['role_access'] ?? false);
        $secured['user_access'] = $this->secureToggle($value['user_access'] ?? false);

        $email_fields = $value['email_fields'] ?? array();
        if (!is_array($email_fields)) {
            $email_fields = is_string($email_fields) ? preg_split('/[\s,]+/', $email_fields) : array();
        }
        $secured['email_fields'] = array_values(array_filter(array_map('absint', (array) $email_fields)));

        $roles = $value['roles'] ?? array();
        if (!is_array($roles)) {
            $roles = is_string($roles) ? preg_split('/[\s,]+/', $roles) : array();
        }
        $secured['roles'] = array_values(array_filter(array_map('sanitize_key', (array) $roles)));

        $users = $value['users'] ?? array();
        if (!is_array($users)) {
            $users = is_string($users) ? preg_split('/[\s,]+/', $users) : array();
        }
        $secured['users'] = array_values(array_filter(array_map('absint', (array) $users)));

        $max_edits = isset($value['max_edits']) ? absint($value['max_edits']) : 0;
        $secured['max_edits'] = max(0, $max_edits);

        $secured['time'] = $this->secureSubmissionEditTime($value['time'] ?? array());

        if (
            empty($secured['original_submitters']) &&
            empty($secured['email_owners']) &&
            empty($secured['role_access']) &&
            empty($secured['user_access'])
        ) {
            $secured['toggle'] = false;
            $secured['email_fields'] = array();
            $secured['roles'] = array();
            $secured['users'] = array();
            $secured['max_edits'] = 0;
            $secured['time'] = $defaults['time'];
        }

        return $secured;
    }

    protected function secureSubmissionEditTime($value): array
    {
        $defaults = array(
            'mode' => 'none',
            'start_ts' => 0,
            'end_ts' => 0,
            'duration_days' => 0,
            'duration_hours' => 0,
            'pre_message' => '',
            'post_message' => '',
        );

        if (!is_array($value)) {
            return $defaults;
        }

        $mode = isset($value['mode']) ? sanitize_key((string) $value['mode']) : 'none';
        if (!in_array($mode, array('none', 'window', 'duration'), true)) {
            $mode = 'none';
        }

        $secured = $defaults;
        $secured['mode'] = $mode;

        if ($mode === 'window') {
            $start_date = isset($value['start_date']) ? sanitize_text_field((string) $value['start_date']) : '';
            $start_time = isset($value['start_time']) ? sanitize_text_field((string) $value['start_time']) : '';
            $end_date = isset($value['end_date']) ? sanitize_text_field((string) $value['end_date']) : '';
            $end_time = isset($value['end_time']) ? sanitize_text_field((string) $value['end_time']) : '';

            $secured['start_ts'] = $this->convertLocalDateTimeToUtcTimestamp($start_date, $start_time, 'start');
            $secured['end_ts'] = $this->convertLocalDateTimeToUtcTimestamp($end_date, $end_time, 'end');
            $secured['pre_message'] = isset($value['pre_message']) ? sanitize_textarea_field((string) $value['pre_message']) : '';
            $secured['post_message'] = isset($value['post_message']) ? sanitize_textarea_field((string) $value['post_message']) : '';
        } elseif ($mode === 'duration') {
            $secured['duration_days'] = isset($value['duration_days']) ? absint($value['duration_days']) : 0;
            $secured['duration_hours'] = isset($value['duration_hours']) ? absint($value['duration_hours']) : 0;
            $secured['pre_message'] = '';
            $secured['post_message'] = isset($value['post_message']) ? sanitize_textarea_field((string) $value['post_message']) : '';

            if ($secured['duration_days'] === 0 && $secured['duration_hours'] === 0) {
                $secured['mode'] = 'none';
            }
        }

        return $secured;
    }
    
    protected function secureUserAction($value)
    {
        return $value;
    }
    
    protected function secureAutoResponder($value)
    {
        $secured_mappings = array();

        if (is_string($value) && !empty($value)) {
            $decoded = json_decode($value, true);

            if (is_array($decoded)) {
                foreach ($decoded as $mapping) {
                    if (
                        is_array($mapping) &&
                        isset($mapping['email_field_id'], $mapping['message_id']) &&
                        is_numeric($mapping['email_field_id']) &&
                        is_numeric($mapping['message_id'])
                    ) {
                        $secured_mappings[] = array(
                            'email_field_id' => absint($mapping['email_field_id']),
                            'message_id' => absint($mapping['message_id'])
                        );
                    }
                }
            }
        }

        return json_encode($secured_mappings);
    }
    
    protected function secureAlertEmails($emails)
    {
        if (!is_array($emails)) {
            return [];
        }

        $secured = [];
        $keys = array_keys($emails);
        $is_assoc = $keys !== range(0, count($emails) - 1);

        if ($is_assoc) {
            foreach ($emails as $email => $message_id) {
                $clean_email = sanitize_email($email);
                if (empty($clean_email)) {
                    continue;
                }
                $secured[$clean_email] = absint($message_id);
            }
            return $secured;
        }

        foreach ($emails as $email) {
            $clean_email = sanitize_email($email);
            if (!empty($clean_email)) {
                $secured[$clean_email] = 0;
            }
        }

        return $secured;
    }
    
    protected function secureSaveEntries($value)
    {
        $valid_values = array_keys($this->choices->getChoices('save_entries'));
        if(in_array($value, $valid_values)) {
            return $value;
        }
    }
    
    protected function secureFormStyle($value)
    {
        return $value;
    }
}
