<?php

namespace App\Services;

use App\Models\Employee;
use App\Models\TerminationLog;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class EmployeeDismissalService
{
    /**
     * Dismiss an employee with all cascading actions
     */
    public function dismiss(Employee $employee, string $reason, User $performedBy, array $options = []): TerminationLog
    {
        return DB::transaction(function () use ($employee, $reason, $performedBy, $options) {
            $processedActions = [];
            
            //Update employee status
            $employee->update([
                'status' => 'terminated',
                'dismissed_at' => now(),
                'dismissed_by' => $performedBy->id,
                'dismissal_reason' => $reason,
            ]);
            $processedActions['employee_status'] = 'updated_to_terminated';
            
            // Update employee profile status
            if ($employee->profile) {
                $employee->profile->update([
                    'status' => 'terminated',
                    'dismissed_at' => now(),
                ]);
                $processedActions['employee_profile'] = 'updated_to_terminated';
            }
            
            // Unlink from stations (soft delete)
            $unlinkedStations = $employee->stations()->update([
                'deleted_at' => now(),
            ]);
            $processedActions['stations_unlinked'] = $unlinkedStations;
            
            // Block future deductions (soft delete active assignments)
            $blockedDeductions = DB::table('employee_deductions')
                ->where('employee_id', $employee->id)
                ->whereNull('deleted_at')
                ->update(['deleted_at' => now()]);
            $processedActions['deductions_blocked'] = $blockedDeductions;
            
            // Cancel future scheduled payments
            $cancelledSchedules = DB::table('salary_payment_schedules')
                ->where('employee_id', $employee->id)
                ->whereNull('deleted_at')
                ->whereDate('scheduled_date', '>', now())
                ->update(['deleted_at' => now()]);
            $processedActions['future_payments_cancelled'] = $cancelledSchedules;
            
            // Update salary_employees status
            if ($employee->salaryEmployee) {
                $employee->salaryEmployee->update(['status' => 'terminated']);
                $processedActions['salary_employee'] = 'updated_to_terminated';
            }
            
            //Create termination log
            $terminationLog = TerminationLog::create([
                'employee_id' => $employee->id,
                'termination_date' => now(),
                'reason' => $reason,
                'processed_actions' => $processedActions,
                'metadata' => $options,
                'performed_by' => $performedBy->id,
                'is_reversed' => false,
            ]);
            
            // 8. Log audit trail
            Log::info('Employee dismissed', [
                'employee_id' => $employee->id,
                'employee_name' => $employee->name,
                'performed_by' => $performedBy->id,
                'reason' => $reason,
                'actions' => $processedActions,
            ]);
            
            return $terminationLog;
        });
    }
    
    /**
     * Reverse dismissal (reinstatement)
     */
    public function reinstate(Employee $employee, User $performedBy, string $reason = null): bool
    {
        return DB::transaction(function () use ($employee, $performedBy, $reason) {
            // Find the latest termination log
            $terminationLog = TerminationLog::where('employee_id', $employee->id)
                ->where('is_reversed', false)
                ->latest()
                ->first();
                
            if (!$terminationLog) {
                throw new \Exception('No active termination record found for this employee.');
            }
            
            //Restore employee status
            $employee->update([
                'status' => 'active',
                'dismissed_at' => null,
                'dismissed_by' => null,
                'dismissal_reason' => null,
            ]);
            
            //Restore profile status
            if ($employee->profile) {
                $employee->profile->update([
                    'status' => 'active',
                    'dismissed_at' => null,
                ]);
            }
            
            //Restore station assignments
            $employee->stations()->restore();
            
            //Restore deductions
            DB::table('employee_deductions')
                ->where('employee_id', $employee->id)
                ->update(['deleted_at' => null]);
            
            //Restore future payment schedules
            DB::table('salary_payment_schedules')
                ->where('employee_id', $employee->id)
                ->whereDate('scheduled_date', '>', now())
                ->update(['deleted_at' => null]);
            
            //Restore salary employee status
            if ($employee->salaryEmployee) {
                $employee->salaryEmployee->update(['status' => 'active']);
            }
            
            //Update termination log
            $terminationLog->update([
                'is_reversed' => true,
                'reversed_at' => now(),
                'reversed_by' => $performedBy->id,
            ]);
            
            //Create reinstatement log entry
            Log::info('Employee reinstated', [
                'employee_id' => $employee->id,
                'employee_name' => $employee->name,
                'performed_by' => $performedBy->id,
                'reason' => $reason,
                'original_termination_id' => $terminationLog->id,
            ]);
            
            return true;
        });
    }

    protected function unlinkFromStations(Employee $employee)
    {
        if (method_exists($employee, 'stations')) {
            foreach ($employee->stations as $station) {
                $employee->stations()->updateExistingPivot($station->id, [
                    'deleted_at' => now()
                ]);
            }
        }
    }
}