<?php

namespace ZenoChatbot\Http\Controller\Api\V1;

use ZenoChatbot\Helper\ExternalSources;
use ZenoChatbot\Helper\MediaResources;
use ZenoChatbot\Helper\Security;
use ZenoChatbot\Helper\Settings;

/**
 * Data Source Settings API Controller
 */
class DataSourceSettingsController
{
    /**
     * Get data source settings
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function get(\WP_REST_Request $request)
    {
        try {
            // Get external sources
            $external_sources = ExternalSources::getAll();

            $settings = [
                'internal_enabled' => Settings::get('data_source.internal_enabled', 'yes'),
                'external_enabled' => Settings::get('data_source.external_enabled', 'yes'),
                'selected_post_types' => Settings::get('data_source.selected_post_types', ['post', 'page']),
                'include_excerpts' => Settings::get('data_source.include_excerpts', true),
                'include_content' => Settings::get('data_source.include_content', true),
                'auto_update' => Settings::get('data_source.auto_update', true),
                'external_sources' => $external_sources,
                'source_count' => count($external_sources)
            ];

            return [
                'success' => true,
                'data' => $settings
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to retrieve data source settings',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Save data source settings
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function save(\WP_REST_Request $request)
    {
        // Verify user permissions
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {

            // Get parameters
            $internal_enabled = sanitize_text_field($request->get_param('internal_enabled'));
            $external_enabled = sanitize_text_field($request->get_param('external_enabled'));
            $selected_post_types = $request->get_param('selected_post_types');
            $include_excerpts = $request->get_param('include_excerpts');
            $include_content = $request->get_param('include_content');
            $auto_update = $request->get_param('auto_update');

            // Validate and sanitize selected_post_types
            if (!is_array($selected_post_types)) {
                $selected_post_types = [];
            }
            $selected_post_types = array_map('sanitize_text_field', $selected_post_types);

            // Save settings
            Settings::update('data_source.internal_enabled', $internal_enabled === 'yes' ? 'yes' : 'no');
            Settings::update('data_source.external_enabled', $external_enabled === 'yes' ? 'yes' : 'no');
            Settings::update('data_source.selected_post_types', $selected_post_types);
            Settings::update('data_source.include_excerpts', (bool) $include_excerpts);
            Settings::update('data_source.include_content', (bool) $include_content);
            Settings::update('data_source.auto_update', (bool) $auto_update);

            return [
                'success' => true,
                'message' => 'Data source settings saved successfully'
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to save data source settings',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Get available post types
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function getPostTypes(\WP_REST_Request $request)
    {
        try {
            $post_types = get_post_types(['public' => true], 'objects');
            $available_types = [];

            foreach ($post_types as $post_type) {
                // Skip attachments
                if ($post_type->name === 'attachment') {
                    continue;
                }

                $count = wp_count_posts($post_type->name);
                $published_count = isset($count->publish) ? $count->publish : 0;

                $available_types[] = [
                    'name' => $post_type->name,
                    'label' => $post_type->labels->name,
                    'count' => $published_count,
                    'description' => $post_type->description ?: $post_type->labels->name
                ];
            }

            return [
                'success' => true,
                'data' => [
                    'post_types' => $available_types
                ]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to retrieve post types',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Add external source
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function addExternalSource(\WP_REST_Request $request)
    {
        // Verify user permissions
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {

            // Get parameters
            $title = sanitize_text_field($request->get_param('title'));
            $link = esc_url_raw($request->get_param('link'));
            $context = sanitize_textarea_field($request->get_param('context'));

            // Validate required fields
            if (empty($title)) {
                return [
                    'success' => false,
                    'message' => 'Source title is required',
                    'status' => 400
                ];
            }

            if (empty($link)) {
                return [
                    'success' => false,
                    'message' => 'Source link is required',
                    'status' => 400
                ];
            }

            // Validate URL format
            if (!filter_var($link, FILTER_VALIDATE_URL)) {
                return [
                    'success' => false,
                    'message' => 'Please enter a valid URL',
                    'status' => 400
                ];
            }

            // Check for duplicate
            if (ExternalSources::exists($link)) {
                return [
                    'success' => false,
                    'message' => 'This URL has already been added',
                    'status' => 400
                ];
            }

            // Add the source
            $result = ExternalSources::add($title, $link, $context);

            if (!$result) {
                return [
                    'success' => false,
                    'message' => 'Failed to add external source',
                    'status' => 500
                ];
            }

            // Return updated list
            $external_sources = ExternalSources::getAll();

            return [
                'success' => true,
                'message' => 'External source added successfully',
                'data' => [
                    'external_sources' => $external_sources,
                    'source_count' => count($external_sources)
                ]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to add external source',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Remove external source
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function removeExternalSource(\WP_REST_Request $request)
    {
        // Verify user permissions
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {

            // Get link parameter
            $link = esc_url_raw($request->get_param('link'));

            if (empty($link)) {
                return [
                    'success' => false,
                    'message' => 'Source link is required',
                    'status' => 400
                ];
            }

            // Remove the source
            $result = ExternalSources::remove($link);

            if (!$result) {
                return [
                    'success' => false,
                    'message' => 'Failed to remove external source',
                    'status' => 500
                ];
            }

            // Return updated list
            $external_sources = ExternalSources::getAll();

            return [
                'success' => true,
                'message' => 'External source removed successfully',
                'data' => [
                    'external_sources' => $external_sources,
                    'source_count' => count($external_sources)
                ]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to remove external source',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Update external source
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function updateExternalSource(\WP_REST_Request $request)
    {
        // Verify user permissions
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {

            // Get parameters
            $oldLink = esc_url_raw($request->get_param('old_link'));
            $title = sanitize_text_field($request->get_param('title'));
            $link = esc_url_raw($request->get_param('link'));
            $context = sanitize_textarea_field($request->get_param('context'));

            // Validate required fields
            if (empty($oldLink)) {
                return [
                    'success' => false,
                    'message' => 'Original source link is required',
                    'status' => 400
                ];
            }

            if (empty($title)) {
                return [
                    'success' => false,
                    'message' => 'Source title is required',
                    'status' => 400
                ];
            }

            if (empty($link)) {
                return [
                    'success' => false,
                    'message' => 'Source link is required',
                    'status' => 400
                ];
            }

            // Validate URL format
            if (!filter_var($link, FILTER_VALIDATE_URL)) {
                return [
                    'success' => false,
                    'message' => 'Please enter a valid URL',
                    'status' => 400
                ];
            }

            // Update the source
            $result = ExternalSources::update($oldLink, $title, $link, $context);

            if (!$result) {
                return [
                    'success' => false,
                    'message' => 'Failed to update external source or source not found',
                    'status' => 500
                ];
            }

            // Return updated list
            $external_sources = ExternalSources::getAll();

            return [
                'success' => true,
                'message' => 'External source updated successfully',
                'data' => [
                    'external_sources' => $external_sources,
                    'source_count' => count($external_sources)
                ]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to update external source',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Get media resources
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function getMediaResources(\WP_REST_Request $request)
    {
        try {
            $resources = MediaResources::getAll();

            return [
                'success' => true,
                'data' => [
                    'resources' => $resources,
                    'count' => count($resources),
                    'allowed_types' => MediaResources::getAllowedExtensions()
                ]
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to retrieve media resources',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Add media resource(s)
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function addMediaResource(\WP_REST_Request $request)
    {
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {
            $attachmentIds = $request->get_param('attachment_ids');

            if (empty($attachmentIds)) {
                return [
                    'success' => false,
                    'message' => 'No attachments provided',
                    'status' => 400
                ];
            }

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

            $attachmentIds = array_map('intval', $attachmentIds);
            $result = MediaResources::addMultiple($attachmentIds);

            $resources = MediaResources::getAll();

            return [
                'success' => $result['success'],
                'message' => $result['message'],
                'data' => [
                    'resources' => $resources,
                    'count' => count($resources),
                    'added' => $result['added'],
                    'skipped' => $result['skipped']
                ]
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to add media resource',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Remove media resource
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function removeMediaResource(\WP_REST_Request $request)
    {
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403
            ];
        }

        try {
            $attachmentId = (int) $request->get_param('attachment_id');

            if (empty($attachmentId)) {
                return [
                    'success' => false,
                    'message' => 'Attachment ID is required',
                    'status' => 400
                ];
            }

            $removed = MediaResources::remove($attachmentId);

            if (!$removed) {
                return [
                    'success' => false,
                    'message' => 'Resource not found or could not be removed',
                    'status' => 404
                ];
            }

            $resources = MediaResources::getAll();

            return [
                'success' => true,
                'message' => 'Resource removed successfully',
                'data' => [
                    'resources' => $resources,
                    'count' => count($resources)
                ]
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to remove media resource',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }
}
