<?php

namespace Kylin\LawCase\Services;

use Kylin\LawCase\Models\CaseModel;
use Kylin\LawCase\Models\Schedule;
use Kylin\LawCase\Enums\CaseStatus;
use Kylin\LawCase\Events\ScheduleReminder;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class DeadlineWarningService
{
    /**
     * 时限预警级别：7天/3天/1天三级提醒
     */
    private const WARNING_LEVELS = [7, 3, 1];

    /**
     * 扫描即将到期的日程，触发预警
     */
    public function scanUpcomingDeadlines(): array
    {
        $triggered = [];

        foreach (self::WARNING_LEVELS as $daysBefore) {
            $targetDate = Carbon::now()->addDays($daysBefore)->toDateString();

            $schedules = Schedule::whereDate('start_time', $targetDate)
                ->with(['case', 'user'])
                ->get();

            foreach ($schedules as $schedule) {
                Event::dispatch(new ScheduleReminder($schedule, $daysBefore));
                $triggered[] = [
                    'schedule_id' => $schedule->id,
                    'title' => $schedule->title,
                    'days_before' => $daysBefore,
                    'target_date' => $targetDate,
                ];

                $this->audit('deadline_warning_triggered', [
                    'schedule_id' => $schedule->id,
                    'case_id' => $schedule->case_id,
                    'title' => $schedule->title,
                    'days_before' => $daysBefore,
                    'target_date' => $targetDate,
                ]);
            }
        }

        return $triggered;
    }

    /**
     * 获取即将到期的案件期限列表
     */
    public function getUpcomingDeadlines(int $userId, int $days = 30): array
    {
        $endDate = Carbon::now()->addDays($days);

        return Schedule::where('user_id', $userId)
            ->whereBetween('start_time', [now(), $endDate])
            ->with('case')
            ->orderBy('start_time')
            ->get()
            ->map(fn($s) => [
                'id' => $s->id,
                'title' => $s->title,
                'type' => $s->schedule_type->value,
                'start_time' => $s->start_time->toIso8601String(),
                'days_remaining' => (int) now()->diffInDays($s->start_time, false),
                'case_name' => $s->case?->case_name,
                'urgency' => $this->calculateUrgency($s->start_time),
            ])
            ->toArray();
    }

    private function calculateUrgency(Carbon $deadline): string
    {
        $days = (int) now()->diffInDays($deadline, false);

        return match (true) {
            $days <= 1 => 'urgent',
            $days <= 3 => 'high',
            $days <= 7 => 'medium',
            default => 'low',
        };
    }

    /**
     * 记录时限预警审计日志
     *
     * 依据《律师法》和律师执业管理规范，
     * 案件时限预警触发需记录审计日志，防止错过法定期限。
     */
    private function audit(string $event, array $extra = []): void
    {
        if (! class_exists(\Kylin\AuditLog\Models\AuditLog::class)) {
            return;
        }

        try {
            \Kylin\AuditLog\Models\AuditLog::create([
                'event' => $event,
                'model_type' => 'schedule',
                'model_id' => $extra['schedule_id'] ?? 0,
                'new_values' => $extra,
                'old_values' => null,
                'user_id' => auth()->id(),
                'ip' => request()?->ip(),
                'url' => request()?->fullUrl(),
                'tag' => 'law-case-deadline',
            ]);
        } catch (\Throwable $e) {
            Log::warning('时限预警审计日志写入失败', [
                'error' => $e->getMessage(),
                'event' => $event,
            ]);
        }
    }
}
