<?php

namespace App\Console\Commands;

use App\Models\Attendance;
use App\Models\AttendanceSetting;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Console\Command;

class SyncAttendanceDailyStatus extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'attendance:sync-daily-status {--date= : Target date (Y-m-d), default H-1 berdasarkan timezone setting}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sinkron status absensi: isi alpha jika tidak absen, dan beri catatan jika check-out tidak ditemukan pada hari kerja efektif.';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $setting = AttendanceSetting::query()->first();

        if (!$setting) {
            $this->error('Attendance setting belum tersedia. Jalankan seeder AttendanceSettingSeeder.');
            return self::FAILURE;
        }

        $timezone = $setting->timezone ?: config('app.timezone', 'Asia/Jakarta');
        $targetDate = $this->resolveTargetDate($timezone);

        if (!$targetDate) {
            return self::FAILURE;
        }

        $effectiveWorkdays = collect($setting->effective_workdays ?? [])
            ->map(fn($day) => (int) $day)
            ->unique()
            ->values();

        if ($effectiveWorkdays->isNotEmpty() && !$effectiveWorkdays->contains($targetDate->isoWeekday())) {
            $this->info("Skip {$targetDate->toDateString()}: bukan hari kerja efektif.");
            return self::SUCCESS;
        }

        $users = User::query()
            ->where('status', 'aktif')
            ->select('id', 'name')
            ->get();

        $createdAlpha = 0;
        $notedMissingCheckout = 0;

        foreach ($users as $user) {
            $attendance = Attendance::query()
                ->where('user_id', $user->id)
                ->whereDate('date', $targetDate->toDateString())
                ->first();

            if (!$attendance) {
                Attendance::create([
                    'user_id' => $user->id,
                    'date' => $targetDate->toDateString(),
                    'status' => 'alpha',
                    'notes' => 'Tidak melakukan absensi pada hari kerja efektif.',
                ]);
                $createdAlpha++;
                continue;
            }

            if ($setting->require_checkout && $attendance->check_in && !$attendance->check_out) {
                $attendance->update([
                    'notes' => $this->appendNote($attendance->notes, 'Absensi tidak lengkap: check-out tidak ditemukan.'),
                ]);
                $notedMissingCheckout++;
            }
        }

        $this->info("Sinkronisasi {$targetDate->toDateString()} selesai.");
        $this->line("Alpha dibuat: {$createdAlpha}");
        $this->line("Catatan check-out kosong: {$notedMissingCheckout}");

        return self::SUCCESS;
    }

    private function resolveTargetDate(string $timezone): ?Carbon
    {
        $dateOption = $this->option('date');

        if (!$dateOption) {
            return Carbon::now($timezone)->subDay()->startOfDay();
        }

        try {
            return Carbon::createFromFormat('Y-m-d', (string) $dateOption, $timezone)->startOfDay();
        } catch (\Throwable $e) {
            $this->error('Format --date tidak valid. Gunakan Y-m-d, contoh: 2026-02-19');
            return null;
        }
    }

    private function appendNote(?string $existing, string $note): string
    {
        $current = trim((string) $existing);

        if ($current === '') {
            return $note;
        }

        if (str_contains($current, $note)) {
            return $current;
        }

        return "{$current} | {$note}";
    }
}
