<?php

namespace App\Components\Institution;

use App\Models\Institution\Institution;
use App\Services\HistoryService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\DB;
use Livewire\Component;

class Merge extends Component {
    use AuthorizesRequests;
    public Institution $institution;
    public array $sourceInstitutionIds = [];

    public function merge(HistoryService $history) {
        $this->authorize('institutions.merge');
        $this->validate([
            'sourceInstitutionIds'   => 'required|array|min:1',
            'sourceInstitutionIds.*' => 'exists:institutions,id|different:institution.id',
        ]);

        DB::transaction(function () use ($history) {
            foreach ($this->sourceInstitutionIds as $sourceId) {
                $source = Institution::find($sourceId);

                $source->careSettings()->update(['institution_id' => $this->institution->id]);
                $source->dsars()->update(['institution_id' => $this->institution->id]);
                $source->contacts()->update(['institution_id' => $this->institution->id]);
                $source->notes()->update(['owner_id' => $this->institution->id]);

                // Remove pivot rows that would duplicate an existing claim link on the current institution.
                // Wrap in a derived table to avoid MySQL's restriction on referencing the target table in a subquery.
                $targetId = $this->institution->id;
                $existingClaimIds = DB::table('claim_institution')
                    ->where('institution_id', $targetId)
                    ->pluck('claim_id');

                if ($existingClaimIds->isNotEmpty()) {
                    DB::table('claim_institution')
                        ->where('institution_id', $source->id)
                        ->whereIn('claim_id', $existingClaimIds)
                        ->delete();
                }

                DB::table('claim_institution')
                    ->where('institution_id', $source->id)
                    ->update(['institution_id' => $this->institution->id]);

                $history->add($this->institution, "Merged {$source->display_name} into this institution");
                $history->add($source, "Merged into {$this->institution->display_name}");

                $source->delete();
            }
        });

        $this->sourceInstitutionIds = [];

        return redirect()->route('institutions.show', $this->institution);
    }

    public function render() {
        return view('components.institution.merge', [
            'institutions' => Institution::where('id', '!=', $this->institution->id)
                ->get()
                ->mapWithKeys(fn ($i) => [
                    $i->id => "{$i->displayId} - {$i->display_name}"
                ])
                ->toArray()
        ]);
    }
}
