<?php

namespace App\Http\Controllers;

use App\Models\Dispute;
use App\Models\DisputeMessage;
use App\Models\BookingItem;
use App\Models\Booking;
use Illuminate\Http\Request;

class DisputeController extends Controller
{
    // ============================================================
    // List disputes
    // ============================================================
    public function index()
    {
        $user = auth()->user();

        if ($user->isAdmin()) {
            $disputes = Dispute::with([
                'booking', 'bookingItem.placement',
                'raisedBy', 'mediaOwner', 'assignedTo'
            ])->latest()->paginate(15);
        } elseif ($user->isMediaOwner()) {
            $owner    = $user->mediaOwner;
            $disputes = Dispute::where('media_owner_id', $owner?->id)
                ->with(['booking', 'bookingItem.placement', 'raisedBy'])
                ->latest()->paginate(15);
        } else {
            $disputes = Dispute::where('raised_by', $user->id)
                ->with(['booking', 'bookingItem.placement', 'mediaOwner'])
                ->latest()->paginate(15);
        }

        return view('disputes.index', compact('disputes'));
    }

    // ============================================================
    // Create dispute form
    // ============================================================
    public function create(Request $request)
    {
        $bookingItem = null;

        if ($request->filled('booking_item')) {
            $bookingItem = BookingItem::with(['booking', 'placement'])
                ->findOrFail($request->booking_item);
            abort_if($bookingItem->booking->user_id !== auth()->id(), 403);
        }

        $bookings = Booking::forUser(auth()->id())
            ->with('items.placement')
            ->latest()
            ->get();

        return view('disputes.create', compact('bookingItem', 'bookings'));
    }

    // ============================================================
    // Store dispute
    // ============================================================
    public function store(Request $request)
    {
        $request->validate([
            'booking_item_id' => 'required|exists:booking_items,id',
            'reason'          => 'required|string',
            'description'     => 'required|string|min:20|max:2000',
        ]);

        $bookingItem = BookingItem::with([
            'booking', 'placement', 'mediaOwner'
        ])->findOrFail($request->booking_item_id);

        abort_if($bookingItem->booking->user_id !== auth()->id(), 403);

        $dispute = Dispute::create([
            'booking_id'      => $bookingItem->booking_id,
            'booking_item_id' => $bookingItem->id,
            'raised_by'       => auth()->id(),
            'against_user_id' => $bookingItem->mediaOwner->user_id,
            'media_owner_id'  => $bookingItem->media_owner_id,
            'reason'          => $request->reason,
            'description'     => $request->description,
            'status'          => 'open',
            'payout_held'     => true,
            'payout_held_at'  => now(),
        ]);

        // Add opening message
        DisputeMessage::create([
            'dispute_id'  => $dispute->id,
            'sent_by'     => auth()->id(),
            'message'     => $request->description,
            'sender_role' => 'advertiser',
            'is_internal' => false,
        ]);

        // Update booking item status
        $bookingItem->update(['status' => 'disputed']);

        return redirect()
            ->route('disputes.show', $dispute)
            ->with('success', 'Dispute opened. Payout is on hold until resolved.');
    }

    // ============================================================
    // Show dispute
    // ============================================================
    public function show(Dispute $dispute)
    {
        $user = auth()->user();

        // Access control
        $canView = $user->isAdmin()
            || $dispute->raised_by === $user->id
            || $dispute->mediaOwner?->user_id === $user->id;

        abort_if(!$canView, 403);

        $dispute->load([
            'booking',
            'bookingItem.placement',
            'raisedBy',
            'mediaOwner',
            'assignedTo',
            'resolvedBy',
            'publicMessages.sentBy',
        ]);

        return view('disputes.show', compact('dispute'));
    }

    // ============================================================
    // Add message
    // ============================================================
    public function message(Request $request, Dispute $dispute)
    {
        $user = auth()->user();

        $canMessage = $user->isAdmin()
            || $dispute->raised_by === $user->id
            || $dispute->mediaOwner?->user_id === $user->id;

        abort_if(!$canMessage, 403);

        $request->validate([
            'message' => 'required|string|min:2|max:2000',
        ]);

        $role = 'advertiser';
        if ($user->isAdmin()) $role = 'admin';
        elseif ($user->isMediaOwner()) $role = 'media_owner';

        DisputeMessage::create([
            'dispute_id'  => $dispute->id,
            'sent_by'     => $user->id,
            'message'     => $request->message,
            'sender_role' => $role,
            'is_internal' => false,
        ]);

        return back()->with('success', 'Message sent.');
    }
}