<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;

class Overtime extends BaseModel
{
    use HasFactory;

    protected $fillable = [
        'employee_id',
        'site_id',
        'check_in',
        'check_out',
        'date',
        'working_hours',
        'status',
        'description',
        'customer_id',
        'workspace_id'
    ];

    protected $hidden = [
        'customer_id',
        'workspace_id',
    ];

    // Note: Removed $dates and $casts for date/datetime fields to prevent Carbon::parse errors
    // Date/time formatting is now handled by BaseModel's safe parsing logic
    
    protected $casts = [
        // Removed check_in and check_out datetime casts
    ];

    /**
     * Override setAttribute to handle datetime fields properly
     */
    public function setAttribute($key, $value)
    {
        // Handle datetime fields (check_in, check_out) differently from date fields
        if (in_array($key, ['check_in', 'check_out']) && $value) {
            try {
                // Debug: Log the incoming value
                Log::info("Overtime setAttribute - Field: {$key}, Value: {$value}");
                
                // Check if the value is only a time (HH:mm or HH:mm:ss format)
                if (is_string($value) && preg_match('/^(\d{1,2}):(\d{2})(:\d{2})?$/', $value)) {
                    // If only time is provided, combine it with the date field
                    $dateValue = $this->attributes['date'] ?? now()->format('Y-m-d');
                    $value = $dateValue . ' ' . $value;
                    Log::info("Overtime setAttribute - Combined time with date: {$value}");
                }
                
                // Fix malformed timezone offset before parsing
                if (is_string($value) && preg_match('/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([+-]?)(\d{2}:\d{2})$/', $value, $matches)) {
                    $dateTimePart = $matches[1];
                    $sign = $matches[2];
                    $timezoneOffset = $matches[3];
                    
                    // Add the '+' sign for positive timezone offsets if missing
                    if (empty($sign)) {
                        $sign = '+';
                    }
                    
                    $value = $dateTimePart . $sign . $timezoneOffset;
                }
                
                // Try to parse the datetime value and keep both date and time
                $parsedValue = \Carbon\Carbon::parse($value)->format('Y-m-d H:i:s');
                Log::info("Overtime setAttribute - Final parsed value for {$key}: {$parsedValue}");
                $this->attributes[$key] = $parsedValue;
                return $this;
            } catch (\Exception $e) {
                // If parsing fails, let parent handle it
                Log::warning("Failed to parse datetime for field '{$key}' with value '{$value}': " . $e->getMessage());
            }
        }
        
        return parent::setAttribute($key, $value);
    }

    /**
     * Accessor for check_in to format according to system settings
     */
    public function getCheckInAttribute($value)
    {
        if ($value) {
            try {
                $carbonDate = \Carbon\Carbon::parse($value);
                $userDateFormat = $this->getUserDateFormat();
                $userTimeFormat = $this->getUserTimeFormat();
                
                // Format as date and time according to user preferences
                return $carbonDate->format($userDateFormat . ' ' . $userTimeFormat);
            } catch (\Exception $e) {
                Log::warning("Failed to format check_in datetime: " . $e->getMessage());
                return $value;
            }
        }
        return $value;
    }

    /**
     * Accessor for check_out to format according to system settings
     */
    public function getCheckOutAttribute($value)
    {
        if ($value) {
            try {
                $carbonDate = \Carbon\Carbon::parse($value);
                $userDateFormat = $this->getUserDateFormat();
                $userTimeFormat = $this->getUserTimeFormat();
                
                // Format as date and time according to user preferences
                return $carbonDate->format($userDateFormat . ' ' . $userTimeFormat);
            } catch (\Exception $e) {
                Log::warning("Failed to format check_out datetime: " . $e->getMessage());
                return $value;
            }
        }
        return $value;
    }

    /**
     * Override toArray to handle custom datetime formatting for check_in and check_out
     */
    public function toArray()
    {
        $array = parent::toArray();
        
        // Format check_in and check_out according to user preferences
        $userDateFormat = $this->getUserDateFormat();
        $userTimeFormat = $this->getUserTimeFormat();
        
        if (isset($array['check_in']) && $array['check_in']) {
            try {
                // Get the raw original value to avoid double parsing
                $rawValue = $this->getRawOriginal('check_in');
                if ($rawValue) {
                    $carbonDate = \Carbon\Carbon::parse($rawValue);
                    $array['check_in'] = $carbonDate->format($userDateFormat . ' ' . $userTimeFormat);
                }
            } catch (\Exception $e) {
                Log::warning("Failed to format check_in in toArray: " . $e->getMessage());
            }
        }
        
        if (isset($array['check_out']) && $array['check_out']) {
            try {
                // Get the raw original value to avoid double parsing
                $rawValue = $this->getRawOriginal('check_out');
                if ($rawValue) {
                    $carbonDate = \Carbon\Carbon::parse($rawValue);
                    $array['check_out'] = $carbonDate->format($userDateFormat . ' ' . $userTimeFormat);
                }
            } catch (\Exception $e) {
                Log::warning("Failed to format check_out in toArray: " . $e->getMessage());
            }
        }
        
        return $array;
    }

    public function emppersonaldetails()
    {
        return $this->belongsTo(EmpPersonalDetails::class, 'employee_id', 'emp_id');
    }

    public function empTeamsMembers()
    {
        return $this->hasMany(EmpTeamsMember::class, 'emp_id', 'employee_id')->with('empTeamsList');
    }

    public function empcompanydetails()
    {
        return $this->belongsTo(EmpCompanyDetails::class, 'employee_id', 'id');
    }
    public function sites()
    {
        return $this->belongsTo(Sites::class, 'site_id');
    }

    /**
     * Check if overtime is pending
     */
    public function isPending()
    {
        return $this->status === config('constants.overtime_status.pending');
    }

    /**
     * Check if overtime is approved
     */
    public function isApproved()
    {
        return $this->status === config('constants.overtime_status.approved');
    }

    /**
     * Check if overtime is rejected
     */
    public function isRejected()
    {
        return $this->status === config('constants.overtime_status.rejected');
    }

    /**
     * Get all possible overtime statuses
     */
    public static function getStatuses()
    {
        return config('constants.overtime_status');
    }

    

}
