<?php

namespace App\Filament\Resources;

use App\Filament\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource\RelationManagers;
use App\Models\Invoice;
use App\Models\Product;
use App\Models\Setting;
use App\Models\User;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use pxlrbt\FilamentExcel\Actions\Tables\ExportAction;
use pxlrbt\FilamentExcel\Actions\Tables\ExportBulkAction;
use pxlrbt\FilamentExcel\Exports\ExcelExport;

class InvoiceResource extends Resource
{
    protected static ?string $model = Invoice::class;

    protected static ?string $navigationIcon = 'heroicon-o-document-text';
    protected static ?string $navigationGroup = 'فاکتورها';
    protected static ?string $navigationLabel = 'فاکتور و پیش‌فاکتور';
    protected static ?string $modelLabel = 'فاکتور';
    protected static ?string $pluralModelLabel = 'فاکتورها';
    protected static ?int $navigationSort = 1;

    public static function form(Form $form): Form
    {
        return $form->schema([
            Forms\Components\Section::make()->columns(3)->schema([
                Forms\Components\ToggleButtons::make('type')->label('نوع')
                    ->options(['proforma' => 'پیش‌فاکتور', 'invoice' => 'فاکتور', 'official' => 'فاکتور رسمی'])
                    ->default('proforma')->inline()->required()->live(),
                Forms\Components\TextInput::make('number')->label('شماره')
                    ->placeholder('خودکار تولید می‌شود')->disabled()->dehydrated(false),
                Forms\Components\Select::make('status')->label('وضعیت')
                    ->options([
                        'draft' => 'پیش‌نویس', 'issued' => 'صادرشده', 'paid' => 'پرداخت‌شده',
                        'partial' => 'پرداخت جزئی', 'void' => 'باطل',
                    ])->default('draft')->required(),
                Forms\Components\Select::make('customer_id')->label('مشتری')
                    ->options(fn () => \App\Models\Customer::query()
                        ->when(! auth()->user()->canSeeAll('customers'), fn ($q) => $q->where('assigned_user_id', auth()->id()))
                        ->get()->mapWithKeys(fn ($c) => [$c->id => $c->display_name]))
                    ->searchable()->preload()->required(),
                Forms\Components\Select::make('company_id')->label('شرکت / سربرگ')
                    ->options(fn () => \App\Models\Company::pluck('name', 'id'))
                    ->default(fn () => \App\Models\Company::default()?->id)
                    ->searchable()->preload(),
                Forms\Components\Select::make('layout')->label('چیدمان چاپ')
                    ->options(['portrait' => 'عمودی', 'landscape' => 'افقی'])
                    ->default('portrait')->required(),
                Forms\Components\DatePicker::make('issue_date')->label('تاریخ صدور')->jalali()->default(now())->required(),
                Forms\Components\DatePicker::make('due_date')->label('سررسید')->jalali(),
                Forms\Components\TextInput::make('attachment')->label('پیوست')->default('ندارد'),
            ]),

            Forms\Components\Section::make('اطلاعات فاکتور رسمی')
                ->description('برای صورتحساب فروش کالا و خدمات (فاکتور رسمی)')
                ->columns(3)
                ->visible(fn (Forms\Get $get) => $get('type') === 'official')
                ->schema([
                    Forms\Components\TextInput::make('serial_number')->label('شماره سریال')
                        ->placeholder('۱۴۰۵-۹۱۱۰')->helperText('به‌صورت دستی وارد کنید'),
                    Forms\Components\TextInput::make('tax_id')->label('شناسه مالیاتی'),
                    Forms\Components\TextInput::make('contract_number')->label('قرارداد شماره'),
                ]),

            Forms\Components\Section::make('ردیف‌های کالا/خدمت')->schema([
                Forms\Components\Repeater::make('items')
                    ->relationship()
                    ->label('')
                    ->schema([
                        Forms\Components\Select::make('description')->label('شرح کالا / خدمت')
                            ->options(fn () => Product::where('is_active', true)->pluck('name', 'name'))
                            ->getSearchResultsUsing(fn (string $search) => Product::where('is_active', true)
                                ->where('name', 'like', "%{$search}%")->limit(50)->pluck('name', 'name')->toArray())
                            ->searchable()
                            ->allowHtml(false)
                            ->createOptionForm([
                                Forms\Components\TextInput::make('name')->label('نام کالا/خدمت')->required(),
                                Forms\Components\TextInput::make('default_price')->label('قیمت پیش‌فرض')->numeric()->default(0),
                            ])
                            ->createOptionUsing(function (array $data) {
                                Product::create(['name' => $data['name'], 'default_price' => $data['default_price'] ?? 0, 'is_active' => true]);
                                return $data['name'];
                            })
                            ->live()
                            ->afterStateUpdated(function ($state, Forms\Set $set) {
                                if ($product = Product::where('name', $state)->first()) {
                                    $set('unit_price', $product->default_price);
                                }
                            })
                            ->required()->columnSpan(5),
                        Forms\Components\TextInput::make('product_code')->label('کد کالا')->columnSpan(2),
                        Forms\Components\TextInput::make('unit')->label('واحد')->placeholder('عدد')->columnSpan(1),
                        Forms\Components\TextInput::make('quantity')->label('تعداد')->numeric()->default(1)->live(onBlur: true)->required()->columnSpan(1),
                        Forms\Components\TextInput::make('unit_price')->label('قیمت واحد')->numeric()->default(0)->live(onBlur: true)->required()->columnSpan(2),
                        Forms\Components\TextInput::make('discount')->label('تخفیف ردیف')->numeric()->default(0)->live(onBlur: true)->columnSpan(1),
                    ])
                    ->columns(12)
                    ->defaultItems(1)
                    ->addActionLabel('افزودن ردیف')
                    ->reorderableWithButtons()
                    ->live()
                    ->afterStateUpdated(fn (Forms\Get $get, Forms\Set $set) => self::updateTotals($get, $set)),
            ]),

            Forms\Components\Section::make('شرایط فاکتور')->columns(4)->schema([
                Forms\Components\Select::make('sale_terms')->label('شرایط فروش')
                    ->options(['cash' => 'نقدی', 'credit' => 'غیر نقدی'])->default('cash'),
                Forms\Components\TextInput::make('delivery_place')->label('محل تحویل')->placeholder('درب کارخانه'),
                Forms\Components\TextInput::make('warranty')->label('گارانتی')->placeholder('۱۲ ماه'),
                Forms\Components\Select::make('bank_account_id')->label('شماره حساب جهت واریز')
                    ->options(fn () => \App\Models\BankAccount::all()->mapWithKeys(fn ($b) => [$b->id => $b->label]))
                    ->default(fn () => \App\Models\BankAccount::default()?->id)
                    ->searchable(),
            ]),

            Forms\Components\Section::make('مبالغ')->columns(4)->schema([
                Forms\Components\TextInput::make('discount_total')->label('تخفیف کلی')->numeric()->default(0)
                    ->live(onBlur: true)->afterStateUpdated(fn (Forms\Get $get, Forms\Set $set) => self::updateTotals($get, $set)),
                Forms\Components\TextInput::make('shipping_cost')->label('حمل و نقل')->numeric()->default(0)
                    ->live(onBlur: true)->afterStateUpdated(fn (Forms\Get $get, Forms\Set $set) => self::updateTotals($get, $set)),
                Forms\Components\Toggle::make('vat_enabled')->label('مالیات و عوارض فعال باشد؟')
                    ->default(true)->inline(false)->live()
                    ->afterStateUpdated(fn (Forms\Get $get, Forms\Set $set) => self::updateTotals($get, $set)),
                Forms\Components\TextInput::make('tax_percent')->label('درصد مالیات و عوارض')->numeric()
                    ->default(10)
                    ->disabled(fn (Forms\Get $get) => ! $get('vat_enabled'))
                    ->live(onBlur: true)->afterStateUpdated(fn (Forms\Get $get, Forms\Set $set) => self::updateTotals($get, $set)),
                Forms\Components\Placeholder::make('summary')->label('خلاصه')->columnSpanFull()
                    ->content(function (Forms\Get $get) {
                        $sub = collect($get('items'))->sum(fn ($i) => ((float) ($i['quantity'] ?? 0) * (float) ($i['unit_price'] ?? 0)) - (float) ($i['discount'] ?? 0));
                        $base = max(0, $sub - (float) $get('discount_total'));
                        $tax = $get('vat_enabled') ? $base * ((float) $get('tax_percent') / 100) : 0;
                        $total = $base + $tax + (float) $get('shipping_cost');
                        $m = fn ($v) => \App\Support\NumberToWords::money($v);
                        return new \Illuminate\Support\HtmlString(
                            'جمع: ' . $m($sub) . ' ریال<br>' .
                            'مالیات و عوارض: ' . $m($tax) . ' ریال<br>' .
                            'حمل و نقل: ' . $m((float) $get('shipping_cost')) . ' ریال<br>' .
                            '<strong>مبلغ نهایی: ' . $m($total) . ' ریال</strong><br>' .
                            '<span style="color:#6b7280">به حروف: ' . \App\Support\NumberToWords::rials($total) . '</span>'
                        );
                    }),
            ]),

            Forms\Components\Textarea::make('notes')->label('توضیحات')->columnSpanFull(),
        ]);
    }

    protected static function updateTotals(Forms\Get $get, Forms\Set $set): void
    {
        $items = $get('items') ?? [];
        $subtotal = collect($items)->sum(fn ($i) => ((float) ($i['quantity'] ?? 0) * (float) ($i['unit_price'] ?? 0)) - (float) ($i['discount'] ?? 0));
        $base = max(0, $subtotal - (float) $get('discount_total'));
        $tax = $get('vat_enabled') ? $base * ((float) $get('tax_percent') / 100) : 0;
        $set('subtotal', $subtotal);
        $set('tax_amount', round($tax, 2));
        $set('grand_total', round($base + $tax + (float) $get('shipping_cost'), 2));
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('number')->label('شماره')->searchable()->sortable(),
                Tables\Columns\TextColumn::make('type')->label('نوع')->badge()
                    ->color(fn ($state) => ['proforma' => 'gray', 'invoice' => 'success', 'official' => 'warning'][$state] ?? 'gray')
                    ->formatStateUsing(fn ($state) => ['proforma' => 'پیش‌فاکتور', 'invoice' => 'فاکتور', 'official' => 'فاکتور رسمی'][$state] ?? $state),
                Tables\Columns\TextColumn::make('customer.display_name')->label('مشتری')->searchable(['first_name', 'last_name', 'company_name']),
                Tables\Columns\TextColumn::make('status')->label('وضعیت')->badge()
                    ->color(fn ($state) => [
                        'draft' => 'gray', 'issued' => 'info', 'paid' => 'success',
                        'partial' => 'warning', 'void' => 'danger',
                    ][$state] ?? 'gray')
                    ->formatStateUsing(fn ($state) => [
                        'draft' => 'پیش‌نویس', 'issued' => 'صادرشده', 'paid' => 'پرداخت‌شده',
                        'partial' => 'پرداخت جزئی', 'void' => 'باطل',
                    ][$state] ?? $state),
                Tables\Columns\TextColumn::make('grand_total')->label('مبلغ کل')->money('IRR')->sortable(),
                Tables\Columns\TextColumn::make('balance')->label('مانده')->money('IRR'),
                Tables\Columns\TextColumn::make('issue_date')->label('تاریخ صدور')->jalaliDate()->sortable(),
                Tables\Columns\TextColumn::make('user.name')->label('صادرکننده')->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('type')->label('نوع')->options(['proforma' => 'پیش‌فاکتور', 'invoice' => 'فاکتور', 'official' => 'فاکتور رسمی']),
                Tables\Filters\SelectFilter::make('status')->label('وضعیت')->options([
                    'draft' => 'پیش‌نویس', 'issued' => 'صادرشده', 'paid' => 'پرداخت‌شده',
                    'partial' => 'پرداخت جزئی', 'void' => 'باطل',
                ]),
            ])
            ->actions([
                Tables\Actions\Action::make('print')->label('چاپ / PDF')->icon('heroicon-o-printer')->color('gray')
                    ->visible(fn () => auth()->user()?->can('print_invoices'))
                    ->url(fn (Invoice $record) => route('invoices.print', $record))->openUrlInNewTab(),
                Tables\Actions\Action::make('excel')->label('اکسل')->icon('heroicon-o-table-cells')->color('success')
                    ->visible(fn () => auth()->user()?->can('export_invoices'))
                    ->url(fn (Invoice $record) => route('invoices.excel', $record)),
                Tables\Actions\Action::make('convert')->label('تبدیل به فاکتور')->icon('heroicon-o-arrow-path')->color('success')
                    ->visible(fn (Invoice $record) => $record->type === 'proforma' && auth()->user()?->can('convert_invoices'))
                    ->requiresConfirmation()
                    ->action(function (Invoice $record) {
                        $new = $record->convertToInvoice();
                        Notification::make()->success()->title('فاکتور رسمی ساخته شد: ' . $new->number)->send();
                        return redirect(InvoiceResource::getUrl('edit', ['record' => $new]));
                    }),
                Tables\Actions\Action::make('duplicate')->label('تکرار')->icon('heroicon-o-document-duplicate')
                    ->visible(fn () => auth()->user()?->can('create_invoices'))
                    ->action(function (Invoice $record) {
                        $new = $record->duplicate();
                        Notification::make()->success()->title('کپی ساخته شد: ' . $new->number)->send();
                        return redirect(InvoiceResource::getUrl('edit', ['record' => $new]));
                    }),
                Tables\Actions\Action::make('share')->label('لینک اشتراکی')->icon('heroicon-o-link')->color('info')
                    ->action(function (Invoice $record) {
                        $url = route('invoices.share', $record->ensureShareToken());
                        Notification::make()->success()->title('لینک اشتراکی')->body($url)->persistent()->send();
                    }),
                Tables\Actions\EditAction::make(),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                    ExportBulkAction::make()->exports([ExcelExport::make()->fromTable()->withFilename('invoices-' . date('Y-m-d'))]),
                ]),
            ])
            ->headerActions([
                ExportAction::make()->label('خروجی اکسل')->exports([ExcelExport::make()->fromTable()]),
            ])
            ->defaultSort('created_at', 'desc');
    }

    public static function getRelations(): array
    {
        return [
            RelationManagers\PaymentsRelationManager::class,
        ];
    }

    public static function getEloquentQuery(): Builder
    {
        $query = parent::getEloquentQuery();

        $user = auth()->user();
        if ($user && ! $user->canSeeAll('invoices')) {
            $query->where('user_id', $user->id);
        }

        return $query;
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListInvoices::route('/'),
            'create' => Pages\CreateInvoice::route('/create'),
            'edit' => Pages\EditInvoice::route('/{record}/edit'),
        ];
    }
}
