<?php

namespace App\Livewire\HR;

use App\Domain\HR\Enums\PayrollPeriodStatus;
use App\Domain\HR\Enums\PayslipStatus;
use App\Domain\HR\Models\PayrollPeriod;
use App\Domain\HR\Models\Payslip;
use App\Domain\HR\Models\Trainer;
use App\Domain\HR\Services\PayrollService;
use App\Domain\Shared\Traits\UsesBranchScope;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('إدارة الرواتب')]
class PayrollDashboard extends Component
{
    use WithPagination, UsesBranchScope;

    #[Url]
    public string $periodFilter = '';

    #[Url]
    public string $payslipStatus = '';

    #[Url]
    public string $search = '';

    #[Url]
    public string $activeTab = 'periods'; // periods | payslips

    // Stats
    public bool $payrollEnabled = false;
    public int $totalPayrollThisMonth = 0;
    public int $pendingApprovals = 0;
    public int $paidThisMonth = 0;
    public int $activeTrainers = 0;

    // Mark-paid modal state
    public bool $showMarkPaidModal = false;
    public ?int $markPaidPayslipId = null;
    public string $markPaidMethod = 'cash';
    public string $markPaidReference = '';

    public function mount(): void
    {
        $this->authorize('payroll.manage');
        $this->loadStats();
    }

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedPeriodFilter(): void
    {
        $this->resetPage();
    }

    public function updatedPayslipStatus(): void
    {
        $this->resetPage();
    }

    public function loadStats(): void
    {
        $academyId = app('current_academy')->id;

        $this->payrollEnabled = (bool) app(\App\Domain\Shared\Services\SettingsService::class)->get('payroll_enabled', false);

        $currentPeriod = PayrollPeriod::where('academy_id', $academyId)
            ->latest('period_start')
            ->first();

        $this->totalPayrollThisMonth = $currentPeriod?->total_net ?? 0;
        $branchId = $this->getActiveBranchId();

        $this->pendingApprovals = Payslip::where('academy_id', $academyId)
            ->when($branchId, fn ($q) => $q->whereHas('trainer.employee', fn ($e) => $e->forBranch($branchId)))
            ->whereIn('status', [
                PayslipStatus::Draft->value,
                PayslipStatus::PendingApproval->value,
            ])
            ->count();

        $this->paidThisMonth = Payslip::where('academy_id', $academyId)
            ->when($branchId, fn ($q) => $q->whereHas('trainer.employee', fn ($e) => $e->forBranch($branchId)))
            ->where('status', PayslipStatus::Paid->value)
            ->whereMonth('paid_at', now()->month)
            ->whereYear('paid_at', now()->year)
            ->sum('net_amount');

        $this->activeTrainers = Trainer::where('academy_id', $academyId)
            ->when($branchId, fn ($q) => $q->whereHas('employee', fn ($e) => $e->forBranch($branchId)))
            ->where('status', 'active')
            ->count();
    }

    public function enablePayroll(): void
    {
        app(\App\Domain\Shared\Services\SettingsService::class)->set('payroll_enabled', '1');
        app(\App\Domain\Shared\Services\SettingsService::class)->set('auto_trainer_compensation_enabled', '1');
        $this->payrollEnabled = true;
        session()->flash('success', __('تم تفعيل نظام الرواتب'));
        $this->loadStats();
    }

    public function createPeriod(): void
    {
        try {
            $service = app(PayrollService::class);
            $service->getOrCreateCurrentPeriod(
                app('current_academy')->id,
                auth()->user()
            );
            session()->flash('success', __('تم إنشاء فترة الرواتب بنجاح'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function calculatePeriod(int $periodId): void
    {
        try {
            $period = PayrollPeriod::findOrFail($periodId);
            $service = app(PayrollService::class);
            $service->calculatePeriod($period, auth()->user());
            session()->flash('success', __('تم احتساب كشوف الرواتب بنجاح'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function approvePeriod(int $periodId): void
    {
        try {
            $period = PayrollPeriod::findOrFail($periodId);
            $service = app(PayrollService::class);
            $service->approvePeriod($period, auth()->user());
            session()->flash('success', __('تم اعتماد فترة الرواتب'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function closePeriod(int $periodId): void
    {
        try {
            $period = PayrollPeriod::findOrFail($periodId);
            $service = app(PayrollService::class);
            $service->closePeriod($period, auth()->user());
            session()->flash('success', __('تم إغلاق فترة الرواتب'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function approvePayslip(int $payslipId): void
    {
        try {
            $payslip = Payslip::findOrFail($payslipId);
            $service = app(PayrollService::class);
            $service->approvePayslip($payslip, auth()->user());
            session()->flash('success', __('تم اعتماد كشف الراتب'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function openMarkPaidModal(int $payslipId): void
    {
        $this->markPaidPayslipId = $payslipId;
        $this->markPaidMethod = 'cash';
        $this->markPaidReference = '';
        $this->showMarkPaidModal = true;
    }

    public function confirmMarkPaid(): void
    {
        if (!$this->markPaidPayslipId) {
            return;
        }

        try {
            $payslip = Payslip::findOrFail($this->markPaidPayslipId);
            $service = app(PayrollService::class);
            $service->markPaid(
                $payslip,
                $this->markPaidMethod,
                $this->markPaidReference ?: null,
                auth()->user()
            );
            $this->showMarkPaidModal = false;
            $this->markPaidPayslipId = null;
            session()->flash('success', __('تم تسجيل الدفع بنجاح'));
            $this->loadStats();
        } catch (\Throwable $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function closeModal(): void
    {
        $this->showMarkPaidModal = false;
        $this->markPaidPayslipId = null;
    }

    public function render()
    {
        $periodsQuery = PayrollPeriod::where('academy_id', app('current_academy')->id)
            ->latest('period_start');

        if ($this->periodFilter) {
            $periodsQuery->where('status', $this->periodFilter);
        }

        $payslipsQuery = Payslip::with(['trainer.employee.person', 'trainer.person', 'period'])
            ->where('academy_id', app('current_academy')->id)
            ->when($this->getActiveBranchId(), fn ($q) => $q->whereHas('trainer.employee', fn ($e) => $e->forBranch($this->getActiveBranchId())))
            ->latest();

        if ($this->payslipStatus) {
            $payslipsQuery->where('status', $this->payslipStatus);
        }

        if ($this->search) {
            $search = $this->search;
            $payslipsQuery->whereHas('trainer.employee.person', function ($q) use ($search) {
                $q->where('name_ar', 'ilike', "%{$search}%")
                    ->orWhere('name', 'ilike', "%{$search}%");
            });
        }

        return view('livewire.hr.payroll-dashboard', [
            'periods'         => $periodsQuery->paginate(10, pageName: 'periodsPage'),
            'payslips'        => $payslipsQuery->paginate(15, pageName: 'payslipsPage'),
            'periodStatuses'  => PayrollPeriodStatus::cases(),
            'payslipStatuses' => PayslipStatus::cases(),
            'paymentMethods'  => \App\Domain\HR\Enums\StaffPaymentMethod::cases(),
        ]);
    }
}
