<?php

namespace App\Filament\Resources\ResellerOrders\Schemas;

use App\Models\Order;
use App\Models\Product;
use App\Models\ShippingMethod;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Hidden;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class ResellerOrderForm
{
    public static function updateTotals(callable $get, callable $set, ?Order $record = null): void
    {
        $items = $get('items') ?? [];
        $subtotal = 0;
        $totalResellerPrice = 0;
        foreach ($items as $item) {
            $subtotal += ((float) ($item['price'] ?? 0)) * ((int) ($item['quantity'] ?? 1));
            $totalResellerPrice += ((float) ($item['reseller_price'] ?? 0)) * ((int) ($item['quantity'] ?? 1));
        }
        $set('subtotal', $subtotal);
        $set('total_reseller_price', $totalResellerPrice);
        
        $shipping = is_numeric($get('shipping_cost')) ? (float) $get('shipping_cost') : 80.00;
        
        $returnedValue = 0.00;
        if ($record && $record->is_exchange) {
            $returnRequest = \App\Models\ReturnRequest::where('exchange_order_id', $record->id)->first();
            if ($returnRequest) {
                $returnedValue = (float) $returnRequest->items->sum(fn($item) => $item->price * $item->quantity);
            }
        }
        
        $discountType = $get('discount_type') ?? 'fixed';
        $discountValue = is_numeric($get('discount_value')) ? (float) $get('discount_value') : 0.00;
        $additionalDiscount = $discountType === 'percentage' ? ($subtotal * $discountValue) / 100 : $discountValue;
        
        $discount = $returnedValue + $additionalDiscount;
        $set('discount', $discount);
        
        $tax = is_numeric($get('tax')) ? (float) $get('tax') : 0.00;
        
        $grandTotal = 0.00;
        if ($record && $record->is_exchange) {
            $grandTotal = max(0, $subtotal + $shipping + $tax - $discount);
        } else {
            $grandTotal = max(0, $subtotal - $discount) + $shipping + $tax;
        }
        $set('grand_total', $grandTotal);

        // Update reseller profit reactively (subtotal minus wholesale price)
        $set('total_reseller_profit', max(0, ($subtotal - $discount) - $totalResellerPrice));
    }

    public static function updateTotalsFromChild(callable $get, callable $set, ?Order $record = null): void
    {
        $items = $get('../../items') ?? [];
        $subtotal = 0;
        $totalResellerPrice = 0;
        foreach ($items as $item) {
            $subtotal += ((float) ($item['price'] ?? 0)) * ((int) ($item['quantity'] ?? 1));
            $totalResellerPrice += ((float) ($item['reseller_price'] ?? 0)) * ((int) ($item['quantity'] ?? 1));
        }
        $set('../../subtotal', $subtotal);
        $set('../../total_reseller_price', $totalResellerPrice);
        
        $shipping = is_numeric($get('../../shipping_cost')) ? (float) $get('../../shipping_cost') : 80.00;
        
        $returnedValue = 0.00;
        if ($record && $record->is_exchange) {
            $returnRequest = \App\Models\ReturnRequest::where('exchange_order_id', $record->id)->first();
            if ($returnRequest) {
                $returnedValue = (float) $returnRequest->items->sum(fn($item) => $item->price * $item->quantity);
            }
        }
        
        $discountType = $get('../../discount_type') ?? 'fixed';
        $discountValue = is_numeric($get('../../discount_value')) ? (float) $get('../../discount_value') : 0.00;
        $additionalDiscount = $discountType === 'percentage' ? ($subtotal * $discountValue) / 100 : $discountValue;
        
        $discount = $returnedValue + $additionalDiscount;
        $set('../../discount', $discount);
        
        $tax = is_numeric($get('../../tax')) ? (float) $get('../../tax') : 0.00;
        
        $grandTotal = 0.00;
        if ($record && $record->is_exchange) {
            $grandTotal = max(0, $subtotal + $shipping + $tax - $discount);
        } else {
            $grandTotal = max(0, $subtotal - $discount) + $shipping + $tax;
        }
        $set('../../grand_total', $grandTotal);

        // Update reseller profit reactively from child (subtotal minus wholesale price)
        $set('../../total_reseller_profit', max(0, ($subtotal - $discount) - $totalResellerPrice));
    }

    /**
     * Calculate total weight of order items (in grams) for weight-based shipping.
     */
    public static function calculateOrderWeightGrams(array $items): int
    {
        $totalGrams = 0;
        foreach ($items as $item) {
            $productId = $item['product_id'] ?? null;
            $qty       = (int) ($item['quantity'] ?? 1);
            if ($productId) {
                $product = Product::find($productId);
                if ($product && $product->weight_grams) {
                    $totalGrams += $product->weight_grams * $qty;
                }
            }
        }
        return $totalGrams;
    }

    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->components([
                Grid::make([
                    'default' => 1,
                    'lg' => 12,
                ])
                    ->schema([
                        // ─── Left / Main Column (span 2) ──────────────────────
                        Grid::make(1)
                            ->schema([
                                // Order header section
                                Section::make('Order Details')
                                    ->schema([
                                        TextInput::make('order_number')
                                            ->label('Order number')
                                            ->disabled()
                                            ->dehydrated()
                                            ->columnSpan(1),
                                        TextInput::make('customer_name')
                                            ->label('Customer name')
                                            ->columnSpan(1),
                                        TextInput::make('customer_phone')
                                            ->label('Customer phone')
                                            ->columnSpan(1),
                                        TextInput::make('customer_email')
                                            ->label('Customer email')
                                            ->email()
                                            ->columnSpan(1),

                                        ToggleButtons::make('status')
                                            ->label('Order Status')
                                            ->options([
                                                'pending'    => 'New',
                                                'processing' => 'Processing',
                                                'shipped'    => 'Shipped',
                                                'delivered'  => 'Delivered',
                                                'cancelled'  => 'Cancelled',
                                                'returned'   => 'Returned',
                                            ])
                                            ->colors([
                                                'pending'    => 'info',
                                                'processing' => 'warning',
                                                'shipped'    => 'info',
                                                'delivered'  => 'success',
                                                'cancelled'  => 'danger',
                                                'returned'   => 'purple',
                                            ])
                                            ->icons([
                                                'pending'    => 'heroicon-m-sparkles',
                                                'processing' => 'heroicon-m-arrow-path',
                                                'shipped'    => 'heroicon-m-truck',
                                                'delivered'  => 'heroicon-m-check-circle',
                                                'cancelled'  => 'heroicon-m-x-circle',
                                                'returned'   => 'heroicon-m-arrow-uturn-left',
                                            ])
                                            ->inline()
                                            ->columnSpanFull(),

                                        ToggleButtons::make('payment_status')
                                            ->label('Payment Status')
                                            ->options([
                                                'pending'  => 'Pending',
                                                'paid'     => 'Paid',
                                                'failed'   => 'Failed',
                                                'refunded' => 'Refunded',
                                            ])
                                            ->colors([
                                                'pending'  => 'warning',
                                                'paid'     => 'success',
                                                'failed'   => 'danger',
                                                'refunded' => 'info',
                                            ])
                                            ->icons([
                                                'pending'  => 'heroicon-m-clock',
                                                'paid'     => 'heroicon-m-check-circle',
                                                'failed'   => 'heroicon-m-x-circle',
                                                'refunded' => 'heroicon-m-arrow-uturn-left',
                                            ])
                                            ->inline()
                                            ->columnSpanFull(),

                                        Select::make('payment_method')
                                             ->label('Payment Method')
                                             ->options(function () {
                                                 $methods = [];
                                                 if (\App\Models\Setting::getValue('cod_enabled') == '1') {
                                                     $methods['cod'] = 'Cash on Delivery';
                                                 }
                                                 if (\App\Models\Setting::getValue('sslcommerz_enabled') == '1') {
                                                     $methods['sslcommerz'] = 'SSLCommerz';
                                                 }
                                                 if (\App\Models\Setting::getValue('bkash_enabled') == '1') {
                                                     $methods['bkash'] = 'bKash';
                                                 }
                                                 if (\App\Models\Setting::getValue('nagad_enabled') == '1') {
                                                     $methods['nagad'] = 'Nagad';
                                                 }
                                                 if (empty($methods)) {
                                                     $methods['cod'] = 'Cash on Delivery';
                                                 }
                                                 return $methods;
                                             })
                                             ->columnSpanFull(),
                                    ])
                                    ->columns([
                                        'default' => 1,
                                        'sm' => 2,
                                    ]),



                                // Shipping / Address section
                                Section::make('Shipping address')
                                    ->schema([
                                        Textarea::make('shipping_address')
                                            ->label('Shipping address')
                                            ->rows(3)
                                            ->columnSpanFull(),
                                        Textarea::make('billing_address')
                                            ->label('Billing address')
                                            ->rows(3)
                                            ->columnSpanFull(),
                                    ])
                                    ->columns(1),

                                // Notes section
                                Section::make('Notes')
                                    ->schema([
                                        RichEditor::make('notes')
                                            ->label('Customer notes')
                                            ->columnSpanFull(),
                                    ])
                                    ->collapsible(),

                                // Hidden financial fields for calculation
                                Hidden::make('discount')->default(0.00),
                                Hidden::make('grand_total')->default(80.00),

                                // Charges & Adjustments section
                                Section::make('Charges & Adjustments')
                                    ->schema([
                                        // Shipping method selector
                                        Select::make('shipping_method_id')
                                            ->label('Shipping Method')
                                            ->options(function () {
                                                return ShippingMethod::where('is_active', true)
                                                    ->get()
                                                    ->mapWithKeys(fn ($m) => [
                                                        $m->id => $m->dropdown_label,
                                                    ]);
                                            })
                                            ->nullable()
                                            ->searchable()
                                            ->live()
                                            ->afterStateUpdated(function ($state, callable $get, callable $set, ?Order $record) {
                                                if (!$state) return;

                                                $method = ShippingMethod::find($state);
                                                if (!$method) return;

                                                // Calculate total weight from order items
                                                $items       = $get('items') ?? [];
                                                $weightGrams = self::calculateOrderWeightGrams($items);

                                                // Auto-fill shipping cost
                                                $cost = $method->calculateCost($weightGrams);
                                                $set('shipping_cost', $cost);

                                                // Recalculate grand total
                                                self::updateTotals($get, $set, $record);
                                            })
                                            ->columnSpanFull()
                                            ->helperText('Select a method to auto-fill the shipping cost. You can still edit it manually.'),

                                        TextInput::make('shipping_cost')
                                            ->label('Shipping Cost')
                                            ->numeric()
                                            ->default(80.00)
                                            ->live(onBlur: true)
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                        Select::make('discount_type')
                                            ->label('Discount Type')
                                            ->options([
                                                'fixed' => 'Fixed Amount (৳)',
                                                'percentage' => 'Percentage (%)',
                                            ])
                                            ->default('fixed')
                                            ->live()
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                        TextInput::make('discount_value')
                                            ->label('Discount Value')
                                            ->numeric()
                                            ->default(0.00)
                                            ->live(onBlur: true)
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                        TextInput::make('tax')
                                            ->label('Tax')
                                            ->numeric()
                                            ->default(0.00)
                                            ->live(onBlur: true)
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                    ])
                                    ->columns([
                                        'default' => 1,
                                        'sm' => 2,
                                        'lg' => 4,
                                    ]),

                                // Order items repeater
                                Section::make('Order items')
                                    ->headerActions([
                                        \Filament\Actions\Action::make('reset')
                                            ->label('Reset')
                                            ->color('danger')
                                            ->requiresConfirmation()
                                            ->modalHeading('Reset order items?')
                                            ->modalDescription('Are you sure you want to clear all items from this order?')
                                            ->action(fn (callable $set) => $set('items', [])),
                                    ])
                                    ->schema([
                                        Repeater::make('items')
                                            ->relationship('items')
                                            ->orderColumn('sort_order')
                                            ->hiddenLabel()
                                            ->addActionLabel('Add to order items')
                                            ->table([
                                                \Filament\Forms\Components\Repeater\TableColumn::make('Product'),
                                                \Filament\Forms\Components\Repeater\TableColumn::make('Quantity')
                                                    ->width('120px'),
                                                \Filament\Forms\Components\Repeater\TableColumn::make('Unit Price')
                                                    ->width('150px'),
                                            ])
                                            ->schema([
                                                Select::make('product_id')
                                                    ->options(Product::pluck('name', 'id'))
                                                    ->live()
                                                    ->afterStateUpdated(function ($state, callable $set, callable $get, ?Order $record) {
                                                        $product = Product::find($state);
                                                        if ($product) {
                                                            $set('product_name', $product->name);
                                                            $set('product_sku', $product->sku);
                                                            $set('price', $product->sale_price ?? $product->price);
                                                            $set('reseller_price', $product->reseller_price);
                                                            $set('reseller_profit', max(0, (float)($product->sale_price ?? $product->price) - (float)$product->reseller_price));
                                                        }
                                                        self::updateTotalsFromChild($get, $set, $record);
                                                     })
                                                    ->columnSpan(3),
                                                TextInput::make('quantity')
                                                    ->numeric()
                                                    ->default(1)
                                                    ->live(onBlur: true)
                                                    ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                        self::updateTotalsFromChild($get, $set, $record);
                                                     })
                                                    ->columnSpan(1),
                                                TextInput::make('price')
                                                    ->label('Selling Price')
                                                    ->numeric()
                                                    ->required()
                                                    ->live(onBlur: true)
                                                    ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                        $price = (float) $get('price');
                                                        $resellerPrice = (float) $get('reseller_price');
                                                        $set('reseller_profit', max(0, $price - $resellerPrice));
                                                        self::updateTotalsFromChild($get, $set, $record);
                                                    })
                                                    ->columnSpan(1),
                                                Hidden::make('product_name'),
                                                Hidden::make('product_sku'),
                                                Hidden::make('reseller_price')
                                                    ->dehydrated(),
                                                Hidden::make('reseller_profit')
                                                    ->dehydrated(),
                                            ])
                                            ->extraItemActions([
                                                \Filament\Actions\Action::make('openProduct')
                                                    ->icon('heroicon-o-arrow-top-right-on-square')
                                                    ->url(fn (array $arguments, callable $get): ?string => 
                                                        isset($arguments['item']) && ($productId = $get("items.{$arguments['item']}.product_id"))
                                                            ? url('/admin/products/' . $productId . '/edit')
                                                            : null
                                                    )
                                                    ->openUrlInNewTab()
                                            ])
                                            ->live()
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                    ]),

                                Section::make('Reseller & Profit Details')
                                    ->schema([
                                        Select::make('reseller_id')
                                            ->label('Reseller')
                                            ->options(\App\Models\User::where('role', 'reseller')->pluck('name', 'id'))
                                            ->searchable()
                                            ->required(),
                                        TextInput::make('total_reseller_price')
                                            ->label('Wholesale Price')
                                            ->numeric()
                                            ->required()
                                            ->readonly()
                                            ->dehydrated(),
                                        TextInput::make('subtotal')
                                            ->label('Reseller Selling Price')
                                            ->numeric()
                                            ->required()
                                            ->live(onBlur: true)
                                            ->afterStateUpdated(function (callable $get, callable $set, ?Order $record) {
                                                self::updateTotals($get, $set, $record);
                                            }),
                                        TextInput::make('total_reseller_profit')
                                            ->label('Reseller Profit')
                                            ->numeric()
                                            ->readonly()
                                            ->dehydrated(),
                                        Hidden::make('is_reseller_order')
                                            ->default(true),
                                    ])
                                    ->columns(2),
                            ])
                            ->columnSpan([
                                'default' => 1,
                                'lg' => 8,
                            ]),

                         // ─── Right Sidebar Column (span 1) ───────────────────
                        Grid::make(1)
                            ->schema([
                                // Order dates
                                Section::make()
                                    ->schema([
                                        Placeholder::make('parent_order_link')
                                            ->label('Original Order')
                                            ->visible(fn (?Order $record) => $record && $record->is_exchange && $record->parent_order_id)
                                            ->content(function (?Order $record) {
                                                if (!$record || !$record->parent_order_id || !$record->parentOrder) {
                                                    return '—';
                                                }
                                                $url = \App\Filament\Resources\Orders\OrderResource::getUrl('edit', ['record' => $record->parent_order_id]);
                                                return new \Illuminate\Support\HtmlString("
                                                    <a href='{$url}' class='text-primary-600 dark:text-primary-400 hover:underline font-semibold' style='display: inline-flex; align-items: center; gap: 0.25rem;'>
                                                        #{$record->parentOrder->order_number}
                                                        <svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24' style='width: 1rem; height: 1rem;'>
                                                            <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25'></path>
                                                        </svg>
                                                    </a>
                                                ");
                                            }),

                                        Placeholder::make('child_orders_links')
                                            ->label('Exchange Orders')
                                            ->visible(fn (?Order $record) => $record && $record->childOrders()->exists())
                                            ->content(function (?Order $record) {
                                                if (!$record) return '—';
                                                $links = $record->childOrders->map(function ($child) {
                                                    $url = \App\Filament\Resources\Orders\OrderResource::getUrl('edit', ['record' => $child->id]);
                                                    return "<a href='{$url}' class='text-primary-600 dark:text-primary-400 hover:underline font-semibold' style='display: inline-flex; align-items: center; gap: 0.25rem;'>
                                                        #{$child->order_number}
                                                    </a>";
                                                })->implode(', ');
                                                return new \Illuminate\Support\HtmlString($links ?: '—');
                                            }),

                                        Placeholder::make('created_at')
                                            ->label('Order date')
                                            ->content(fn (?Order $record): string => $record
                                                ? $record->created_at->format('M j, Y \a\t H:i')
                                                : '—'),
                                        Placeholder::make('updated_at')
                                            ->label('Last modified')
                                            ->content(fn (?Order $record): string => $record
                                                ? $record->updated_at->diffForHumans()
                                                : '—'),
                                    ]),

                                // Financial summary
                                Section::make('Order summary')
                                    ->schema([
                                        Placeholder::make('subtotal_display')
                                            ->label('Subtotal')
                                            ->content(fn ($get): string => '৳ ' . number_format(is_numeric($get('subtotal')) ? (float) $get('subtotal') : 0.00, 2)),
                                        Placeholder::make('shipping_cost_display')
                                            ->label('Shipping')
                                            ->content(fn ($get): string => '৳ ' . number_format(is_numeric($get('shipping_cost')) ? (float) $get('shipping_cost') : 80.00, 2)),
                                        Placeholder::make('discount_display')
                                            ->label('Discount')
                                            ->visible(fn (?Order $record) => !$record || !$record->is_exchange)
                                            ->content(fn ($get): string => (is_numeric($get('discount')) ? (float) $get('discount') : 0.00) > 0
                                                ? '- ৳ ' . number_format((float) $get('discount'), 2)
                                                : '৳ 0.00'),
                                        Placeholder::make('returned_value_display')
                                            ->label('Returned value')
                                            ->visible(fn (?Order $record) => $record && $record->is_exchange)
                                            ->content(fn ($get): string => (is_numeric($get('discount')) ? (float) $get('discount') : 0.00) > 0
                                                ? '- ৳ ' . number_format((float) $get('discount'), 2)
                                                : '৳ 0.00'),
                                        Placeholder::make('tax_display')
                                            ->label('Tax')
                                            ->content(fn ($get): string => '৳ ' . number_format(is_numeric($get('tax')) ? (float) $get('tax') : 0.00, 2)),
                                        Placeholder::make('refundable_amount_display')
                                            ->label('Refundable amount')
                                            ->visible(fn (?Order $record, $get) => $record && $record->is_exchange && ((float) $get('discount') - (float) $get('subtotal') - (float) $get('shipping_cost') - (float) $get('tax')) > 0)
                                            ->content(fn ($get): string => '৳ ' . number_format(max(0, (float) $get('discount') - (float) $get('subtotal') - (float) $get('shipping_cost') - (float) $get('tax')), 2)),
                                        Placeholder::make('grand_total_display')
                                            ->label('Grand total')
                                            ->content(fn ($get): string => '৳ ' . number_format(is_numeric($get('grand_total')) ? (float) $get('grand_total') : 80.00, 2)),
                                    ]),

                                Section::make('Order History Timeline')
                                    ->schema([
                                        Placeholder::make('order_timeline')
                                            ->hiddenLabel()
                                            ->view('filament.components.order-timeline'),
                                    ])
                                    ->visible(fn (?Order $record): bool => $record !== null)
                                    ->collapsible()
                                    ->collapsed(),
                            ])
                            ->columnSpan([
                                'default' => 1,
                                'lg' => 4,
                            ]),
                    ])
                    ->columnSpanFull(),

            ]);
    }
}
