<?php

namespace App\Livewire\Components;

use Livewire\Component;
use Illuminate\Support\Facades\Log;

class Table extends Component
{
    // Table Configuration
    public $columns = [];
    public $rows = [];
    public $selected = [];
    public $addRoute = null;
    public $hasAddButton = true;
    public $hasDelete = true;
    public $selectAll = false;
    public $hasCheckbox = true;
    public $hasActions = false;
    public $isViewPage = false;
    public $search = '';
    public $sortField = null;
    public $sortDirection = 'asc';
    public bool $hasSearch = true;

    public $startDate;
    public $endDate;

    // Pagination Configuration
    public $perPage = 5;
    public $page = 1;
    public $renderKey = 0; // Dummy property to force re-render

    // Modal Configuration
    public $showModal = false;
    public $modalMode = 'view';
    public $modalData = [];

    public function mount($columns, $rows, $addRoute = null)
    {
        $this->columns = $columns;
        // Convert $rows to a plain array to ensure consistent pagination
        $this->rows = collect($rows)->map(function ($row) {
            return is_array($row) ? $row : (array) $row;
        })->values()->toArray();
        $this->addRoute = $addRoute;
        Log::info("Initial rows count: " . count($this->rows));
    }

    public function viewRow($id)
    {
        $this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
        $this->modalMode = 'view';
        $this->showModal = true;
    }

    public function editRow($id)
    {
        $this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
        $this->modalMode = 'edit';
        $this->showModal = true;
    }

    public function closeModal()
    {
        $this->showModal = false;
        $this->modalData = [];
    }

    public function updatedSearch()
    {
        $this->selected = [];
        $this->page = 1;
        $this->forceRender();
    }

    public function updatedStartDate()
    {
        $this->page = 1;
        $this->forceRender();
    }

    public function updatedEndDate()
    {
        $this->page = 1;
        $this->forceRender();
    }

    public function selectAllRows()
    {
        $currentRows = $this->getPaginatedRows();
        if ($this->selectAll) {
            $this->selected = collect($currentRows)->pluck('id')->toArray();
        } else {
            $this->selected = [];
        }
    }

    public function selectRow($rowId)
    {
        if (in_array($rowId, $this->selected)) {
            $this->selected = array_diff($this->selected, [$rowId]);
        } else {
            $this->selected[] = $rowId;
        }
    }

    public function sortBy($field)
    {
        if ($this->sortField === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortField = $field;
            $this->sortDirection = 'asc';
        }
        $this->page = 1;
        $this->forceRender();
    }

    public function gotoPage($page)
    {
        $totalRows = $this->getFilteredRows()->count();
        $lastPage = max(1, ceil($totalRows / $this->perPage));
        $newPage = min(max(1, (int) $page), $lastPage);
        $this->page = $newPage;
        $this->forceRender();
        Log::info("Page updated to: {$this->page}, Total Rows: {$totalRows}, Last Page: {$lastPage}");
    }

    private function forceRender()
    {
        $this->renderKey++; // Increment to force Livewire to re-render
    }

    private function getFilteredRows()
    {
        $filteredRows = collect($this->rows);

        // Apply search filtering
        if ($this->hasSearch && $this->search) {
            $filteredRows = $filteredRows->filter(function ($row) {
                foreach ($this->columns as $column) {
                    if (stripos($row[$column['field']] ?? '', $this->search) !== false) {
                        return true;
                    }
                }
                return false;
            });
        }

        // Apply date filtering
        if (!$this->hasSearch && ($this->startDate || $this->endDate)) {
            $filteredRows = $filteredRows->filter(function ($row) {
                $date = $row['created_at'] ?? null;
                if ($date) {
                    $date = strtotime($date);
                    $start = $this->startDate ? strtotime($this->startDate) : null;
                    $end = $this->endDate ? strtotime($this->endDate) : null;

                    if ($start && $date < $start) {
                        return false;
                    }
                    if ($end && $date > $end) {
                        return false;
                    }
                }
                return true;
            });
        }

        // Apply sorting
        if ($this->sortField) {
            $filteredRows = $filteredRows->sortBy($this->sortField, SORT_REGULAR, $this->sortDirection === 'desc');
        }

        return $filteredRows->values();
    }

    private function getPaginatedRows()
    {
        $filteredRows = $this->getFilteredRows();
        $start = ($this->page - 1) * $this->perPage;
        $paginated = $filteredRows->slice($start, $this->perPage)->values()->toArray();
        // Force Livewire to detect the change by serializing and unserializing
        $result = json_decode(json_encode($paginated), true);
        Log::info("Paginated rows count: " . count($result) . ", Start: {$start}, Page: {$this->page}, First Username: " . ($result[0]['username'] ?? 'N/A'));
        return $result;
    }

    public function render()
    {
        $filteredRows = $this->getFilteredRows();
        $total = $filteredRows->count();
        $lastPage = max(1, ceil($total / $this->perPage));
        $this->page = min(max(1, $this->page), $lastPage);

        $paginatedRows = $this->getPaginatedRows();
        Log::info("Rendering - Total Rows: {$total}, Current Page: {$this->page}, Last Page: {$lastPage}, Displayed Rows: " . count($paginatedRows));

        return view('livewire.components.table', [
            'rows' => $paginatedRows,
            'totalRows' => $total,
            'perPage' => $this->perPage,
            'currentPage' => $this->page,
            'lastPage' => $lastPage,
            'renderKey' => $this->renderKey,
        ]);
    }
}