<?php

namespace App\Livewire\Forms\Studio\Loyalty;

use App\Enums\VoucherType;
use App\Models\Voucher;
use App\Rules\UnsignedInteger;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;

class VoucherForm extends Form
{
    public ?Voucher $voucher = null;

    public string $name = '';

    public string $code = '';

    public string $type = '1';

    public string $discount_amount = '';

    public ?string $min_purchase = null;

    public ?string $max_discount = null;

    public ?string $quota = null;

    public ?string $limit_per_user = null;

    public string $start_date = '';

    public ?string $end_date = null;

    public array $outlet_ids = [];

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:50'],
            'code' => [
                'required',
                'string',
                'max:20',
                'alpha_num',
                Rule::unique('vouchers', 'code')->ignore($this->voucher),
            ],
            'type' => ['required', Rule::in(VoucherType::values())],
            'discount_amount' => [
                'required',
                Rule::when(
                    fn () => $this->type == VoucherType::PERCENTAGE->value,
                    ['integer', 'between:0,100'],
                    [new UnsignedInteger],
                ),
            ],
            'min_purchase' => ['nullable', new UnsignedInteger],
            'max_discount' => [
                Rule::when(
                    fn () => $this->type == VoucherType::PERCENTAGE->value,
                    ['required', new UnsignedInteger],
                    ['nullable'],
                ),
            ],
            'quota' => ['nullable', new UnsignedInteger],
            'limit_per_user' => ['nullable', new UnsignedInteger],
            'start_date' => ['required', 'date', 'after:yesterday'],
            'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
            'outlet_ids' => ['required', 'array', 'min:1'],
            'outlet_ids.*' => Rule::exists('outlets', 'id'),
        ];
    }

    public function validationAttributes(): array
    {
        return [
            'name' => 'nama',
            'code' => 'kode',
            'min_purchase' => 'min. belanja',
            'max_discount' => 'maks. diskon',
            'quota' => 'kuota',
            'limit_per_user' => 'limit per user',
            'type' => 'Tipe',
            'discount_amount' => 'Jumlah Diskon',
            'start_date' => 'tanggal mulai',
            'end_date' => 'tanggal selesai',
        ];
    }

    public function setVoucher(Voucher $voucher)
    {
        $voucher->load('outlets');

        $this->voucher = $voucher;

        $this->name = $this->voucher->name;
        $this->code = $this->voucher->code;
        $this->type = $this->voucher->type->value;
        $this->discount_amount = replaceCurrency($this->voucher->discount_amount);
        $this->min_purchase = replaceCurrency($this->voucher->min_purchase);
        $this->max_discount = replaceCurrency($this->voucher->max_discount);
        $this->quota = $this->voucher->quota;
        $this->limit_per_user = $this->voucher->limit_per_user;
        $this->start_date = $this->voucher->start_date;
        $this->end_date = $this->voucher->end_date;

        $this->outlet_ids = $this->voucher->outlets->pluck('id')->toArray();
    }

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

        $data = $this->prepareSavedData();
        $data = sanitizeIntegers($data, ['min_purchase', 'max_discount', 'quota', 'limit_per_user']);

        DB::transaction(function () use ($data) {
            $voucher = Voucher::create($data);

            $voucher->outlets()->attach($this->outlet_ids);
        });
    }

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

        $data = $this->prepareSavedData();
        DB::transaction(function () use ($data) {
            $this->voucher->update($data);

            $this->voucher->outlets()->sync($this->outlet_ids);
        });
    }

    private function prepareSavedData()
    {
        return [
            'name' => $this->name,
            'code' => $this->code,
            'type' => $this->type,
            'discount_amount' => replaceCurrency($this->discount_amount),
            'min_purchase' => replaceCurrency($this->min_purchase),
            'max_discount' => $this->type == VoucherType::PERCENTAGE->value ? replaceCurrency($this->max_discount) : null,
            'quota' => $this->quota,
            'available_count' => $this->quota,
            'limit_per_user' => $this->limit_per_user,
            'start_date' => $this->start_date,
            'end_date' => $this->end_date,
        ];
    }
}
