<?php

namespace App\Http\Controllers\Agency\Operation;

use App\Http\Controllers\Controller;
use App\Models\ResourceSchedule;
use App\Services\Operation\OperationService;
use App\Services\Operation\ResourceAssignmentService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class OperationResourceController extends Controller
{
    public function __construct(
        private OperationService $ops,
        private ResourceAssignmentService $assignments
    ) {
    }

    private function agencyId(): int
    {
        return Auth::user()->currentAgencyId();
    }

    private function resolveOrFail(string $type, int $id): Model
    {
        $date = $this->ops->resolveByKey($type, $id);
        abort_if(!$date, 404);
        $tour = $this->ops->tourOf($date);
        abort_if(!$tour || (int) $tour->agency_id !== $this->agencyId(), 403, 'Bu işlem için yetkiniz yok.');
        return $date;
    }

    /** Kaynak ata. */
    public function assign(Request $request, string $type, int $id)
    {
        $date = $this->resolveOrFail($type, $id);

        $data = $request->validate([
            'resource_id' => 'required|integer|exists:resources,id',
            'cost_items_present' => 'nullable|boolean',
            'cost_items' => 'nullable|array|max:30',
            'cost_items.*.title' => 'nullable|required_with:cost_items.*.unit_amount|string|max:150',
            'cost_items.*.unit_amount' => 'nullable|numeric|min:0|max:99999999.99',
            'cost_items.*.quantity' => 'nullable|numeric|min:0|max:999999.99',
            'cost_items.*.unit' => 'nullable|string|max:20',
            'notes' => 'nullable|string|max:500',
        ], [
            'cost_items.*.title.required_with' => 'Maliyet başlığı boş bırakılamaz.',
            'cost_items.*.unit_amount.numeric' => 'Birim fiyat sayı olmalıdır.',
            'cost_items.*.unit_amount.min' => 'Birim fiyat negatif olamaz.',
            'cost_items.*.quantity.numeric' => 'Çarpan sayı olmalıdır.',
        ]);

        // Form maliyet başlığı taşıyorsa (tümü silinmiş olsa bile) o liste geçerlidir;
        // hiç göndermediyse null geçilir ve kaynağın varsayılanları kopyalanır.
        $data['cost_items'] = $request->boolean('cost_items_present')
            ? array_values($request->input('cost_items', []))
            : null;

        $this->assignments->assign($date, (int) $data['resource_id'], $data);

        if ($request->expectsJson()) {
            return response()->json(['success' => true, 'message' => 'Kaynak kalkışa atandı.']);
        }

        return back()->with('success', 'Kaynak kalkışa atandı.');
    }

    /** Atamayı kaldır. */
    public function remove(string $type, int $id, int $schedule)
    {
        $date = $this->resolveOrFail($type, $id);

        $sched = ResourceSchedule::where('agency_id', $this->agencyId())
            ->where('id', $schedule)
            ->forReference(get_class($date), $date->getKey())
            ->firstOrFail();

        $this->assignments->remove($sched);

        if (request()->expectsJson()) {
            return response()->json(['success' => true, 'message' => 'Kaynak ataması kaldırıldı.']);
        }

        return back()->with('success', 'Kaynak ataması kaldırıldı.');
    }

    /** Ön atamayı kesin atamaya çevirir (veya geri alır). */
    public function toggleConfirm(string $type, int $id, int $schedule)
    {
        $date = $this->resolveOrFail($type, $id);

        $sched = ResourceSchedule::where('agency_id', $this->agencyId())
            ->where('id', $schedule)
            ->where('schedule_type', 'tour_assignment')
            ->forReference(get_class($date), $date->getKey())
            ->firstOrFail();

        $confirmed = $sched->assignment_status === 'confirmed';
        $sched->update(['assignment_status' => $confirmed ? 'pre_assigned' : 'confirmed']);

        $msg = $confirmed ? 'Atama ön atamaya geri alındı.' : 'Atama kesin olarak onaylandı.';

        if (request()->expectsJson()) {
            return response()->json(['success' => true, 'message' => $msg]);
        }

        return back()->with('success', $msg);
    }

    /** Bu kalkış için atanabilir kaynaklar (müsaitlik + maliyet) — JSON. */
    public function available(Request $request, string $type, int $id)
    {
        $date = $this->resolveOrFail($type, $id);
        $role = $request->get('role');

        $list = $this->assignments->assignableResources($this->agencyId(), $date, $role)
            ->map(fn ($x) => [
                'id' => $x['resource']->id,
                'name' => $x['resource']->name,
                'type' => $x['resource']->type,
                'plate' => $x['resource']->vehicle_plate,
                'available' => $x['available'],
                'already_assigned' => $x['already_assigned'],
                'cost_items' => $x['cost_items'],
                'cost_total' => $x['cost_total'],
                'conflict_titles' => $x['conflict_titles'],
            ]);

        return response()->json(['resources' => $list]);
    }
}
