<?php

namespace App\Services\Events;

use App\Models\Event;
use App\Services\Invoices\InvoiceGenerationService;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;

class EventManagementService
{
    public function __construct(
        private EventChargeService $charges,
        private InvoiceGenerationService $invoiceGeneration
    ) {
    }

    public function create(array $payload, ?UploadedFile $flyer, int $actorId): array
    {
        return DB::transaction(function () use ($payload, $flyer, $actorId) {
            $flyerPath = $this->storeFlyer($flyer);

            $event = Event::query()->create([
                'event_name' => $payload['event_name'],
                'event_category' => $payload['event_category'],
                'description' => $payload['description'] ?? null,
                'amount' => $payload['amount'],
                'flyer' => $flyerPath,
                'expiration_date' => $payload['expiration_date'],
                'semester' => $payload['semester'],
                'school_year' => $payload['school_year'],
                'created_by' => $actorId ?: null,
                'created_at' => utc_now(),
                'updated_at' => utc_now(),
            ]);

            $seed = $this->charges->seedChargesForEvent(
                $event,
                (string) $payload['school_year'],
                (string) $payload['semester'],
                (float) $payload['amount'],
                $actorId
            );

            return [
                'ok' => true,
                'event' => $event,
                'charges_created' => $seed['created'] ?? 0,
            ];
        });
    }

    public function update(int $eventId, array $payload, ?UploadedFile $flyer): array
    {
        $event = Event::query()->find($eventId);
        if (!$event) {
            return ['ok' => false, 'message' => 'Event not found.'];
        }

        $flyerPath = $event->flyer;
        if ($flyer) {
            $flyerPath = $this->storeFlyer($flyer) ?: $flyerPath;
        }

        $event->update([
            'event_name' => $payload['event_name'] ?? $event->event_name,
            'event_category' => $payload['event_category'] ?? $event->event_category,
            'description' => $payload['description'] ?? $event->description,
            'amount' => $payload['amount'] ?? $event->amount,
            'flyer' => $flyerPath,
            'expiration_date' => $payload['expiration_date'] ?? $event->expiration_date,
            'semester' => $payload['semester'] ?? $event->semester,
            'school_year' => $payload['school_year'] ?? $event->school_year,
            'updated_at' => utc_now(),
        ]);

        return ['ok' => true, 'event' => $event];
    }

    public function delete(int $eventId, int $actorId): array
    {
        $event = Event::query()->find($eventId);
        if (!$event) {
            return ['ok' => false, 'message' => 'Event not found.'];
        }

        return DB::transaction(function () use ($event) {
            $charges = $this->charges->deleteChargesForEvent((int) $event->id);
            $event->delete();

            foreach ($charges['parent_ids'] ?? [] as $parentId) {
                $this->invoiceGeneration->generateInvoice((int) $parentId, (string) $event->school_year);
            }

            return ['ok' => true];
        });
    }

    private function storeFlyer(?UploadedFile $file): ?string
    {
        if (!$file || !$file->isValid()) {
            return null;
        }

        $dir = public_path('uploads/event_flyers');
        if (!File::exists($dir)) {
            File::makeDirectory($dir, 0755, true);
        }

        $name = $file->hashName();
        $file->move($dir, $name);

        return 'event_flyers/' . $name;
    }
}
