<?php

namespace App\Services\Admin\Master\RawMaterial;

use App\Enums\Role;
use App\Models\RawMaterial;
use App\Models\RawMaterialPrice;
use App\Services\Concerns\RegistersMedia;
use App\Services\NotificationService;
use App\Services\S3PresignedService;
use Illuminate\Support\Facades\DB;

class RawMaterialVariantService
{
    use RegistersMedia;

    public function __construct(
        private S3PresignedService $s3Service,
    ) {}

    public function getForCutting(): array
    {
        return RawMaterial::query()
            ->select(['id', 'name', 'unit', 'is_active'])
            ->with([
                'rawMaterialPrices:id,raw_material_id,variant,price,stock',
            ])
            ->active()
            ->orderBy('name')
            ->get()
            ->each(function (RawMaterial $rawMaterial) {
                $rawMaterial->rawMaterialPrices->each(function (RawMaterialPrice $price) {
                    $media = $price->getFirstMedia('images');
                    $price->photo_url = $media
                        ? $this->s3Service->getTemporaryUrl($media->getPath())
                        : null;
                });
            })
            ->toArray();
    }

    public function getForEdit(RawMaterialPrice $variant): array
    {
        $variant->load('media');

        $media = $variant->getMedia('images');
        $photoKeys = $media->map(fn ($m) => $m->getCustomProperty('s3_key') ?? $m->file_name)->toArray();
        $photoUrls = $media->map(fn ($m) => $this->s3Service->getTemporaryUrl($m->getPath()))->toArray();

        return [
            'id' => $variant->id,
            'raw_material_id' => $variant->raw_material_id,
            'variant' => $variant->variant,
            'price' => $variant->price,
            'stock' => $variant->stock,
            'photo_key' => $photoKeys[0] ?? null,
            'photo_url' => $photoUrls[0] ?? null,
        ];
    }

    public function update(RawMaterialPrice $variant, array $data): RawMaterialPrice
    {
        DB::transaction(function () use ($variant, $data) {
            $variant->update([
                'variant' => $data['variant'],
                'price' => $data['price'],
                'stock' => $data['stock'],
            ]);

            if (array_key_exists('photo_key', $data)) {
                $existingKey = $variant->getMedia('images')->first()?->getCustomProperty('s3_key');
                $newKey = $data['photo_key'];

                if ($existingKey !== $newKey) {
                    $variant->clearMediaCollection('images');
                    if ($newKey) {
                        $this->registerPhoto($variant, $newKey);
                    }
                }
            }
        });

        NotificationService::notify(
            roles: [Role::OWNER, Role::DEVELOPER, Role::DIREKTUR, Role::ADMIN_TOKO],
            title: 'Varian Diperbarui',
            body: "Varian \"{$variant->variant}\" berhasil diperbarui".' oleh '.auth()->user()->full_name.'.',
            url: route('admin.master.raw-materials.index'),
        );

        return $variant->fresh();
    }

    public function destroy(RawMaterial $rawMaterial, RawMaterialPrice $variant): bool
    {
        $result = DB::transaction(function () use ($variant) {
            return $variant->delete();
        });

        NotificationService::notify(
            roles: [Role::OWNER, Role::DEVELOPER, Role::DIREKTUR, Role::ADMIN_TOKO],
            title: 'Varian Dihapus',
            body: "Varian \"{$variant->variant}\" dari bahan baku \"{$rawMaterial->name}\" berhasil dihapus".' oleh '.auth()->user()->full_name.'.',
            url: route('admin.master.raw-materials.index'),
        );

        return $result;
    }
}
