<?php

namespace App\Filament\Pages;

use App\Filament\ReportFuncs\ProfitReport;
use App\Filament\ReportFuncs\AccountLedgerReport;
use App\Filament\ReportFuncs\AccountRetrievalReport;
use App\Filament\ReportFuncs\ItemLedgerReport;
use App\Filament\ReportFuncs\JournalReport;
use App\Filament\ReportFuncs\TradeReport;
use App\Models\Account;
use Filament\Pages\Page;
use App\Models\Item;
use Carbon\Carbon;

use Filament\Forms\Components\Actions;
use Filament\Forms\Components\Actions\Action;

use Filament\Forms\Form;
use Illuminate\Support\Collection;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Select;
use Filament\Forms\Concerns\InteractsWithForms;

class Reports extends Page
{
  use InteractsWithForms;

  protected static ?string $navigationIcon = 'heroicon-o-document-text';
  protected static string $view = 'filament.pages.reports';
  protected static ?string $navigationGroup = 'Reports';

  public string $activeTab = 'journal';
  public Collection $results;

  // stock fields
  public float $openingStock = 0;

  // opening account fields
  public float $accOpeningAfn = 0;
  public float $accOpeningUsd = 0;
  public float $accTotalAfnDebit = 0;
  public float $accTotalAfnCredit = 0;
  public float $accTotalUsdDebit = 0;
  public float $accTotalUsdCredit = 0;




  // Filters for Reports
  public ?string $fromDate = null;
  public ?string $toDate = null;
  public ?int $selectedAccountId = null;
  public ?int $selectedItemId = null;
  public ?string $selectedTradeType = null;


  public function mount(): void
  {

    $this->form->fill([
      'fromDate' => now()->format('Y-m-d'),
      'toDate' => now()->format('Y-m-d'),
    ]);


    $this->results = collect();
  }

  public function updatedActiveTab($value): void
  {
    $this->results = collect();

    if ($value === 'gold_trade') {
      $this->form->fill([
        'selectedAccountId' => '0',
        'selectedItemId' => '0',
        'selectedTradeType' => 'sale',
      ]);
    }
  }


  protected function getViewData(): array
  {
    return [
      'tabs' => [
        'journal' => 'Journals',
        'stock' => 'Stock',
        'item_ledger' => 'Items Ledger',
        'account_ledger' => 'Account Ledger',
        'account_retreval' => 'Account Balances',
        'gold_trade' => 'Gold Operations',
        'profit_report' => 'Profit Report',
      ],
    ];
  }



  public function generate(): void
  {
    $from = $this->fromDate;
    $to = $this->toDate;

    if ($this->activeTab === 'journal') {

      $res = JournalReport::generate($from, $to);

      $this->results = collect($res['results']);
    }

    if ($this->activeTab === 'stock') {
      $this->results = collect(Item::all()->map(function ($item, $key) use ($to) {
        $stock = Item::stockSummary($item->id, $to);
        return [
          'index' => $key + 1,
          'name' => $item->name,
          'qty' => $stock[0],
          'unit_price' => $stock[1],
          'total_price' => round($stock[0] * $stock[1], 2),
        ];
      })->toArray());
    }

    if ($this->activeTab === 'item_ledger') {
      $res = ItemLedgerReport::generate($from, $to, $this->selectedItemId);
      $this->results = collect($res['results']);
      $this->openingStock = $res['opening'];
    }

    if ($this->activeTab === 'account_ledger') {
      $res = AccountLedgerReport::generate($from, $to, $this->selectedAccountId);
      $this->results = collect($res['results']);
      $this->accOpeningAfn = $res['openingAfn'];
      $this->accOpeningUsd = $res['openingUsd'];
      $this->accTotalAfnDebit = $res['totalAfnDebit'];
      $this->accTotalAfnCredit = $res['totalAfnCredit'];
      $this->accTotalUsdDebit = $res['totalUsdDebit'];
      $this->accTotalUsdCredit = $res['totalUsdCredit'];
    }

    if ($this->activeTab === 'account_retreval') {
      $res = AccountRetrievalReport::generate($to);
      $this->results = collect($res['results']);
    }

    if ($this->activeTab === 'gold_trade') {
      $res = TradeReport::generate($from, $to, $this->selectedTradeType);
      $this->results = collect($res['results']);
    }

    if ($this->activeTab === 'profit_report') {
      $res = ProfitReport::generate($from, $to);
      $this->results = collect($res['results']);
    }
  }

  public function form(Form $form): Form
  {
    return $form
      ->schema([
        Grid::make()
          ->schema([
            Select::make('selectedTradeType')
              ->label('Select Report Type')
              ->options([
                'sale' => 'Sale Report',
                'purchase' => 'Purchase Report',
              ])
              ->default('sale')
              ->searchable()->preload()->reactive()
              ->visible(fn() => in_array($this->activeTab, ['gold_trade']))
              ->required(fn() => in_array($this->activeTab, ['gold_trade'])),

            Select::make('selectedAccountId')
              ->label('Select Account')
              ->options(function () {
                $opts = Account::where('type', '!=', 'expense')->pluck('name', 'id')->toArray();

                if (in_array($this->activeTab, ['gold_trade'])) {
                  return [0 => 'All'] + $opts;
                }
                return $opts;
              })
              ->searchable()->preload()->live()->reactive()
              ->visible(fn() => in_array($this->activeTab, ['account_ledger', 'gold_trade']))
              ->required(fn() => in_array($this->activeTab, ['account_ledger', 'gold_trade'])),

            Select::make('selectedItemId')
              ->label('Select Item')
              ->options(function () {
                $opts = Item::query()->pluck('name', 'id')->toArray();

                if (in_array($this->activeTab, ['gold_trade'])) {
                  return [0 => 'All'] + $opts;
                }
                return $opts;
              })
              ->searchable()->preload()->live()->reactive()
              ->visible(fn() => in_array($this->activeTab, ['item_ledger', 'gold_trade']))
              ->required(fn() => in_array($this->activeTab, ['item_ledger', 'gold_trade'])),

            DatePicker::make('fromDate')
              ->label('From Date')
              ->required()->native(false)->displayFormat('Y-m-d')->reactive()
              ->visible(fn() => !in_array($this->activeTab, ['stock', 'account_retreval',])),

            DatePicker::make('toDate')
              ->label('To Date')
              ->required()->native(false)->displayFormat('Y-m-d')->reactive()
            // ->minDate(fn(callable $get) => $get('fromDate') ?: now())
            ,


            Actions::make([
              Action::make('submit')
                ->label('Generate Report')
                ->color('primary')->action('generate')
                ->disabled(
                  fn() => ($this->activeTab === 'account_ledger' && empty($this->selectedAccountId)) ||
                    ($this->activeTab === 'item_ledger' && empty($this->selectedItemId)) ||
                    ($this->activeTab === 'gold_trade' && empty($this->selectedTradeType))
                )->extraAttributes(['style' => 'margin-top: 32px;'])
            ])
          ])
          ->columns([
            'md' => 2,
            'lg' => 4,
          ]),


      ]);
  }

  // Helper methods for the blade template
  public function getSelectedDateRange(): string
  {
    return sprintf(
      'From: %s To: %s',
      $this->fromDate ? Carbon::parse($this->fromDate)->format('Y-m-d') : '-',
      $this->toDate ? Carbon::parse($this->toDate)->format('Y-m-d') : '-'
    );
  }

  public function getToDateFormatted(): string
  {
    return $this->toDate ? Carbon::parse($this->toDate)->format('Y-m-d') : '-';
  }

  public function getSelectedAccountName(): string
  {
    return $this->selectedAccountId
      ? Account::find($this->selectedAccountId)?->name
      : '-';
  }

  public function getSelectedItemName(): string
  {
    return $this->selectedItemId
      ? Item::find($this->selectedItemId)?->name
      : '-';
  }

  public function getSelectedTradeType(): string
  {
    return match ($this->selectedTradeType) {
      'sale' => 'Sale Report',
      'purchase' => 'Purchase Report',
      default => 'sale',
    };
  }
}
