<?php

namespace App\Modules\Content;

use App\Contracts\TelegramModuleInterface;
use App\DTOs\TelegramMessage;
use App\DTOs\TelegramCallback;
use App\DTOs\TelegramResponse;
use App\Services\Core\ConfigurationManager;
use App\Services\Analytics\EventBus;
use App\Models\User;
use App\Models\MenuItem;
use App\Models\ContentPage;
use Illuminate\Support\Facades\Log;

class ContentModule implements TelegramModuleInterface
{
    private ConfigurationManager $config;
    private EventBus $eventBus;

    public function __construct(
        ConfigurationManager $config,
        EventBus $eventBus
    ) {
        $this->config = $config;
        $this->eventBus = $eventBus;
    }

    public function getModuleName(): string
    {
        return 'content';
    }

    public function getModuleVersion(): string
    {
        return '1.0.0';
    }

    public function getDependencies(): array
    {
        return [];
    }

    public function getConfigurationSchema(): array
    {
        return [
            'enabled' => [
                'type' => 'boolean',
                'default' => true,
                'description' => 'Enable content management module',
            ],
            'max_menu_depth' => [
                'type' => 'integer',
                'default' => 3,
                'min' => 1,
                'max' => 5,
                'description' => 'Maximum menu nesting depth',
            ],
            'cache_content' => [
                'type' => 'boolean',
                'default' => true,
                'description' => 'Cache content pages for better performance',
            ],
            'default_language' => [
                'type' => 'string',
                'default' => 'fa',
                'options' => ['fa', 'en'],
                'description' => 'Default content language',
            ],
        ];
    }

    public function isEnabled(): bool
    {
        return $this->config->get('modules.content.enabled', true);
    }

    public function getPriority(): int
    {
        return 70; // Higher priority to handle menu interactions
    }

    public function handleMessage(TelegramMessage $message): ?TelegramResponse
    {
        $text = trim($message->text ?? '');
        $user = $this->getUserFromMessage($message);

        if (!$user) {
            return null;
        }

        // Handle menu navigation commands
        if (str_starts_with($text, '/menu')) {
            return $this->handleMenuCommand($message, $user);
        }

        // Handle content page requests
        if (str_starts_with($text, '/page')) {
            return $this->handlePageCommand($message, $user);
        }

        // Handle main menu request
        if (in_array(strtolower($text), ['menu', 'منو', 'منوی اصلی', '/start'])) {
            return $this->showMainMenu($user);
        }

        // Try to match text with menu items
        return $this->handleMenuItemByText($text, $user);
    }

    public function handleCallback(TelegramCallback $callback): ?TelegramResponse
    {
        $data = $callback->data;
        $user = $this->getUserFromCallback($callback);

        if (!$user) {
            return null;
        }

        // Handle menu navigation callbacks
        if (str_starts_with($data, 'menu_')) {
            return $this->handleMenuCallback($callback, $user);
        }

        // Handle content page callbacks
        if (str_starts_with($data, 'page_')) {
            return $this->handlePageCallback($callback, $user);
        }

        return null;
    }

    public function install(): void
    {
        try {
            // Set default configuration
            $this->config->setModuleConfig('content', [
                'enabled' => true,
                'max_menu_depth' => 3,
                'cache_content' => true,
                'default_language' => 'fa',
            ]);

            // Create default main menu structure
            $this->createDefaultMenuStructure();

            // Emit installation event
            $this->eventBus->emitModuleEvent('content', 'module_installed', [
                'timestamp' => now()->toISOString(),
            ]);

            Log::info('Content module installed successfully');
        } catch (\Throwable $e) {
            Log::error('Failed to install content module', [
                'error' => $e->getMessage(),
            ]);
            throw $e;
        }
    }

    public function uninstall(): void
    {
        try {
            // Disable the module
            $this->config->setModuleConfig('content', ['enabled' => false]);

            // Emit uninstallation event
            $this->eventBus->emitModuleEvent('content', 'module_uninstalled', [
                'timestamp' => now()->toISOString(),
            ]);

            Log::info('Content module uninstalled successfully');
        } catch (\Throwable $e) {
            Log::error('Failed to uninstall content module', [
                'error' => $e->getMessage(),
            ]);
            throw $e;
        }
    }

    /**
     * Get user from message
     */
    private function getUserFromMessage(TelegramMessage $message): ?User
    {
        return User::where('tg_id', (string) $message->userId)->first();
    }

    /**
     * Get user from callback
     */
    private function getUserFromCallback(TelegramCallback $callback): ?User
    {
        return User::where('tg_id', (string) $callback->userId)->first();
    }

    /**
     * Handle menu command
     */
    private function handleMenuCommand(TelegramMessage $message, User $user): TelegramResponse
    {
        $args = explode(' ', trim($message->text), 2);
        
        if (count($args) === 1) {
            return $this->showMainMenu($user);
        }

        $menuPath = $args[1];
        return $this->showMenuByPath($menuPath, $user);
    }

    /**
     * Handle page command
     */
    private function handlePageCommand(TelegramMessage $message, User $user): TelegramResponse
    {
        $args = explode(' ', trim($message->text), 2);
        
        if (count($args) < 2) {
            return new TelegramResponse('لطفاً نام صفحه را مشخص کنید.');
        }

        $pageSlug = $args[1];
        return $this->showPage($pageSlug, $user);
    }

    /**
     * Show main menu
     */
    private function showMainMenu(User $user): TelegramResponse
    {
        $mainMenuItems = MenuItem::active()
            ->whereNull('parent_id')
            ->orderBy('sort_order')
            ->get();

        if ($mainMenuItems->isEmpty()) {
            return new TelegramResponse(
                'منوی اصلی در حال حاضر در دسترس نیست.' . PHP_EOL .
                'لطفاً بعداً دوباره تلاش کنید.'
            );
        }

        $text = $this->config->get('modules.content.welcome_message', 
            '🏠 خوش آمدید! از منوی زیر گزینه مورد نظر را انتخاب کنید:'
        );

        $keyboard = $this->buildMenuKeyboard($mainMenuItems);

        // Track menu view event
        $this->eventBus->emitModuleEvent('content', 'main_menu_viewed', [
            'user_id' => $user->id,
            'timestamp' => now()->toISOString(),
        ]);

        return new TelegramResponse($text, null, $keyboard);
    }

    /**
     * Show menu by path
     */
    private function showMenuByPath(string $path, User $user): TelegramResponse
    {
        $menuItem = MenuItem::active()
            ->where('slug', $path)
            ->orWhere('id', $path)
            ->first();

        if (!$menuItem) {
            return new TelegramResponse('منوی مورد نظر یافت نشد.');
        }

        return $this->showMenuItem($menuItem, $user);
    }

    /**
     * Show specific menu item
     */
    private function showMenuItem(MenuItem $menuItem, User $user): TelegramResponse
    {
        $text = $menuItem->title;
        
        if ($menuItem->description) {
            $text .= PHP_EOL . PHP_EOL . $menuItem->description;
        }

        // If this menu item has a linked content page, show it
        if ($menuItem->content_page_id && $menuItem->contentPage) {
            $page = $menuItem->contentPage;
            if ($page->content) {
                $text .= PHP_EOL . PHP_EOL . $page->content;
            }
        }

        // Build keyboard with child menu items
        $childItems = $menuItem->children()->active()->orderBy('sort_order')->get();
        $keyboard = [];

        if ($childItems->isNotEmpty()) {
            $keyboard = $this->buildMenuKeyboard($childItems);
        }

        // Add back button if this is not a root menu item
        if ($menuItem->parent_id) {
            $backButton = [
                ['text' => '🔙 بازگشت', 'callback_data' => 'menu_back_' . $menuItem->parent_id],
                ['text' => '🏠 منوی اصلی', 'callback_data' => 'menu_main']
            ];
            $keyboard[] = $backButton;
        }

        // Track menu item view event
        $this->eventBus->emitModuleEvent('content', 'menu_item_viewed', [
            'user_id' => $user->id,
            'menu_item_id' => $menuItem->id,
            'menu_item_slug' => $menuItem->slug,
            'timestamp' => now()->toISOString(),
        ]);

        return new TelegramResponse($text, null, $keyboard);
    }

    /**
     * Handle menu item by text matching
     */
    private function handleMenuItemByText(string $text, User $user): ?TelegramResponse
    {
        // Try to find a menu item that matches the text
        $menuItem = MenuItem::active()
            ->where(function ($query) use ($text) {
                $query->where('title', 'LIKE', "%{$text}%")
                      ->orWhere('keywords', 'LIKE', "%{$text}%");
            })
            ->first();

        if ($menuItem) {
            return $this->showMenuItem($menuItem, $user);
        }

        return null; // Let other modules handle this message
    }

    /**
     * Handle menu callback
     */
    private function handleMenuCallback(TelegramCallback $callback, User $user): TelegramResponse
    {
        $data = $callback->data;
        
        if ($data === 'menu_main') {
            return $this->showMainMenu($user);
        }

        if (str_starts_with($data, 'menu_item_')) {
            $menuItemId = str_replace('menu_item_', '', $data);
            $menuItem = MenuItem::active()->find($menuItemId);
            
            if ($menuItem) {
                return $this->showMenuItem($menuItem, $user);
            }
        }

        if (str_starts_with($data, 'menu_back_')) {
            $parentId = str_replace('menu_back_', '', $data);
            $parentMenuItem = MenuItem::active()->find($parentId);
            
            if ($parentMenuItem) {
                return $this->showMenuItem($parentMenuItem, $user);
            } else {
                return $this->showMainMenu($user);
            }
        }

        return new TelegramResponse('منوی مورد نظر یافت نشد.');
    }

    /**
     * Handle page callback
     */
    private function handlePageCallback(TelegramCallback $callback, User $user): TelegramResponse
    {
        $pageId = str_replace('page_', '', $callback->data);
        return $this->showPage($pageId, $user);
    }

    /**
     * Show content page
     */
    private function showPage(string $slugOrId, User $user): TelegramResponse
    {
        $page = ContentPage::active()
            ->where('slug', $slugOrId)
            ->orWhere('id', $slugOrId)
            ->first();

        if (!$page) {
            return new TelegramResponse('صفحه مورد نظر یافت نشد.');
        }

        $text = $page->title . PHP_EOL . PHP_EOL . $page->content;
        
        $keyboard = [];
        
        // Add related pages if any
        if ($page->related_pages) {
            $relatedIds = json_decode($page->related_pages, true) ?? [];
            $relatedPages = ContentPage::active()->whereIn('id', $relatedIds)->get();
            
            if ($relatedPages->isNotEmpty()) {
                foreach ($relatedPages->take(3) as $relatedPage) {
                    $keyboard[] = [
                        ['text' => $relatedPage->title, 'callback_data' => 'page_' . $relatedPage->id]
                    ];
                }
            }
        }

        // Add back to main menu button
        $keyboard[] = [['text' => '🏠 منوی اصلی', 'callback_data' => 'menu_main']];

        // Track page view event
        $this->eventBus->emitModuleEvent('content', 'page_viewed', [
            'user_id' => $user->id,
            'page_id' => $page->id,
            'page_slug' => $page->slug,
            'timestamp' => now()->toISOString(),
        ]);

        return new TelegramResponse($text, null, $keyboard);
    }

    /**
     * Build keyboard from menu items
     */
    private function buildMenuKeyboard($menuItems): array
    {
        $keyboard = [];
        
        foreach ($menuItems as $item) {
            $keyboard[] = [
                ['text' => $item->title, 'callback_data' => 'menu_item_' . $item->id]
            ];
        }

        return $keyboard;
    }

    /**
     * Create default menu structure
     */
    private function createDefaultMenuStructure(): void
    {
        // Create default menu items if they don't exist
        $defaultItems = [
            [
                'title' => '📋 درباره ما',
                'slug' => 'about',
                'description' => 'اطلاعات درباره این ربات',
                'sort_order' => 1,
            ],
            [
                'title' => '📞 تماس با ما',
                'slug' => 'contact',
                'description' => 'راه‌های ارتباط با پشتیبانی',
                'sort_order' => 2,
            ],
            [
                'title' => '❓ راهنما',
                'slug' => 'help',
                'description' => 'راهنمای استفاده از ربات',
                'sort_order' => 3,
            ],
        ];

        foreach ($defaultItems as $itemData) {
            MenuItem::updateOrCreate(
                ['slug' => $itemData['slug']],
                array_merge($itemData, [
                    'is_active' => true,
                    'created_at' => now(),
                    'updated_at' => now(),
                ])
            );
        }
    }
}