<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Carbon\Carbon;

class Holiday extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'created_by',
        'from_date',
        'to_date',
        'name',
        'year_type', // 'calendar' or 'fiscal'
        'fiscal_year_start', // month number for fiscal year start (1-12)
        'year_identifier', // e.g., '2024', 'FY2024-25'
        'is_deleted',
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    protected $casts = [
        'from_date' => 'date',
        'to_date' => 'date',
        'is_deleted' => 'boolean',
        'fiscal_year_start' => 'integer',
    ];

    /**
     * Get the user who created the holiday
     */
    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Get the year identifier based on year type
     */
    public function getYearIdentifier(): string
    {
        if ($this->year_type === 'calendar') {
            return $this->from_date->format('Y');
        }

        // Fiscal year logic
        return $this->getFiscalYearIdentifier($this->from_date);
    }

    /**
     * Get fiscal year identifier for a date
     */
    private function getFiscalYearIdentifier(Carbon $date): string
    {
        $startMonth = $this->fiscal_year_start ?? 4; // Default April
        $year = $date->year;

        if ($date->month >= $startMonth) {
            return "FY{$year}-" . ($year + 1);
        } else {
            return "FY" . ($year - 1) . "-{$year}";
        }
    }

    /**
     * Scope to get holidays by calendar year
     */
    public function scopeByCalendarYear($query, int $year)
    {
        return $query->where('year_type', 'calendar')
            ->whereYear('from_date', $year);
    }

    /**
     * Scope to get holidays by fiscal year
     */
    public function scopeByFiscalYear($query, string $fiscalYear, int $startMonth = 4)
    {
        // Parse fiscal year like "FY2024-25"
        preg_match('/FY(\d{4})-?(\d{2})?/', $fiscalYear, $matches);
        $startYear = (int) $matches[1];
        $endYear = isset($matches[2]) ? 2000 + (int) $matches[2] : $startYear + 1;

        return $query->where('year_type', 'fiscal')
            ->where('fiscal_year_start', $startMonth)
            ->where(function ($q) use ($startYear, $endYear, $startMonth) {
                $q->whereYear('from_date', $startYear)
                  ->whereMonth('from_date', '>=', $startMonth)
                  ->orWhere(function ($subQ) use ($endYear, $startMonth) {
                      $subQ->whereYear('from_date', $endYear)
                           ->whereMonth('from_date', '<', $startMonth);
                  });
            });
    }

    /**
     * Get holidays for a specific year based on organization settings
     */
    public static function getHolidaysForYear(int $year, string $yearType = 'calendar', int $fiscalStartMonth = 4)
    {
        if ($yearType === 'calendar') {
            return self::byCalendarYear($year)->with(['creator:id,name,image_path'])->get();
        }

        $fiscalYear = "FY{$year}-" . ($year + 1);
        return self::byFiscalYear($fiscalYear, $fiscalStartMonth)->with(['creator:id,name,image_path'])->get();
    }

    /**
     * Check if a date falls within a holiday based on year type
     */
    public static function isHolidayForDate(Carbon $date, string $yearType = 'calendar', int $fiscalStartMonth = 4): bool
    {
        $query = self::where('is_deleted', 0)
            ->whereDate('from_date', '<=', $date)
            ->whereDate('to_date', '>=', $date);

        if ($yearType === 'calendar') {
            $query->where('year_type', 'calendar')
                  ->whereYear('from_date', $date->year);
        } else {
            $fiscalYear = (new self)->getFiscalYearIdentifier($date);
            $query->where('year_type', 'fiscal')
                  ->where('fiscal_year_start', $fiscalStartMonth)
                  ->where('year_identifier', $fiscalYear);
        }

        return $query->exists();
    }

    /**
     * Get available year types
     */
    public static function getYearTypes(): array
    {
        return [
            'calendar' => 'Calendar Year (Jan-Dec)',
            'fiscal' => 'Fiscal Year (Custom Start)',
        ];
    }

    /**
     * Get fiscal year start months
     */
    public static function getFiscalYearStartMonths(): array
    {
        return [
            1 => 'January',
            2 => 'February',
            3 => 'March',
            4 => 'April',
            5 => 'May',
            6 => 'June',
            7 => 'July',
            8 => 'August',
            9 => 'September',
            10 => 'October',
            11 => 'November',
            12 => 'December',
        ];
    }
}
