<?php

namespace App\Filament\Pages;

use App\Models\NavigationMenu;
use App\Models\Category;
use App\Models\Page as StaticPage;
use App\Models\Setting;
use Filament\Pages\Page;
use Filament\Schemas\Schema;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\CheckboxList;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Grid;
use Filament\Forms\Components\Placeholder;
use Illuminate\Support\HtmlString;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Actions\Contracts\HasActions;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Notifications\Notification;

class MenuBuilder extends Page implements HasForms, HasActions
{
    use InteractsWithForms, InteractsWithActions;

    protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-bars-3';

    protected static ?string $title = 'Menu Builder';

    protected static ?string $navigationLabel = 'Menu Builder';

    protected static string|\UnitEnum|null $navigationGroup = 'Site Builder';

    protected static ?int $navigationSort = 2;

    protected string $view = 'filament.pages.menu-builder';

    public ?array $data = [];

    public function mount()
    {
        $this->form->fill([
            'header' => $this->loadMenuItems('header'),
            'mobile' => $this->loadMenuItems('mobile'),
            'sticky_bar' => $this->loadMenuItems('sticky_bar'),
            'footer' => $this->loadMenuItems('footer'),
            'top_bar' => $this->loadMenuItems('top_bar'),
            'footer_policies' => $this->loadMenuItems('footer_policies'),
            'footer_customer_policy' => $this->loadMenuItems('footer_customer_policy'),
            'show_top_bar_desktop' => Setting::getValue('show_top_bar_desktop', '1') === '1',
            'show_top_bar_mobile' => Setting::getValue('show_top_bar_mobile', '1') === '1',
            'store_hotline_text' => Setting::getValue('store_hotline_text', 'Hotline: +880 1700-000000 (9 AM - 10 PM)'),
        ]);
    }

    protected function loadMenuItems(string $position): array
    {
        $items = NavigationMenu::where('position', $position)
            ->whereNull('parent_id')
            ->orderBy('sort_order')
            ->get();

        $result = [];
        foreach ($items as $item) {
            $parsed = $this->parseLinkUrl($item->link_url);
            
            $children = NavigationMenu::where('parent_id', $item->id)
                ->orderBy('sort_order')
                ->get();
                
            $childrenArray = [];
            foreach ($children as $child) {
                $childParsed = $this->parseLinkUrl($child->link_url);
                $childUuid = (string) \Illuminate\Support\Str::uuid();
                $childrenArray[$childUuid] = [
                    'name' => $child->name,
                    'link_type' => $childParsed['link_type'],
                    'category_slug' => $childParsed['category_slug'],
                    'page_slug' => $childParsed['page_slug'],
                    'link_url' => $child->link_url,
                    'is_active' => (bool)$child->is_active,
                ];
            }

            $uuid = (string) \Illuminate\Support\Str::uuid();
            $result[$uuid] = [
                'name' => $item->name,
                'link_type' => $parsed['link_type'],
                'category_slug' => $parsed['category_slug'],
                'page_slug' => $parsed['page_slug'],
                'link_url' => $item->link_url,
                'is_active' => (bool)$item->is_active,
                'children' => $childrenArray,
            ];
        }

        return $result;
    }

    protected function parseLinkUrl(string $url): array
    {
        if (str_contains($url, 'categorySlug=')) {
            $parts = explode('categorySlug=', $url);
            return [
                'link_type' => 'category',
                'category_slug' => $parts[1] ?? null,
                'page_slug' => null,
            ];
        } elseif (str_starts_with($url, '/pages/')) {
            return [
                'link_type' => 'page',
                'category_slug' => null,
                'page_slug' => str_replace('/pages/', '', $url),
            ];
        }
        return [
            'link_type' => 'custom',
            'category_slug' => null,
            'page_slug' => null,
        ];
    }

    public function form(Schema $form): Schema
    {
        return $form
            ->statePath('data')
            ->schema([
                Tabs::make('Menu Tabs')
                    ->tabs([
                        Tabs\Tab::make('Header Menu')
                            ->icon('heroicon-o-computer-desktop')
                            ->schema([
                                $this->getMenuLayout('header', true),
                            ]),
                        Tabs\Tab::make('Mobile Menu')
                            ->icon('heroicon-o-device-phone-mobile')
                            ->schema([
                                $this->getMenuLayout('mobile', true),
                            ]),
                        Tabs\Tab::make('Bottom Sticky Bar')
                            ->icon('heroicon-o-adjustments-vertical')
                            ->schema([
                                $this->getMenuLayout('sticky_bar', false),
                            ]),
                        Tabs\Tab::make('Footer Links')
                            ->icon('heroicon-o-list-bullet')
                            ->schema([
                                Tabs::make('Footer Menu Sections')
                                    ->tabs([
                                        Tabs\Tab::make('Popular Categories')
                                            ->icon('heroicon-o-tag')
                                            ->schema([
                                                $this->getMenuLayout('footer', false),
                                            ]),
                                        Tabs\Tab::make('Information')
                                            ->icon('heroicon-o-information-circle')
                                            ->schema([
                                                $this->getMenuLayout('footer_policies', false),
                                            ]),
                                        Tabs\Tab::make('Customer Policy')
                                            ->icon('heroicon-o-shield-check')
                                            ->schema([
                                                $this->getMenuLayout('footer_customer_policy', false),
                                            ]),
                                    ]),
                            ]),
                        Tabs\Tab::make('Top Bar Menu')
                            ->icon('heroicon-o-window')
                            ->schema([
                                Grid::make(3)
                                    ->schema([
                                        Toggle::make('show_top_bar_desktop')
                                            ->label('Show Top Bar on Desktop')
                                            ->inline(false)
                                            ->live()
                                            ->afterStateUpdated(function ($state) {
                                                Setting::setValue('show_top_bar_desktop', $state ? '1' : '0');
                                                Setting::clearCache();
                                                Notification::make()
                                                    ->title('Top Bar Desktop visibility updated.')
                                                    ->success()
                                                    ->send();
                                            }),
                                        Toggle::make('show_top_bar_mobile')
                                            ->label('Show Top Bar on Mobile')
                                            ->inline(false)
                                            ->live()
                                            ->afterStateUpdated(function ($state) {
                                                Setting::setValue('show_top_bar_mobile', $state ? '1' : '0');
                                                Setting::clearCache();
                                                Notification::make()
                                                    ->title('Top Bar Mobile visibility updated.')
                                                    ->success()
                                                    ->send();
                                            }),
                                        TextInput::make('store_hotline_text')
                                            ->label('Hotline Text')
                                            ->placeholder('e.g. Hotline: +880 1700-000000 (9 AM - 10 PM)')
                                            ->lazy()
                                            ->afterStateUpdated(function ($state) {
                                                Setting::setValue('store_hotline_text', $state ?? 'Hotline: +880 1700-000000 (9 AM - 10 PM)');
                                                Setting::clearCache();
                                                Notification::make()
                                                    ->title('Hotline text updated.')
                                                    ->success()
                                                    ->send();
                                            })
                                            ->columnSpan(1),
                                    ]),
                                $this->getMenuLayout('top_bar', false),
                            ]),
                    ]),
            ]);
    }

    protected function getMenuLayout(string $name, bool $allowChildren): Grid
    {
        $categories = Category::where('is_visible', true)->pluck('name', 'slug')->toArray();
        $pages = StaticPage::pluck('title', 'slug')->toArray();

        return Grid::make(12)
            ->schema([
                // Left Column: Native Selection Presets (4 Columns)
                Grid::make(1)
                    ->schema([
                        Section::make('🛍️ Categories Presets')
                            ->headerActions([
                                \Filament\Actions\Action::make('add_categories_' . $name)
                                    ->label('Add to Menu')
                                    ->color('primary')
                                    ->size('sm')
                                    ->action(function ($get, $set) use ($name, $categories) {
                                        $selected = $get('select_categories_' . $name) ?? [];
                                        if (empty($selected)) {
                                            Notification::make()->title('Please select at least one category.')->warning()->send();
                                            return;
                                        }

                                        $currentItems = $get($name) ?? [];
                                        foreach ($selected as $slug) {
                                            $label = $categories[$slug] ?? $slug;
                                            $uuid = (string) \Illuminate\Support\Str::uuid();
                                            $currentItems[$uuid] = [
                                                'name' => $label,
                                                'link_type' => 'category',
                                                'category_slug' => $slug,
                                                'page_slug' => null,
                                                'link_url' => '/shop?categorySlug=' . $slug,
                                                'is_active' => true,
                                                'children' => [],
                                            ];
                                        }

                                        $set($name, $currentItems);
                                        $set('select_categories_' . $name, []);

                                        Notification::make()
                                            ->title('Added selected categories to active menu list.')
                                            ->success()
                                            ->send();
                                    }),
                            ])
                            ->schema([
                                CheckboxList::make('select_categories_' . $name)
                                    ->hiddenLabel()
                                    ->options($categories)
                                    ->searchable()
                                    ->bulkToggleable()
                                    ->columns(1),
                            ])
                            ->collapsible(),

                        Section::make('📄 Pages Presets')
                            ->headerActions([
                                \Filament\Actions\Action::make('add_pages_' . $name)
                                    ->label('Add to Menu')
                                    ->color('primary')
                                    ->size('sm')
                                    ->action(function ($get, $set) use ($name, $pages) {
                                        $selected = $get('select_pages_' . $name) ?? [];
                                        if (empty($selected)) {
                                            Notification::make()->title('Please select at least one page.')->warning()->send();
                                            return;
                                        }

                                        $currentItems = $get($name) ?? [];
                                        foreach ($selected as $slug) {
                                            $label = $pages[$slug] ?? $slug;
                                            $uuid = (string) \Illuminate\Support\Str::uuid();
                                            $currentItems[$uuid] = [
                                                'name' => $label,
                                                'link_type' => 'page',
                                                'category_slug' => null,
                                                'page_slug' => $slug,
                                                'link_url' => '/pages/' . $slug,
                                                'is_active' => true,
                                                'children' => [],
                                            ];
                                        }

                                        $set($name, $currentItems);
                                        $set('select_pages_' . $name, []);

                                        Notification::make()
                                            ->title('Added selected pages to active menu list.')
                                            ->success()
                                            ->send();
                                    }),
                            ])
                            ->schema([
                                CheckboxList::make('select_pages_' . $name)
                                    ->hiddenLabel()
                                    ->options($pages)
                                    ->searchable()
                                    ->bulkToggleable()
                                    ->columns(1),
                            ])
                            ->collapsible(),

                        Section::make('✍️ Custom Link')
                            ->headerActions([
                                \Filament\Actions\Action::make('add_custom_' . $name)
                                    ->label('Add to Menu')
                                    ->color('primary')
                                    ->size('sm')
                                    ->action(function ($get, $set) use ($name) {
                                        $label = $get('custom_label_' . $name);
                                        $url = $get('custom_url_' . $name);

                                        if (empty($label) || empty($url)) {
                                            Notification::make()->title('Please fill both Link Label and Target URL fields.')->warning()->send();
                                            return;
                                        }

                                        $currentItems = $get($name) ?? [];
                                        $uuid = (string) \Illuminate\Support\Str::uuid();
                                        $currentItems[$uuid] = [
                                            'name' => $label,
                                            'link_type' => 'custom',
                                            'category_slug' => null,
                                            'page_slug' => null,
                                            'link_url' => $url,
                                            'is_active' => true,
                                            'children' => [],
                                        ];

                                        $set($name, $currentItems);
                                        $set('custom_label_' . $name, '');
                                        $set('custom_url_' . $name, '');

                                        Notification::make()
                                            ->title('Added custom link to active menu list.')
                                            ->success()
                                            ->send();
                                    }),
                            ])
                            ->schema([
                                TextInput::make('custom_label_' . $name)
                                    ->label('Link Label')
                                    ->placeholder('e.g. Shop Online'),
                                TextInput::make('custom_url_' . $name)
                                    ->label('Target URL')
                                    ->placeholder('e.g. /shop or https://...'),
                            ])
                            ->collapsible(),
                    ])
                    ->columnSpan([
                        'default' => 12,
                        'lg' => 4,
                    ]),

                $this->getMenuRepeater($name, $allowChildren)
                    ->columnSpan([
                        'default' => 12,
                        'lg' => 8,
                    ]),
            ]);
    }

    protected function getMenuRepeater(string $name, bool $allowChildren): Repeater
    {
        $categories = Category::where('is_visible', true)->pluck('name', 'slug')->toArray();
        $pages = StaticPage::pluck('title', 'slug')->toArray();

        $itemSchema = [
            TextInput::make('name')
                ->label('Link Label')
                ->required()
                ->columnSpan(2),
            Select::make('link_type')
                ->label('Link Type')
                ->options([
                    'custom' => 'Custom Link',
                    'category' => 'Product Category',
                    'page' => 'Static Page',
                ])
                ->default('custom')
                ->live()
                ->columnSpan(2),
            Select::make('category_slug')
                ->label('Choose Category')
                ->options($categories)
                ->visible(fn ($get) => $get('link_type') === 'category')
                ->required(fn ($get) => $get('link_type') === 'category')
                ->live()
                ->afterStateUpdated(fn ($state, $set) => $set('link_url', '/shop?categorySlug=' . $state))
                ->columnSpan(2),
            Select::make('page_slug')
                ->label('Choose Page')
                ->options($pages)
                ->visible(fn ($get) => $get('link_type') === 'page')
                ->required(fn ($get) => $get('link_type') === 'page')
                ->live()
                ->afterStateUpdated(fn ($state, $set) => $set('link_url', '/pages/' . $state))
                ->columnSpan(2),
            TextInput::make('link_url')
                ->label('Link URL')
                ->required()
                ->columnSpan(2),
            Toggle::make('is_active')
                ->label('Active on Storefront')
                ->default(true)
                ->columnSpan(2),
        ];

        $repeater = Repeater::make($name)
            ->label(ucfirst(str_replace('_', ' ', $name)) . ' Menu Items')
            ->schema($itemSchema)
            ->columns(4)
            ->reorderable()
            ->collapsible()
            ->collapsed()
            ->cloneable()
            ->itemLabel(fn (array $state): ?string => $state['name'] ?? null);

        if ($allowChildren) {
            $childRepeater = Repeater::make('children')
                ->label('Sub Links (Dropdown Items)')
                ->schema([
                    TextInput::make('name')
                        ->label('Sub-Link Label')
                        ->required()
                        ->columnSpan(2),
                    Select::make('link_type')
                        ->label('Link Type')
                        ->options([
                            'custom' => 'Custom Link',
                            'category' => 'Product Category',
                            'page' => 'Static Page',
                        ])
                        ->default('custom')
                        ->live()
                        ->columnSpan(2),
                    Select::make('category_slug')
                        ->label('Choose Category')
                        ->options($categories)
                        ->visible(fn ($get) => $get('link_type') === 'category')
                        ->required(fn ($get) => $get('link_type') === 'category')
                        ->live()
                        ->afterStateUpdated(fn ($state, $set) => $set('link_url', '/shop?categorySlug=' . $state))
                        ->columnSpan(2),
                    Select::make('page_slug')
                        ->label('Choose Page')
                        ->options($pages)
                        ->visible(fn ($get) => $get('link_type') === 'page')
                        ->required(fn ($get) => $get('link_type') === 'page')
                        ->live()
                        ->afterStateUpdated(fn ($state, $set) => $set('link_url', '/pages/' . $state))
                        ->columnSpan(2),
                    TextInput::make('link_url')
                        ->label('Link URL')
                        ->required()
                        ->columnSpan(2),
                    Toggle::make('is_active')
                        ->label('Active')
                        ->default(true)
                        ->columnSpan(2),
                ])
                ->columns(4)
                ->reorderable()
                ->collapsible()
                ->collapsed()
                ->itemLabel(fn (array $state): ?string => $state['name'] ?? null)
                ->columnSpan(4);

            $repeater->schema(array_merge($itemSchema, [$childRepeater]));
        }

        return $repeater;
    }

    public function save()
    {
        $state = $this->form->getState();

        // Clear existing navigation menus
        NavigationMenu::query()->delete();

        foreach (['header', 'mobile', 'sticky_bar', 'footer', 'top_bar', 'footer_policies', 'footer_customer_policy'] as $position) {
            $items = $state[$position] ?? [];
            foreach ($items as $index => $itemData) {
                $parent = NavigationMenu::create([
                    'name' => $itemData['name'],
                    'link_url' => $itemData['link_url'],
                    'position' => $position,
                    'sort_order' => $index,
                    'is_active' => $itemData['is_active'] ?? true,
                ]);

                if (!empty($itemData['children'])) {
                    foreach ($itemData['children'] as $childIndex => $childData) {
                        NavigationMenu::create([
                            'name' => $childData['name'],
                            'link_url' => $childData['link_url'],
                            'parent_id' => $parent->id,
                            'position' => $position,
                            'sort_order' => $childIndex,
                            'is_active' => $childData['is_active'] ?? true,
                        ]);
                    }
                }
            }
        }

        // Save visibility settings
        Setting::setValue('show_top_bar_desktop', ($state['show_top_bar_desktop'] ?? true) ? '1' : '0');
        Setting::setValue('show_top_bar_mobile', ($state['show_top_bar_mobile'] ?? true) ? '1' : '0');
        Setting::setValue('store_hotline_text', $state['store_hotline_text'] ?? 'Hotline: +880 1700-000000 (9 AM - 10 PM)');

        Setting::clearCache();

        Notification::make()
            ->title('Navigation menus updated successfully.')
            ->success()
            ->send();
    }

    public function addCategoryPreset(string $position, string $slug, string $name)
    {
        $currentItems = $this->data[$position] ?? [];
        $uuid = (string) \Illuminate\Support\Str::uuid();
        $currentItems[$uuid] = [
            'name' => $name,
            'link_type' => 'category',
            'category_slug' => $slug,
            'page_slug' => null,
            'link_url' => '/shop?categorySlug=' . $slug,
            'is_active' => true,
            'children' => [],
        ];
        
        $this->data[$position] = $currentItems;
        
        Notification::make()
            ->title("Added category link '$name' to " . ucfirst($position) . " Menu.")
            ->success()
            ->send();
    }

    public function addPagePreset(string $position, string $slug, string $title)
    {
        $currentItems = $this->data[$position] ?? [];
        $uuid = (string) \Illuminate\Support\Str::uuid();
        $currentItems[$uuid] = [
            'name' => $title,
            'link_type' => 'page',
            'category_slug' => null,
            'page_slug' => $slug,
            'link_url' => '/pages/' . $slug,
            'is_active' => true,
            'children' => [],
        ];
        
        $this->data[$position] = $currentItems;
        
        Notification::make()
            ->title("Added static page link '$title' to " . ucfirst($position) . " Menu.")
            ->success()
            ->send();
    }

    public function addCustomLinkPreset(string $position, string $label, string $url)
    {
        $currentItems = $this->data[$position] ?? [];
        $uuid = (string) \Illuminate\Support\Str::uuid();
        $currentItems[$uuid] = [
            'name' => $label,
            'link_type' => 'custom',
            'category_slug' => null,
            'page_slug' => null,
            'link_url' => $url,
            'is_active' => true,
            'children' => [],
        ];
        
        $this->data[$position] = $currentItems;
        
        Notification::make()
            ->title("Added custom link '$label' to " . ucfirst($position) . " Menu.")
            ->success()
            ->send();
    }

    protected function getHeaderActions(): array
    {
        return [
            \Filament\Actions\Action::make('save')
                ->label('Save Settings')
                ->action('save')
                ->color('primary'),
        ];
    }
}

