<?php

namespace Modules\Accounts\Database\Seeders;

use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Modules\Accounts\Enums\AccountingPeriodStatusEnum;
use Modules\Accounts\Enums\FiscalYearStatusEnum;
use Modules\Accounts\Enums\PeriodTypeEnum;
use Modules\Accounts\Models\AccountingPeriod;
use Modules\Accounts\Models\FiscalYear;

class FiscalYearSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $today = Carbon::today();

        if ($today->month >= 7) {
            $startYear = $today->year;
            $endYear = $today->year + 1;
        } else {
            $startYear = $today->year - 1;
            $endYear = $today->year;
        }

        $code = sprintf(
            'FY%s%s',
            substr((string) $startYear, -2),
            substr((string) $endYear, -2)
        );

        $name = "FY{$startYear}-{$endYear}";
        
        $startDate = Carbon::create($startYear, 7, 1)->startOfDay();
        $endDate = Carbon::create($endYear, 6, 30)->endOfDay();

        FiscalYear::query()->update([
            'is_current' => false,
        ]);

        $fiscalYear = FiscalYear::updateOrCreate(
            [
                'code' => $code,
            ],
            [
                'name' => $name,
                'start_date' => $startDate,
                'end_date' => $endDate,
                'is_current' => true,
                'status' => FiscalYearStatusEnum::OPEN->value,
                'lock_date' => null,
                'locked_at' => null,
                'closed_at' => null,
                'opened_by' => null,
                'closed_by' => null,
                'closed_to_fiscal_year_id' => null,
                'opening_entries_generated' => false,
                'opening_entries_generated_at' => null,
                'note' => sprintf(
                    'Auto generated fiscal year %s (%s - %s)',
                    $name,
                    $startDate->format('d M Y'),
                    $endDate->format('d M Y')
                ),
            ]
        );

        /*
        |--------------------------------------------------------------------------
        | Generate 12 Accounting Periods
        |--------------------------------------------------------------------------
        */
        AccountingPeriod::query()
            ->where('fiscal_year_id', $fiscalYear->id)
            ->update([
                'is_current' => false,
            ]);

        $periodDate = $startDate->copy();

        for ($periodNo = 1; $periodNo <= 12; $periodNo++) {
            $monthStart = $periodDate->copy()->startOfMonth();
            $monthEnd = $periodDate->copy()->endOfMonth();

            AccountingPeriod::updateOrCreate(
                [
                    'fiscal_year_id' => $fiscalYear->id,
                    'period_no' => $periodNo,
                ],
                [
                    'name' => $monthStart->format('M Y'),

                    'period_type' => PeriodTypeEnum::MONTHLY->value,

                    'start_date' => $monthStart,
                    'end_date' => $monthEnd,

                    'is_current' => $today->between(
                        $monthStart,
                        $monthEnd
                    ),

                    'status' => AccountingPeriodStatusEnum::OPEN->value,

                    'lock_date' => null,

                    'locked_at' => null,
                    'closed_at' => null,

                    'opened_by' => null,
                    'closed_by' => null,

                    'note' => sprintf(
                        'Auto generated accounting period %s (%s - %s)',
                        $monthStart->format('M Y'),
                        $monthStart->format('d M Y'),
                        $monthEnd->format('d M Y')
                    ),
                ]
            );

            $periodDate->addMonth();
        }
    }
}
