<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ReturnModel;
use App\Models\Sale;
use App\Services\ActivityLogger;
use App\Services\NotificationService;
use App\Services\ReturnService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class ReturnController extends Controller
{
    public function __construct(
        protected ReturnService $returnService
    ) {}

    public function index(Request $request)
    {
        $query = ReturnModel::with(['sale.customer', 'user', 'approvedBy', 'items.product'])
            ->orderBy('created_at', 'desc');

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // Filter by date range
        if ($request->filled('start_date')) {
            $query->whereDate('created_at', '>=', $request->start_date);
        }

        if ($request->filled('end_date')) {
            $query->whereDate('created_at', '<=', $request->end_date);
        }

        // Search by return number or customer
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('return_number', 'like', "%{$search}%")
                  ->orWhereHas('sale.customer', function($q) use ($search) {
                      $q->where('name', 'like', "%{$search}%");
                  });
            });
        }

        $returns = $query->paginate($request->per_page ?? 15);

        return response()->json($returns);
    }

    public function store(Request $request)
    {
        $this->authorize('process-returns');

        $validated = $request->validate([
            'sale_id' => ['required', Rule::exists('sales', 'id')->where('organization_id', app('current_organization_id'))],
            'reason' => 'required|string|max:500',
            'notes' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.sale_item_id' => ['required', Rule::exists('sale_items', 'id')],
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.reason' => 'nullable|string',
        ]);

        try {
            $return = $this->returnService->create($validated, $request->user());

            ActivityLogger::log(
                'return_requested',
                "Return {$return->return_number} requested for sale #{$validated['sale_id']}",
                $return
            );

            $orgId    = app('current_organization_id');
            $branchId = app()->bound('current_branch_id') ? app('current_branch_id') : null;
            $actor    = $request->user();
            $customer = $return->sale->customer?->name ?? 'Walk-in';
            NotificationService::notifyRoles(
                $orgId, $branchId,
                ['super-admin', 'admin'],
                'return_requested',
                'Return Requested — ' . $return->return_number,
                "{$actor->name} requested a return for {$customer}. Amount: " . number_format((float) $return->total_amount, 2),
                ['return_id' => $return->id, 'return_number' => $return->return_number],
                $actor->id
            );

            return response()->json(
                $return->load(['sale.customer', 'user', 'items.product']),
                201
            );
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Failed to create return: ' . $e->getMessage()
            ], 422);
        }
    }

    public function show(ReturnModel $return)
    {
        return response()->json(
            $return->load(['sale.customer', 'sale.items.product', 'user', 'approvedBy', 'items.product', 'items.saleItem'])
        );
    }

    public function approve(Request $request, ReturnModel $return)
    {
        $this->authorize('approve-returns');

        if ($return->status !== 'pending') {
            return response()->json([
                'message' => 'Only pending returns can be approved'
            ], 422);
        }

        $validated = $request->validate([
            'notes' => 'nullable|string',
        ]);

        try {
            $return = $this->returnService->approve($return, $request->user(), $validated['notes'] ?? null);

            ActivityLogger::log(
                'return_approved',
                "Return {$return->return_number} approved",
                $return
            );

            // Notify the requester that their return was approved
            $orgId    = app('current_organization_id');
            $branchId = app()->bound('current_branch_id') ? app('current_branch_id') : null;
            if ($return->user_id && $return->user_id !== $request->user()->id) {
                NotificationService::notifyUser(
                    $return->user_id,
                    $orgId, $branchId,
                    'return_approved',
                    'Return Approved — ' . $return->return_number,
                    "Your return request {$return->return_number} has been approved.",
                    ['return_id' => $return->id, 'return_number' => $return->return_number],
                    $request->user()->id
                );
            }

            return response()->json(
                $return->load(['sale.customer', 'user', 'approvedBy', 'items.product'])
            );
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Failed to approve return: ' . $e->getMessage()
            ], 422);
        }
    }

    public function reject(Request $request, ReturnModel $return)
    {
        $this->authorize('approve-returns');

        if ($return->status !== 'pending') {
            return response()->json([
                'message' => 'Only pending returns can be rejected'
            ], 422);
        }

        $validated = $request->validate([
            'notes' => 'required|string',
        ]);

        try {
            $return = $this->returnService->reject($return, $request->user(), $validated['notes']);

            ActivityLogger::log(
                'return_rejected',
                "Return {$return->return_number} rejected — {$validated['notes']}",
                $return
            );

            // Notify the requester that their return was rejected
            $orgId    = app('current_organization_id');
            $branchId = app()->bound('current_branch_id') ? app('current_branch_id') : null;
            if ($return->user_id && $return->user_id !== $request->user()->id) {
                NotificationService::notifyUser(
                    $return->user_id,
                    $orgId, $branchId,
                    'return_rejected',
                    'Return Rejected — ' . $return->return_number,
                    "Your return request {$return->return_number} was rejected. Reason: {$validated['notes']}",
                    ['return_id' => $return->id, 'return_number' => $return->return_number],
                    $request->user()->id
                );
            }

            return response()->json(
                $return->load(['sale.customer', 'user', 'approvedBy', 'items.product'])
            );
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Failed to reject return: ' . $e->getMessage()
            ], 422);
        }
    }

    public function getSaleDetails(Sale $sale)
    {
        return response()->json(
            $sale->load(['items.product', 'customer', 'user'])
        );
    }
}
