<?php

namespace App\Filament\Resources\LoyaltyProgramResource\Pages;

use App\Filament\Resources\LoyaltyProgramResource;
use App\Models\Loyalty\LoyaltyProgram;
use App\Models\Loyalty\LoyaltyTier;
use App\Services\AuditLog;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

/**
 * Ported from LoyaltyProgramController::update(). Tiers are deleted wholesale
 * and recreated from the submitted rows — not diffed — matching the source
 * exactly, which is why the repeater is not ->relationship()-bound.
 */
class EditLoyaltyProgram extends EditRecord
{
    protected static string $resource = LoyaltyProgramResource::class;

    protected function getHeaderActions(): array
    {
        return [];
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    protected function mutateFormDataBeforeFill(array $data): array
    {
        /** @var LoyaltyProgram $program */
        $program = $this->record;

        $data['tiers'] = $program->tiers()->get()->map(fn (LoyaltyTier $tier): array => [
            'name' => $tier->name,
            'code' => $tier->code,
            'min_lifetime_points' => (float) $tier->min_lifetime_points,
            'earn_multiplier' => (float) $tier->earn_multiplier,
            'color' => $tier->color,
        ])->values()->all();

        return $data;
    }

    protected function handleRecordUpdate(Model $record, array $data): Model
    {
        /** @var LoyaltyProgram $program */
        $program = $record;

        DB::transaction(function () use ($data, $program): void {
            $program->update([
                'name' => $data['name'],
                'base_earn_rate' => $data['base_earn_rate'],
                'redemption_rate' => $data['redemption_rate'],
                'minimum_purchase_to_earn' => $data['minimum_purchase_to_earn'] ?? 0,
                'minimum_points_to_redeem' => $data['minimum_points_to_redeem'] ?? 0,
                'points_validity_days' => $data['points_validity_days'] ?? null,
                'is_active' => $data['is_active'] ?? true,
            ]);

            $program->tiers()->delete();
            foreach ($data['tiers'] ?? [] as $tier) {
                $program->tiers()->create([
                    'name' => $tier['name'],
                    'code' => $tier['code'],
                    'min_lifetime_points' => $tier['min_lifetime_points'],
                    'earn_multiplier' => $tier['earn_multiplier'] ?? 1,
                    'color' => $tier['color'] ?? null,
                ]);
            }

            AuditLog::record('loyalty_program.updated', $program, ['name' => $program->name]);
        });

        return $program->refresh();
    }

    protected function getRedirectUrl(): string
    {
        return LoyaltyProgramResource::getUrl('index');
    }
}
