<?php

namespace BitApps\PiPro\src\Integrations\AdvancedCustomFields;

use BitApps\Pi\src\Flow\NodeInfoProvider;
use BitApps\PiPro\Deps\BitApps\WPValidator\Validator;

if (!\defined('ABSPATH')) {
    exit;
}

final class AdvancedCustomFieldsService
{
    private $nodeInfoProvider;

    public function __construct(NodeInfoProvider $nodeInfoProvider)
    {
        $this->nodeInfoProvider = $nodeInfoProvider;
    }

    public function getPostAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'post_id'    => ['required', 'integer'],
            'field_name' => ['required', 'string'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);

        if ($errors) {
            return $errors;
        }

        if (!\function_exists('get_field')) {
            return [
                'response'    => 'ACF function get_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $fieldName = $fieldMappings['field_name'];
        $postId = \intval($fieldMappings['post_id']);

        $response = [
            'post_id'     => $postId,
            'field_name'  => $fieldName,
            'field_value' => get_field($fieldName, $postId),
        ];

        return [
            'response'    => $response,
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function getUserAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'user_id'    => ['required', 'integer'],
            'field_name' => ['required', 'string'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('get_field')) {
            return [
                'response'    => 'ACF function get_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $fieldName = $fieldMappings['field_name'];
        $userId = \intval($fieldMappings['user_id']);

        $response = [
            'user_id'     => $userId,
            'field_name'  => $fieldName,
            'field_value' => get_field($fieldName, 'user_' . $userId),
        ];

        return [
            'response'    => $response,
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function getOptionAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'field_name' => ['required', 'string'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('get_field')) {
            return [
                'response'    => 'ACF function get_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $response = [
            'field_name'  => $fieldMappings['field_name'],
            'field_value' => get_field($fieldMappings['field_name'], 'option'),
        ];

        return [
            'response'    => $response,
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function updatePostAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'post_id'     => ['required', 'integer'],
            'field_name'  => ['required', 'string'],
            'field_value' => ['required'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('update_field')) {
            return [
                'response'    => 'ACF function update_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $isUpdated = update_field(
            $fieldMappings['field_name'],
            $fieldMappings['field_value'],
            \intval($fieldMappings['post_id'])
        );

        if (!$isUpdated) {
            return [
                'response'    => 'Failed to update ACF field. Please check the field name and post ID.',
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }

        return [
            'response'    => __('ACF field updated successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function updateUserAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'user_id'     => ['required', 'integer'],
            'field_name'  => ['required', 'string'],
            'field_value' => ['required'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('update_field')) {
            return [
                'response'    => 'ACF function update_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $isUpdated = update_field(
            $fieldMappings['field_name'],
            $fieldMappings['field_value'],
            'user_' . \intval($fieldMappings['user_id'])
        );

        if (!$isUpdated) {
            return [
                'response'    => 'Failed to update ACF field. Please check the field name and user ID.',
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }

        return [
            'response'    => __('ACF field updated successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function updateOptionAcfValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'field_name'  => ['required', 'string'],
            'field_value' => ['required'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('update_field')) {
            return [
                'response'    => 'ACF function update_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $isUpdated = update_field(
            $fieldMappings['field_name'],
            $fieldMappings['field_value'],
            'option'
        );

        if (!$isUpdated) {
            return [
                'response'    => 'Failed to update ACF option field. Please check the field name.',
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }

        return [
            'response'    => __('ACF option field updated successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function updateGroupFieldValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'post_id'        => ['required', 'integer'],
            'group_name'     => ['required', 'string'],
            'sub_field_name' => ['required', 'string'],
            'field_value'    => ['required'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);
        if ($errors) {
            return $errors;
        }

        if (!\function_exists('update_field') || !\function_exists('get_field')) {
            return [
                'response'    => 'ACF function update_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $postId = \intval($fieldMappings['post_id']);
        $groupName = $fieldMappings['group_name'];
        $subFieldName = $fieldMappings['sub_field_name'];
        $fieldValue = $fieldMappings['field_value'];

        $groupData = get_field($groupName, $postId);

        if (!\is_array($groupData)) {
            $groupData = [];
        }

        $groupData[$subFieldName] = $fieldValue;

        if (!update_field($groupName, $groupData, $postId)) {
            return [
                'response'    => 'Failed to update ACF group field. Please check the group name and post ID.',
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }

        return [
            'response'    => __('ACF group field updated successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public function updateRepeaterFieldValue()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'post_id'        => ['required', 'integer'],
            'repeater_name'  => ['required', 'string'],
            'row_index'      => ['required', 'integer'],
            'sub_field_name' => ['required', 'string'],
            'field_value'    => ['required'],
        ];

        $errors = self::validateFieldMap($fieldMappings, $rules);

        if ($errors) {
            return $errors;
        }

        if (!\function_exists('update_field') || !\function_exists('get_field')) {
            return [
                'response'    => 'ACF function update_field or get_field does not exist. Please ensure ACF plugin is installed and activated.',
                'payload'     => $fieldMappings,
                'status_code' => 500
            ];
        }

        $postId = \intval($fieldMappings['post_id']);
        $rowIndex = \intval($fieldMappings['row_index']);
        $repeaterName = $fieldMappings['repeater_name'];
        $subFieldName = $fieldMappings['sub_field_name'];
        $fieldValue = $fieldMappings['field_value'];

        $repeaterData = get_field($repeaterName, $postId);

        if (!\is_array($repeaterData)) {
            $repeaterData = [];
        }

        if (!isset($repeaterData[$rowIndex])) {
            $repeaterData[$rowIndex] = [];
        }

        $repeaterData[$rowIndex][$subFieldName] = $fieldValue;

        if (!update_field($repeaterName, $repeaterData, $postId)) {
            return [
                'response'    => 'Failed to update ACF repeater field. Please check the repeater name and post ID.',
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }

        return [
            'response'    => __('ACF repeater field updated successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    public static function validateFieldMap($fieldMappings, $validationRules, $payload = null)
    {
        $validator = new Validator();
        $validation = $validator->make($fieldMappings, $validationRules);

        if ($validation->fails()) {
            return [
                'response'    => $validation->errors(),
                'payload'     => $payload ?? $fieldMappings,
                'status_code' => 400
            ];
        }
    }
}
