<?php

namespace FluentCrm\App\Http\Controllers;

use FluentCrm\App\Models\Meta;
use FluentCrm\Framework\Support\Arr;
use FluentCrm\Framework\Http\Request\Request;

class EmailPatternController extends Controller
{
    private $objectType = 'email_pattern';
    private $categoryObjectType = 'email_pattern_category';

    public function index(Request $request)
    {
        $query = Meta::where('object_type', $this->objectType)
            ->orderBy('id', 'desc');

        if ($search = $request->getSafe('search', 'sanitize_text_field')) {
            // Escape LIKE wildcards (%, _) so the term matches literally, not as wildcards.
            global $wpdb;
            $query->where('value', 'LIKE', '%' . $wpdb->esc_like($search) . '%');
        }

        $patterns = $query->paginate();

        $formattedPatterns = [];
        foreach ($patterns as $pattern) {
            $formattedPatterns[] = $this->formatPattern($pattern);
        }

        return $this->sendSuccess([
            'patterns' => [
                'data'  => $formattedPatterns,
                'total' => $patterns->total()
            ]
        ]);
    }

    public function show(Request $request, $id)
    {
        $pattern = Meta::where('object_type', $this->objectType)
            ->where('id', $id)
            ->firstOrFail();

        return $this->sendSuccess([
            'pattern' => $this->formatPattern($pattern)
        ]);
    }

    /**
     * Return patterns in wp_block REST format for the editor middleware.
     */
    public function indexWpFormat(Request $request)
    {
        $patterns = Meta::where('object_type', $this->objectType)
            ->orderBy('id', 'desc')
            ->get();

        $categoryMap = $this->getCategoryMap();
        $formatted = [];
        foreach ($patterns as $pattern) {
            $formatted[] = $this->formatAsWpBlock($pattern, $categoryMap);
        }

        return $formatted;
    }

    public function store(Request $request)
    {
        $this->validate($request->all(), [
            'title'   => 'required|string',
            'content' => 'required|string',
        ]);

        $title = sanitize_text_field($request->get('title'));
        $content = wp_kses_post($request->get('content'));
        $category = sanitize_text_field($request->get('category', ''));
        $description = sanitize_text_field($request->get('description', ''));
        $syncStatus = sanitize_text_field($request->get('sync_status', 'unsynced'));

        $slug = 'fluentcrm/' . sanitize_title($title . '-' . uniqid());

        $pattern = Meta::create([
            'object_type' => $this->objectType,
            'object_id'   => get_current_user_id(),
            'key'         => $slug,
            'value'       => [
                'title'       => $title,
                'content'     => $content,
                'category'    => $category,
                'description' => $description,
                'sync_status' => $syncStatus,
            ],
        ]);

        return $this->sendSuccess([
            'message' => __('Pattern saved successfully', 'fluent-crm'),
            'pattern' => $this->formatPattern($pattern),
        ]);
    }

    /**
     * Store a pattern from wp_block format (called by editor middleware).
     */
    public function storeWpFormat(Request $request)
    {
        $title = $request->get('title', '');
        if (is_array($title)) {
            $title = Arr::get($title, 'raw', '');
        }
        $title = sanitize_text_field($title);

        $content = $request->get('content', '');
        if (is_array($content)) {
            $content = Arr::get($content, 'raw', '');
        }
        $content = wp_kses_post($content);

        if (!$title && !$content) {
            return $this->sendError([
                'message' => __('Title or content is required', 'fluent-crm')
            ]);
        }

        if (!$title) {
            $title = __('Untitled Pattern', 'fluent-crm');
        }

        $meta = $request->get('meta', []);
        $syncStatus = Arr::get($meta, 'wp_pattern_sync_status', '');
        $syncStatus = sanitize_text_field($syncStatus);

        $categoryIds = (array) $request->get('wp_pattern_category', []);
        $categoryName = $this->resolveCategoryName($categoryIds);

        $slug = 'fluentcrm/' . sanitize_title($title . '-' . uniqid());

        $pattern = Meta::create([
            'object_type' => $this->objectType,
            'object_id'   => get_current_user_id(),
            'key'         => $slug,
            'value'       => [
                'title'       => $title,
                'content'     => $content,
                'category'    => $categoryName,
                'description' => '',
                'sync_status' => $syncStatus,
            ],
        ]);

        $categoryMap = $this->getCategoryMap();
        return $this->formatAsWpBlock($pattern, $categoryMap);
    }

    public function update(Request $request, $id)
    {
        $pattern = Meta::where('object_type', $this->objectType)
            ->where('id', $id)
            ->firstOrFail();

        $value = $pattern->value;

        if ($title = $request->get('title')) {
            if (is_array($title)) {
                $title = Arr::get($title, 'raw', '');
            }
            $value['title'] = sanitize_text_field($title);
        }

        if ($request->has('content')) {
            $content = $request->get('content');
            if (is_array($content)) {
                $content = Arr::get($content, 'raw', '');
            }
            $value['content'] = wp_kses_post($content);
        }

        $value['category'] = sanitize_text_field($request->get('category', ''));

        if ($request->has('wp_pattern_category')) {
            $categoryIds = (array) $request->get('wp_pattern_category', []);
            $value['category'] = $this->resolveCategoryName($categoryIds);
        }

        if ($request->has('description')) {
            $value['description'] = sanitize_text_field($request->get('description'));
        }

        if ($request->exists('sync_status')) {
            $value['sync_status'] = sanitize_text_field($request->get('sync_status'));
        }

        $meta = $request->get('meta', []);
        if (is_array($meta) && isset($meta['wp_pattern_sync_status'])) {
            $value['sync_status'] = sanitize_text_field($meta['wp_pattern_sync_status']);
        }

        if ($title = $request->get('title')) {
            if (is_array($title)) {
                $title = Arr::get($title, 'raw', '');
            }
            if ($title) {
                $pattern->key = 'fluentcrm/' . sanitize_title($title . '-' . $pattern->id);
            }
        }

        $pattern->value = $value;
        $pattern->save();

        return $this->sendSuccess([
            'message' => __('Pattern updated successfully', 'fluent-crm'),
            'pattern' => $this->formatPattern($pattern),
        ]);
    }

    public function delete(Request $request, $id)
    {
        Meta::where('object_type', $this->objectType)
            ->where('id', $id)
            ->firstOrFail()
            ->delete();

        return $this->sendSuccess([
            'message' => __('Pattern deleted successfully', 'fluent-crm'),
        ]);
    }

    public function handleBulkAction(Request $request)
    {
        $actionName = sanitize_text_field($request->get('action_name'));

        if ($actionName !== 'delete_patterns') {
            return $this->sendError([
                'message' => __('Invalid action', 'fluent-crm')
            ]);
        }

        $query = Meta::where('object_type', $this->objectType);

        if (filter_var($request->get('select_all'), FILTER_VALIDATE_BOOLEAN)) {
            $search = $request->getSafe('search', 'sanitize_text_field', '');
            if ($search !== '') {
                // Escape LIKE wildcards (%, _) so the term matches literally, not as wildcards.
                global $wpdb;
                $query->where('value', 'LIKE', '%' . $wpdb->esc_like($search) . '%');
            }
        } else {
            $patternIds = array_map('intval', (array) $request->get('pattern_ids', []));
            if (empty($patternIds)) {
                return $this->sendError([
                    'message' => __('No patterns selected', 'fluent-crm')
                ]);
            }
            $query->whereIn('id', $patternIds);
        }

        $count = $query->delete();

        return $this->sendSuccess([
            'message' => sprintf(__('%d pattern(s) deleted successfully', 'fluent-crm'), $count)
        ]);
    }

    /**
     * CRUD for pattern categories (stored as fc_meta with separate object_type).
     */
    public function getCategories()
    {
        // Collect unique category names from all patterns
        $patterns = Meta::where('object_type', $this->objectType)->get();
        $categories = [];
        foreach ($patterns as $pattern) {
            $cat = Arr::get($pattern->value, 'category', '');
            if ($cat && !in_array($cat, $categories)) {
                $categories[] = $cat;
            }
        }

        sort($categories);

        return $this->sendSuccess([
            'categories' => $categories
        ]);
    }

    public function storeCategory(Request $request)
    {
        $name = sanitize_text_field($request->get('name', ''));
        if (!$name) {
            return $this->sendError(['message' => __('Category name is required', 'fluent-crm')]);
        }

        $slug = sanitize_title($name);

        // Check for existing
        $existing = Meta::where('object_type', $this->categoryObjectType)
            ->where('key', $slug)
            ->first();

        if ($existing) {
            return $this->formatCategoryAsWpTerm($existing);
        }

        $category = Meta::create([
            'object_type' => $this->categoryObjectType,
            'object_id'   => 0,
            'key'         => $slug,
            'value'       => ['name' => $name],
        ]);

        return $this->formatCategoryAsWpTerm($category);
    }

    public function deleteCategory(Request $request, $id)
    {
        Meta::where('object_type', $this->categoryObjectType)
            ->where('id', $id)
            ->firstOrFail()
            ->delete();

        return $this->sendSuccess([
            'message' => __('Category deleted successfully', 'fluent-crm'),
        ]);
    }

    /**
     * Format a pattern Meta record as a wp_block REST response.
     */
    private function formatAsWpBlock($meta, $categoryMap = [])
    {
        $value = $meta->value;
        $title = Arr::get($value, 'title', '');
        $content = Arr::get($value, 'content', '');
        $syncStatus = Arr::get($value, 'sync_status', 'unsynced');
        $category = Arr::get($value, 'category', '');

        $categoryIds = [];
        if ($category) {
            $catSlug = sanitize_title($category);
            if (isset($categoryMap[$catSlug])) {
                $categoryIds[] = (int) $categoryMap[$catSlug];
            }
        }

        return [
            'id'                     => (int) $meta->id,
            'date'                   => $meta->created_at ? $meta->created_at : gmdate('Y-m-d\TH:i:s'),
            'date_gmt'               => $meta->created_at ? $meta->created_at : gmdate('Y-m-d\TH:i:s'),
            'modified'               => $meta->updated_at ? $meta->updated_at : gmdate('Y-m-d\TH:i:s'),
            'modified_gmt'           => $meta->updated_at ? $meta->updated_at : gmdate('Y-m-d\TH:i:s'),
            'slug'                   => $meta->key,
            'status'                 => 'publish',
            'type'                   => 'wp_block',
            'link'                   => '',
            'title'                  => ['raw' => $title],
            'content'                => ['raw' => $content, 'protected' => false],
            'meta'                   => new \stdClass(),
            'wp_pattern_sync_status' => $syncStatus ?: '',
            'wp_pattern_category'    => $categoryIds,
        ];
    }

    private function formatCategoryAsWpTerm($meta)
    {
        $value = $meta->value;

        return [
            'id'     => (int) $meta->id,
            'count'  => 0,
            'name'   => Arr::get($value, 'name', $meta->key),
            'slug'   => $meta->key,
            'parent' => 0,
        ];
    }

    private function formatPattern($meta)
    {
        $value = $meta->value;

        return [
            'id'          => (int) $meta->id,
            'slug'        => $meta->key,
            'title'       => Arr::get($value, 'title', ''),
            'content'     => Arr::get($value, 'content', ''),
            'category'    => Arr::get($value, 'category', ''),
            'description' => Arr::get($value, 'description', ''),
            'sync_status' => Arr::get($value, 'sync_status', 'unsynced'),
            'created_at'  => $meta->created_at ? (string) $meta->created_at : '',
            'updated_at'  => $meta->updated_at ? (string) $meta->updated_at : '',
        ];
    }

    /**
     * Build slug → id map for all pattern categories.
     */
    private function getCategoryMap()
    {
        $categories = Meta::where('object_type', $this->categoryObjectType)->get();
        $map = [];
        foreach ($categories as $cat) {
            $map[$cat->key] = $cat->id;
        }
        return $map;
    }

    /**
     * Resolve category IDs back to a single category name.
     */
    private function resolveCategoryName($categoryIds)
    {
        if (empty($categoryIds)) {
            return '';
        }

        $categoryIds = array_map('intval', $categoryIds);
        $category = Meta::where('object_type', $this->categoryObjectType)
            ->whereIn('id', $categoryIds)
            ->first();

        if ($category) {
            return Arr::get($category->value, 'name', $category->key);
        }

        return '';
    }

    /**
     * Get patterns formatted for the block editor boot data.
     */
    public static function getEditorPatterns()
    {
        $patterns = Meta::where('object_type', 'email_pattern')
            ->orderBy('id', 'desc')
            ->get();

        $editorPatterns = [];
        $categories = [];
        $seenCategories = [];

        foreach ($patterns as $pattern) {
            $value = $pattern->value;
            $title = Arr::get($value, 'title', '');
            $content = Arr::get($value, 'content', '');
            $category = Arr::get($value, 'category', '');
            $description = Arr::get($value, 'description', '');

            if (!$content) {
                continue;
            }

            $patternCategories = [];
            if ($category) {
                $catSlug = sanitize_title($category);
                $patternCategories[] = $catSlug;
                if (!isset($seenCategories[$catSlug])) {
                    $seenCategories[$catSlug] = true;
                    $categories[] = [
                        'name'  => $catSlug,
                        'label' => $category,
                    ];
                }
            }

            // Always include in the general fluentcrm-patterns category
            $patternCategories[] = 'fluentcrm-patterns';

            $editorPatterns[] = [
                'name'        => $pattern->key,
                'title'       => $title,
                'content'     => $content,
                'description' => $description,
                'categories'  => $patternCategories,
                'keywords'    => ['fluentcrm', 'email'],
            ];
        }

        // Always add the root category
        array_unshift($categories, [
            'name'  => 'fluentcrm-patterns',
            'label' => __('My Patterns', 'fluent-crm'),
        ]);

        return [
            'patterns'   => $editorPatterns,
            'categories' => $categories,
        ];
    }
}
