<?php

namespace App\Services;

use App\Models\Commons\Holiday;
use Symfony\Component\HttpKernel\Exception\HttpException;

class CalendarScheduleService extends Service
{
    /**
     * 연도별 일정 목록 조회
     */
    public function list(int $year, ?string $type = null): array
    {
        $query = Holiday::forTenant($this->tenantId())
            ->forYear($year)
            ->orderBy('start_date');

        if ($type) {
            $query->where('type', $type);
        }

        return $query->get()->map(function ($h) {
            return [
                'id' => $h->id,
                'name' => $h->name,
                'type' => $h->type,
                'start_date' => $h->start_date->format('Y-m-d'),
                'end_date' => $h->end_date->format('Y-m-d'),
                'days' => $h->start_date->diffInDays($h->end_date) + 1,
                'is_recurring' => $h->is_recurring,
                'memo' => $h->memo,
                'created_at' => $h->created_at?->toIso8601String(),
                'updated_at' => $h->updated_at?->toIso8601String(),
            ];
        })->all();
    }

    /**
     * 통계 조회
     */
    public function stats(int $year): array
    {
        $tenantId = $this->tenantId();
        $holidays = Holiday::forTenant($tenantId)->forYear($year)->get();

        $totalDays = $holidays->sum(function ($h) {
            return $h->start_date->diffInDays($h->end_date) + 1;
        });

        return [
            'total_count' => $holidays->count(),
            'total_holiday_days' => $totalDays,
            'public_holiday_count' => $holidays->where('type', 'public_holiday')->count(),
        ];
    }

    /**
     * 단건 조회
     */
    public function show(int $id): array
    {
        $h = Holiday::forTenant($this->tenantId())->findOrFail($id);

        return [
            'id' => $h->id,
            'name' => $h->name,
            'type' => $h->type,
            'start_date' => $h->start_date->format('Y-m-d'),
            'end_date' => $h->end_date->format('Y-m-d'),
            'days' => $h->start_date->diffInDays($h->end_date) + 1,
            'is_recurring' => $h->is_recurring,
            'memo' => $h->memo,
            'created_at' => $h->created_at?->toIso8601String(),
            'updated_at' => $h->updated_at?->toIso8601String(),
        ];
    }

    /**
     * 등록
     */
    public function store(array $data): array
    {
        $tenantId = $this->tenantId();

        $exists = Holiday::forTenant($tenantId)
            ->where('start_date', $data['start_date'])
            ->where('end_date', $data['end_date'])
            ->where('name', $data['name'])
            ->exists();

        if ($exists) {
            throw new HttpException(422, __('error.duplicate'));
        }

        $holiday = Holiday::create([
            'tenant_id' => $tenantId,
            'start_date' => $data['start_date'],
            'end_date' => $data['end_date'],
            'name' => $data['name'],
            'type' => $data['type'] ?? 'public_holiday',
            'is_recurring' => $data['is_recurring'] ?? false,
            'memo' => $data['memo'] ?? null,
            'created_by' => $this->apiUserId(),
        ]);

        return $this->show($holiday->id);
    }

    /**
     * 수정
     */
    public function update(int $id, array $data): array
    {
        $holiday = Holiday::forTenant($this->tenantId())->findOrFail($id);

        $holiday->update([
            'start_date' => $data['start_date'],
            'end_date' => $data['end_date'],
            'name' => $data['name'],
            'type' => $data['type'],
            'is_recurring' => $data['is_recurring'] ?? false,
            'memo' => $data['memo'] ?? null,
            'updated_by' => $this->apiUserId(),
        ]);

        return $this->show($id);
    }

    /**
     * 삭제
     */
    public function delete(int $id): void
    {
        $holiday = Holiday::forTenant($this->tenantId())->findOrFail($id);
        $holiday->delete();
    }

    /**
     * 대량 등록
     */
    public function bulkStore(array $schedules): array
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();
        $count = 0;
        $skipped = 0;

        foreach ($schedules as $item) {
            $exists = Holiday::forTenant($tenantId)
                ->where('start_date', $item['start_date'])
                ->where('end_date', $item['end_date'])
                ->where('name', $item['name'])
                ->exists();

            if ($exists) {
                $skipped++;

                continue;
            }

            Holiday::create([
                'tenant_id' => $tenantId,
                'start_date' => $item['start_date'],
                'end_date' => $item['end_date'],
                'name' => $item['name'],
                'type' => $item['type'] ?? 'public_holiday',
                'is_recurring' => $item['is_recurring'] ?? false,
                'memo' => $item['memo'] ?? null,
                'created_by' => $userId,
            ]);
            $count++;
        }

        return [
            'created' => $count,
            'skipped' => $skipped,
        ];
    }
}
