<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\User;
use App\Models\SalaryHistory;
use App\Services\PayrollService;
use App\Traits\HasNotifications;
use Carbon\Carbon;

class SalaryHistoryManager extends Component
{
    use WithPagination, HasNotifications;

    public $adjustmentType = 'bonus';
    public $adjustmentAmount = 0;
    public $adjustmentReason = '';
    public $selectedSalaryId = null;
    public $search = '';
    public $downloadFormat = 'csv';
    public $viewMonth;
    public $viewYear;



    public function mount()
    {
        $this->viewMonth = Carbon::now()->format('F');
        $this->viewYear = Carbon::now()->year;
    }





    public function addAdjustment()
    {
        $this->validate([
            'adjustmentType' => 'required|in:bonus,deduction',
            'adjustmentAmount' => 'required|numeric|min:0',
            'adjustmentReason' => 'nullable|string|max:500',
        ]);

        try {
            $salaryHistory = SalaryHistory::find($this->selectedSalaryId);
            $payrollService = new PayrollService();

            $payrollService->addSalaryAdjustment(
                $salaryHistory,
                $this->adjustmentType,
                $this->adjustmentAmount,
                $this->adjustmentReason
            );

            $this->showSuccess(ucfirst($this->adjustmentType) . ' added successfully!', 'Payroll Management');
            $this->reset(['adjustmentType', 'adjustmentAmount', 'adjustmentReason', 'selectedSalaryId']);
            $this->dispatch('adjustment-added');
        } catch (\Exception $e) {
            $this->showError('Failed to add adjustment: ' . $e->getMessage(), 'Payroll Management');
        }
    }

    public function confirmMarkAsPaid($salaryId)
    {
        $this->dispatch('set-pending-action', ['action' => 'markAsPaid', 'id' => $salaryId]);
        
        $this->confirmAction(
            'Mark Salary as Paid?',
            'This will mark the salary as paid and cannot be undone.',
            'Yes, Mark as Paid!',
            'Cancel'
        );
    }

    public function markAsPaid($salaryId)
    {
        try {
            $salary = SalaryHistory::find($salaryId);
            $payrollService = new PayrollService();
            $payrollService->markSalaryAsPaid($salary);

            $this->showSuccess('Salary marked as paid successfully!', 'Payroll Management');
        } catch (\Exception $e) {
            $this->showError('Failed to mark salary as paid: ' . $e->getMessage(), 'Payroll Management');
        }
    }

    public function confirmMarkAsRefunded($salaryId)
    {
        $this->dispatch('set-pending-action', ['action' => 'markAsRefunded', 'id' => $salaryId]);
        
        $this->confirmAction(
            'Mark Salary as Refunded?',
            'This will mark the salary as refunded and reset the paid date.',
            'Yes, Mark as Refunded!',
            'Cancel'
        );
    }

    public function markAsRefunded($salaryId)
    {
        try {
            $salary = SalaryHistory::find($salaryId);
            $payrollService = new PayrollService();
            $payrollService->markSalaryAsRefunded($salary);

            $this->showSuccess('Salary marked as refunded successfully!', 'Payroll Management');
        } catch (\Exception $e) {
            $this->showError('Failed to mark salary as refunded: ' . $e->getMessage(), 'Payroll Management');
        }
    }

    public function confirmGenerateMonthlyPayroll()
    {
        $this->confirmAction(
            'Generate Monthly Payroll?',
            "This will generate payroll for staff who don't have records for {$this->viewMonth} {$this->viewYear}. Existing records will not be affected.",
            'Yes, Generate Payroll!',
            'Cancel'
        );
    }

    public function confirmResetPayroll()
    {
        $this->confirmAction(
            'Reset Payroll Entries?',
            "This will remove all bonuses and deductions from unpaid payroll entries for {$this->viewMonth} {$this->viewYear}. Paid entries will not be affected.",
            'Yes, Reset Payroll!',
            'Cancel'
        );
    }

    public function generateMonthlyPayroll()
    {
        try {
            $payrollService = new PayrollService();
            $generated = $payrollService->generateMonthlyPayroll($this->viewMonth, $this->viewYear);

            if ($generated > 0) {
                $this->showSuccess("Generated payroll for {$generated} new staff members for {$this->viewMonth} {$this->viewYear}!", 'Payroll Management');
            } else {
                $this->showInfo('All staff already have payroll entries for this period.', 'Payroll Management');
            }
        } catch (\Exception $e) {
            $this->showError('Failed to generate payroll: ' . $e->getMessage(), 'Payroll Management');
        }
    }

    public function resetPayroll()
    {
        try {
            $payrollService = new PayrollService();
            $updated = $payrollService->resetPayrollEntries($this->viewMonth, $this->viewYear);

            $this->showSuccess("Reset bonuses and deductions for {$updated} unpaid payroll entries for {$this->viewMonth} {$this->viewYear}!", 'Payroll Management');
        } catch (\Exception $e) {
            $this->showError('Failed to reset payroll: ' . $e->getMessage(), 'Payroll Management');
        }
    }

    public function downloadPayroll()
    {
        return redirect()->route('payroll.download', [
            'month' => $this->viewMonth,
            'year' => $this->viewYear,
            'format' => $this->downloadFormat
        ]);
    }



    public function render()
    {
        $staff = User::whereHas('roles')
            ->whereNotNull('monthly_salary')
            ->get();

        $salaryHistories = SalaryHistory::with(['user', 'adjustments'])
            ->where('month', $this->viewMonth)
            ->where('year', $this->viewYear)
            ->when($this->search, function ($query) {
                $query->whereHas('user', function ($q) {
                    $q->where('firstname', 'like', '%' . $this->search . '%')
                      ->orWhere('surname', 'like', '%' . $this->search . '%');
                });
            })
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        $months = [
            'January', 'February', 'March', 'April', 'May', 'June',
            'July', 'August', 'September', 'October', 'November', 'December'
        ];

        return view('livewire.salary-history-manager', compact('staff', 'salaryHistories', 'months'));
    }

    #[\Livewire\Attributes\On('action-confirmed')]
    public function handleActionConfirmed($action, $id = null)
    {
        if ($action === 'markAsPaid' && $id) {
            $this->markAsPaid($id);
        } elseif ($action === 'markAsRefunded' && $id) {
            $this->markAsRefunded($id);
        } elseif ($action === 'generateMonthlyPayroll') {
            $this->generateMonthlyPayroll();
        } elseif ($action === 'resetPayroll') {
            $this->resetPayroll();
        }
    }

    #[\Livewire\Attributes\On('confirm-generate-payroll')]
    public function handleConfirmGeneratePayroll()
    {
        $this->confirmAction(
            'Generate Monthly Payroll?',
            "This will generate payroll for all staff for {$this->month} {$this->year}. Existing records will be updated.",
            'Yes, Generate Payroll!',
            'Cancel'
        );
    }
}