<?php

namespace App\Resource\Controller;

use App\Auth\Entity\User;
use App\Resource\Entity\NationalHoliday;
use App\Resource\Entity\TenantHolidayOverride;
use App\Resource\Repository\TenantHolidayOverrideRepository;
use App\Resource\Service\HolidayService;
use App\Resource\Service\ResourceContext;
use App\Shared\Constant\ErrorCodes;
use App\Shared\Controller\BaseController;
use App\Shared\Tenant\TenantOwnershipChecker;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[OA\Tag(name: 'Resource')]
#[IsGranted('IS_AUTHENTICATED_FULLY')]
class HolidayController extends BaseController
{
    use ResourcePermissionTrait;

    public function __construct(
        private readonly HolidayService                  $holidays,
        private readonly ResourceContext                 $context,
        private readonly TenantHolidayOverrideRepository $overrides,
        private readonly TenantOwnershipChecker          $ownership,
    ) {}

    /**
     * تعطیلات رسمی سراسری‌اند و به محیط بستگی ندارند؛ هر کاربر واردشده می‌تواند
     * ببیندشان (فقط `view` سنجیده می‌شود).
     */
    #[Route('/api/v1/national-holidays', name: 'national_holidays_list', methods: ['GET'])]
    public function nationalHolidays(#[CurrentUser] User $user, Request $request): JsonResponse
    {
        $this->denyUnlessGranted($user, 'view');

        $year = $this->holidays->assertJalaliYear($request->query->get('year'));

        [$entityType, $entityId] = $this->context->pair($user);
        $overrides = $this->holidays->overridesForYear($entityType, $entityId, $year);

        $overrideByDate = [];
        foreach ($overrides as $override) {
            $overrideByDate[$override->getDate()] = $override;
        }

        return $this->success([
            'year'      => $year,
            'holidays'  => array_map(
                static function (NationalHoliday $h) use ($overrideByDate): array {
                    $row = $h->toArray();
                    // «این محیط آن روز باز است» کنار خودِ تعطیلی می‌آید تا UI مجبور
                    // نباشد دو فهرست را خودش تطبیق دهد.
                    $row['overridden_working'] = ($overrideByDate[$h->getDate()] ?? null)?->isWorking();

                    return $row;
                },
                $this->holidays->forYear($year),
            ),
            'overrides' => array_map(
                static fn (TenantHolidayOverride $o): array => $o->toArray(),
                $overrides,
            ),
        ]);
    }

    #[Route('/api/v1/holiday-overrides', name: 'holiday_override_create', methods: ['POST'])]
    public function createOverride(#[CurrentUser] User $user, Request $request): JsonResponse
    {
        $this->denyUnlessGranted($user, 'update');

        $data = json_decode($request->getContent(), true);

        if (!is_array($data) || !is_numeric($data['date'] ?? null)) {
            return $this->error(ErrorCodes::ERR_VALIDATION_002, 'فیلد date الزامی است', 422, 'date');
        }

        if (!array_key_exists('is_working', $data)) {
            return $this->error(ErrorCodes::ERR_VALIDATION_002, 'فیلد is_working الزامی است', 422, 'is_working');
        }

        [$entityType, $entityId] = $this->context->pair($user);

        $override = $this->holidays->setOverride(
            $entityType,
            $entityId,
            (int) $data['date'],
            (bool) $data['is_working'],
            is_string($data['note'] ?? null) && trim($data['note']) !== '' ? trim($data['note']) : null,
        );

        return $this->success($override->toArray(), 201);
    }

    #[Route('/api/v1/holiday-override/{uuid}', name: 'holiday_override_delete', methods: ['DELETE'])]
    public function deleteOverride(#[CurrentUser] User $user, string $uuid): JsonResponse
    {
        $this->denyUnlessGranted($user, 'update');

        $override = $this->overrides->findByUuid($uuid);
        [$entityType, $entityId] = $this->context->pair($user);

        if ($override === null || !$this->ownership->belongsToPair($entityType, $entityId, $override)) {
            return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'استثنای تعطیلی یافت نشد', 404);
        }

        $this->holidays->deleteOverride($override);

        return $this->success(null);
    }
}
