<?php

namespace App\Livewire\Forms\Studio\Catalog;

use App\Enums\Concentration;
use App\Models\Perfume;
use App\Rules\UnsignedInteger;
use App\Traits\WithMediaHandler;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;

class PerfumeForm extends Form
{
    use WithMediaHandler;

    public ?Perfume $perfume = null;

    public string $name = '';

    public string $sku = '';

    public ?string $brand_id = null;

    public string $cost_price = '';

    public string $sale_price = '';

    public ?string $base_notes = null;

    public ?string $middle_notes = null;

    public ?string $top_notes = null;

    public ?string $description = null;

    public string $concentration = '2';

    public array $category_ids = [];

    public array $image = [];

    public array $outlet_ids = [];

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:50'],
            'sku' => [
                'required',
                'string',
                'max:20',
                Rule::unique('perfumes', 'sku')->ignore($this->perfume),
            ],
            'brand_id' => ['nullable', Rule::exists('brands', 'id')],
            'cost_price' => ['required', new UnsignedInteger],
            'sale_price' => ['required', new UnsignedInteger],
            'base_notes' => ['nullable', 'string', 'max:255'],
            'middle_notes' => ['nullable', 'string', 'max:255'],
            'top_notes' => ['nullable', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'concentration' => ['required', Rule::in(Concentration::values())],
            'category_ids' => ['required', 'array', 'min:1'],
            'category_ids.*' => Rule::exists('categories', 'id'),
            'outlet_ids' => ['required', 'array', 'min:1'],
            'outlet_ids.*' => Rule::exists('outlets', 'id'),
            'image' => ['nullable', 'array', 'max:1'],
        ];
    }

    public function validationAttributes(): array
    {
        return [
            'name' => 'nama',
            'brand_id' => 'merek',
            'cost_price' => 'harga beli',
            'sale_price' => 'harga jual',
            'description' => 'deskripsi',
            'category_ids' => 'kategori',
            'outlet_ids' => 'outlet',
            'image' => 'gambar',
        ];
    }

    public function setPerfume(Perfume $perfume)
    {
        $perfume->load(['brand', 'outlets', 'categories']);

        $this->perfume = $perfume;

        $this->name = $perfume->name;
        $this->sku = $perfume->sku;
        $this->brand_id = $perfume->brand_id;
        $this->cost_price = $perfume->cost_price;
        $this->sale_price = $perfume->sale_price;
        $this->base_notes = $perfume->base_notes;
        $this->middle_notes = $perfume->middle_notes;
        $this->top_notes = $perfume->top_notes;
        $this->description = $perfume->description;
        $this->concentration = $perfume->concentration->value;
        $this->category_ids = $perfume->categories->pluck('id')->toArray();
        $this->outlet_ids = $this->perfume->outlets->pluck('id')->toArray();
        $this->image = $this->mapMediaCollection($perfume->getMedia('image'));
    }

    public function store()
    {
        $this->validate();

        $data = $this->prepareSavedData();

        DB::transaction(function () use ($data) {
            $perfume = Perfume::create($data);

            $perfume->categories()->attach($this->category_ids);

            $perfume->outlets()->attach($this->outlet_ids);

            $this->uploadMedia($this->image, $perfume, 'image');
        });
    }

    public function update()
    {
        $this->validate();

        $data = $this->prepareSavedData();

        DB::transaction(function () use ($data) {
            $this->perfume->update($data);

            $this->perfume->categories()->sync($this->category_ids);

            $this->perfume->outlets()->sync($this->outlet_ids);

            $this->syncMedia($data['image'], $this->perfume, 'image');
            $this->uploadMedia($data['image'], $this->perfume, 'image');
        });
    }

    private function prepareSavedData()
    {
        return [
            'name' => $this->name,
            'sku' => $this->sku,
            'cost_price' => replaceCurrency($this->cost_price),
            'sale_price' => replaceCurrency($this->sale_price),
            'base_notes' => $this->base_notes,
            'middle_notes' => $this->middle_notes,
            'top_notes' => $this->top_notes,
            'description' => $this->description,
            'concentration' => $this->concentration,
            'brand_id' => $this->brand_id,
            'category_ids' => $this->category_ids,
            'outlet_ids' => $this->outlet_ids,
            'image' => $this->image,
        ];
    }
}
