<?php

namespace Modules\PurchaseRequisition\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\PurchaseRequisition\Entities\PrRequest;
use Modules\PurchaseRequisition\Entities\PrSupplierResponse;
use Modules\PurchaseRequisition\Entities\PrSupplierProduct;
use Modules\PurchaseRequisition\Entities\Services\PurchaseGenerationService;
use Yajra\DataTables\Facades\DataTables;
use App\Contact;
use App\BusinessLocation;
use DB;
use Illuminate\Support\Str;

class PrIndexController extends Controller
{
    protected $purchaseGenerationService;

    public function __construct(PurchaseGenerationService $purchaseGenerationService)
    {
        $this->purchaseGenerationService = $purchaseGenerationService;
    }

    /**
     * Display index page.
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        if (!auth()->user()->can('purchase_requisition.view_all') && !auth()->user()->can('purchase_requisition.view_own')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');

        // Get suppliers for filter
        $suppliers = Contact::suppliersDropdown($businessId, false);

        // Get business locations
        $locations = BusinessLocation::forDropdown($businessId);

        // Get statuses
        $statuses = [
            'generating' => __('purchaseRequisition::lang.generating'),
            'draft' => __('purchaseRequisition::lang.draft'),
            'pending_supplier' => __('purchaseRequisition::lang.pending_supplier'),
            'pending_approval' => __('purchaseRequisition::lang.pending_approval'),
            'approved' => __('purchaseRequisition::lang.approved'),
            'completed' => __('purchaseRequisition::lang.completed'),
        ];

        return view('purchaseRequisition::index.index', compact('suppliers', 'statuses', 'locations'));
    }

    /**
     * Get requisitions for DataTable.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getRequests(Request $request)
    {
        if (!auth()->user()->can('purchase_requisition.view_all') && !auth()->user()->can('purchase_requisition.view_own')) {
            abort(403, 'Unauthorized action.');
        }

        if ($request->ajax()) {
            $businessId = request()->session()->get('user.business_id');

            $query = PrRequest::with(['location', 'createdBy', 'supplierResponses.supplier'])
                ->where('business_id', $businessId);

            // Filter by view permission
            if (!auth()->user()->can('purchase_requisition.view_all')) {
                $query->where('created_by', auth()->user()->id);
            }

            // Apply filters
            if ($request->supplier_id) {
                $query->whereHas('supplierResponses', function ($q) use ($request) {
                    $q->where('supplier_id', $request->supplier_id);
                });
            }

            if ($request->status) {
                $query->where('status', $request->status);
            }

            if ($request->start_date && $request->end_date) {
                $query->whereBetween('transaction_date', [$request->start_date, $request->end_date]);
            }

            $query->select('pr_requests.*');

            return DataTables::of($query)
                ->addColumn('action', function ($row) {
                    $html = '<div class="btn-group">
                        <button type="button" class="btn btn-info dropdown-toggle btn-xs" data-toggle="dropdown">
                            ' . __('messages.actions') . ' <span class="caret"></span>
                        </button>
                        <ul class="dropdown-menu dropdown-menu-right" role="menu">';

                    $html .= '<li><a href="#" class="view-pr" data-id="' . $row->id . '"><i class="fa fa-eye"></i> ' . __('messages.view') . '</a></li>';

                    // Edit - for generating or draft status (draft = submitted but no share link yet)
                    if ((auth()->user()->can('purchase_requisition.edit') || auth()->user()->can('purchase_requisition.create')) && in_array($row->status, ['generating', 'draft'])) {
                        $html .= '<li><a href="' . url('/pr-module/generate/' . $row->id . '/edit') . '"><i class="fa fa-edit"></i> ' . __('messages.edit') . '</a></li>';
                    }

                    $html .= '<li><a href="' . action([\Modules\PurchaseRequisition\Http\Controllers\PrIndexController::class, 'print'], ['id' => $row->id]) . '" target="_blank"><i class="fa fa-print"></i> ' . __('messages.print') . '</a></li>';

                    if (auth()->user()->can('purchase_requisition.share_with_suppliers') && in_array($row->status, ['draft', 'pending_supplier', 'pending_approval'])) {
                        $html .= '<li><a href="#" class="share-with-suppliers" data-id="' . $row->id . '"><i class="fa fa-share"></i> ' . __('purchaseRequisition::lang.share_link') . '</a></li>';
                    }

                    if (auth()->user()->can('purchase_requisition.make_purchase') && $row->status == 'approved') {
                        $html .= '<li><a href="#" class="make-purchase" data-id="' . $row->id . '"><i class="fa fa-shopping-cart"></i> ' . __('purchaseRequisition::lang.make_purchase') . '</a></li>';
                    }

                    if ($row->status == 'pending_approval') {
                        $submittedResponses = $row->supplierResponses->whereIn('status', ['submitted', 'approved']);
                        $submittedCount = $submittedResponses->count();

                        if ($submittedCount === 1) {
                            // Single supplier — go directly to that supplier's approval
                            $singleResponse = $submittedResponses->first();
                            $approveUrl = action([\Modules\PurchaseRequisition\Http\Controllers\PrApprovalController::class, 'index'], ['id' => $row->id]) . '?response_id=' . $singleResponse->id;
                            $html .= '<li><a href="' . $approveUrl . '"><i class="fa fa-check"></i> ' . __('purchaseRequisition::lang.approve') . '</a></li>';
                        } elseif ($submittedCount > 1) {
                            // Multiple suppliers — go to compare page
                            $compareUrl = route('pr.compare', $row->id);
                            $html .= '<li><a href="' . $compareUrl . '"><i class="fa fa-exchange"></i> ' . __('purchaseRequisition::lang.compare_and_approve') . '</a></li>';
                        }
                    }

                    // Return to Supplier - for pending_approval status
                    if ((auth()->user()->can('purchase_requisition.approve') || auth()->user()->can('purchase_requisition.share_with_suppliers')) && in_array($row->status, ['pending_approval'])) {
                        $html .= '<li class="divider"></li>';
                        $html .= '<li><a href="#" class="return-to-supplier" data-id="' . $row->id . '"><i class="fa fa-undo"></i> ' . __('purchaseRequisition::lang.return_to_supplier') . '</a></li>';
                    }

                    $html .= '</ul></div>';

                    return $html;
                })
                ->editColumn('transaction_date', function ($row) {
                    return \Carbon\Carbon::parse($row->transaction_date)->format('Y-m-d');
                })
                ->editColumn('status', function ($row) {
                    $statusLabels = [
                        'generating' => 'default',
                        'draft' => 'default',
                        'pending_supplier' => 'warning',
                        'pending_approval' => 'info',
                        'approved' => 'success',
                        'completed' => 'primary',
                    ];

                    $label = $statusLabels[$row->status] ?? 'default';
                    return '<span class="label label-' . $label . '">' . ucfirst(str_replace('_', ' ', $row->status)) . '</span>';
                })
                ->addColumn('supplier_responses', function ($row) {
                    $html = '';
                    foreach ($row->supplierResponses as $response) {
                        $statusLabel = [
                            'pending' => 'default',
                            'submitted' => 'info',
                            'approved' => 'success',
                            'rejected' => 'danger',
                        ][$response->status] ?? 'default';

                        $supplier = $response->supplier;
                        $supplierName = ($supplier ? ($supplier->name ?: $supplier->supplier_business_name) : null) ?: 'Unknown Supplier';
                        $refNo = $response->ref_no ? ' (' . $response->ref_no . ')' : '';
                        $shareUrl = url('/supplier-response/' . $response->share_token);
                        $approveUrl = action([\Modules\PurchaseRequisition\Http\Controllers\PrApprovalController::class, 'index'], ['id' => $row->id]) . '?response_id=' . $response->id;

                        $html .= '<div class="supplier-row" style="margin-bottom: 8px;">';
                        $html .= '<span class="label label-' . $statusLabel . '">' . ucfirst($response->status) . '</span>';
                        $html .= ' <strong>' . $supplierName . '</strong>' . $refNo;

                        if ($response->status == 'pending') {
                            $html .= ' <a href="' . $shareUrl . '" target="_blank"><i class="fa fa-link"></i> ' . __('purchaseRequisition::lang.share_link') . '</a>';
                        } elseif (in_array($response->status, ['submitted', 'approved'])) {
                            $html .= ' <a href="' . $approveUrl . '"><i class="fa fa-eye"></i> ' . __('messages.view') . '</a>';
                        }

                        $html .= '</div>';
                    }
                    return $html ?: '-';
                })
                ->rawColumns(['action', 'status', 'supplier_responses'])
                ->make(true);
        }
    }

    /**
     * Show PR details modal.
     *
     * @param int $id
     * @return \Illuminate\View\View
     */
    public function show($id)
    {
        if (!auth()->user()->can('purchase_requisition.view_all') && !auth()->user()->can('purchase_requisition.view_own')) {
            abort(403, 'Unauthorized action.');
        }

        $prRequest = PrRequest::with([
                'products.product.brand',
                'products.product.category',
                'products.product.sub_category',
                'products.variation',
                'location',
                'createdBy',
            ])
            ->findOrFail($id);

        return view('purchaseRequisition::index.show_modal', compact('prRequest'));
    }

    /**
     * Share requisition with suppliers.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function shareWithSuppliers(Request $request)
    {
        if (!auth()->user()->can('purchase_requisition.share_with_suppliers')) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'pr_id' => 'required|exists:pr_requests,id',
            'supplier_ids' => 'required|array',
            'supplier_ids.*' => 'exists:contacts,id',
        ]);

        try {
            DB::beginTransaction();

            $businessId = request()->session()->get('user.business_id');
            $prRequest = PrRequest::findOrFail($request->pr_id);

            $links = [];

            foreach ($request->supplier_ids as $supplierId) {
                // Check if response already exists
                $response = PrSupplierResponse::where('pr_request_id', $prRequest->id)
                    ->where('supplier_id', $supplierId)
                    ->first();

                if (!$response) {
                    // Generate unique ref_no for this supplier response
                    $refNo = $this->generateSupplierResponseRefNo($businessId, $prRequest->ref_no);

                    // Create new response with unique token and ref_no
                    $response = PrSupplierResponse::create([
                        'business_id' => $businessId,
                        'pr_request_id' => $prRequest->id,
                        'supplier_id' => $supplierId,
                        'ref_no' => $refNo,
                        'share_token' => Str::random(64),
                        'status' => 'pending',
                    ]);
                }

                $links[] = [
                    'supplier' => Contact::find($supplierId)->name,
                    'url' => url('/supplier-response/' . $response->share_token),
                ];
            }

            // Update PR status
            if ($prRequest->status == 'draft') {
                $prRequest->update(['status' => 'pending_supplier']);
            }

            DB::commit();

            $output = [
                'success' => true,
                'links' => $links,
                'msg' => __('purchaseRequisition::lang.success')
            ];
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::emergency('File:' . $e->getFile() . ' Line:' . $e->getLine() . ' Message:' . $e->getMessage());

            $output = [
                'success' => false,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Return supplier responses to pending status.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function returnToSupplier(Request $request)
    {
        if (!auth()->user()->can('purchase_requisition.approve') && !auth()->user()->can('purchase_requisition.share_with_suppliers')) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'pr_id' => 'required|exists:pr_requests,id',
            'supplier_response_ids' => 'required|array',
            'supplier_response_ids.*' => 'exists:pr_supplier_responses,id',
        ]);

        try {
            DB::beginTransaction();

            $prRequest = PrRequest::findOrFail($request->pr_id);

            foreach ($request->supplier_response_ids as $responseId) {
                $response = PrSupplierResponse::findOrFail($responseId);

                // Reset supplier response to pending
                $response->update([
                    'status' => 'pending',
                    'submitted_at' => null,
                    'approved_at' => null,
                    'approved_by' => null,
                ]);

                // Reset approved flags on supplier products
                PrSupplierProduct::where('pr_supplier_response_id', $responseId)
                    ->update(['approved' => false]);
            }

            // Check if all responses are now pending -> set PR to pending_supplier
            $hasSubmittedResponses = PrSupplierResponse::where('pr_request_id', $prRequest->id)
                ->whereIn('status', ['submitted', 'approved'])
                ->exists();

            if (!$hasSubmittedResponses) {
                $prRequest->update(['status' => 'pending_supplier']);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'msg' => __('purchaseRequisition::lang.returned_to_supplier_successfully')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::emergency('File:' . $e->getFile() . ' Line:' . $e->getLine() . ' Message:' . $e->getMessage());

            return response()->json([
                'success' => false,
                'msg' => __('messages.something_went_wrong')
            ]);
        }
    }

    /**
     * Get submitted supplier responses for return to supplier modal.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getSubmittedResponses(Request $request)
    {
        $prId = $request->pr_id;
        $responses = PrSupplierResponse::with('supplier')
            ->where('pr_request_id', $prId)
            ->whereIn('status', ['submitted', 'approved'])
            ->get();

        $data = [];
        foreach ($responses as $response) {
            $data[] = [
                'id' => $response->id,
                'supplier_name' => ($response->supplier ? ($response->supplier->name ?: $response->supplier->supplier_business_name) : null) ?: 'Unknown',
                'ref_no' => $response->ref_no,
                'status' => ucfirst($response->status),
            ];
        }

        return response()->json(['responses' => $data]);
    }

    /**
     * Make purchase from requisitions.
     *
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function makePurchase(Request $request)
    {
        if (!auth()->user()->can('purchase_requisition.make_purchase')) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'pr_request_ids' => 'required|array',
            'supplier_id' => 'required|exists:contacts,id',
            'location_id' => 'required|exists:business_locations,id',
        ]);

        try {
            $businessId = request()->session()->get('user.business_id');

            // Validate
            $validation = $this->purchaseGenerationService->validatePurchaseGeneration(
                $request->pr_request_ids,
                $request->supplier_id
            );

            if (!$validation['valid']) {
                return redirect()->back()->with('status', [
                    'success' => 0,
                    'msg' => implode(', ', $validation['errors'])
                ]);
            }

            // Generate purchase
            $transaction = $this->purchaseGenerationService->generatePurchase(
                $request->pr_request_ids,
                $request->supplier_id,
                $request->location_id,
                $businessId
            );

            $output = [
                'success' => 1,
                'msg' => __('purchaseRequisition::lang.purchase_created_successfully'),
                'transaction_id' => $transaction->id,
            ];

            // Export CSV if requested
            if ($request->export_csv) {
                $csv = $this->purchaseGenerationService->exportToCsv($transaction->id);
                // Save CSV or download
            }

            return redirect()->action([\App\Http\Controllers\PurchaseController::class, 'edit'], ['purchase' => $transaction->id])->with('status', $output);

        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . ' Line:' . $e->getLine() . ' Message:' . $e->getMessage());

            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];

            return redirect()->back()->with('status', $output);
        }
    }

    /**
     * Print requisition.
     *
     * @param int $id
     * @return \Illuminate\View\View
     */
    public function print($id)
    {
        $prRequest = PrRequest::with(['products.product', 'products.variation', 'location', 'createdBy'])
            ->findOrFail($id);

        return view('purchaseRequisition::index.print', compact('prRequest'));
    }

    /**
     * Get approved requests by supplier for make purchase.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getApprovedRequestsBySupplier(Request $request)
    {
        if (!auth()->user()->can('purchase_requisition.make_purchase')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $supplierId = $request->supplier_id;

        if (!$supplierId) {
            return response()->json(['requests' => []]);
        }

        // Get approved supplier responses for the selected supplier
        $responses = PrSupplierResponse::with(['prRequest'])
            ->where('business_id', $businessId)
            ->where('supplier_id', $supplierId)
            ->where('status', 'approved')
            ->whereHas('prRequest', function ($q) {
                $q->where('status', 'approved');
            })
            ->get();

        $requests = [];
        foreach ($responses as $response) {
            $requests[] = [
                'id' => $response->id,
                'pr_request_id' => $response->pr_request_id,
                'ref_no' => $response->ref_no,
                'pr_ref_no' => $response->prRequest->ref_no,
                'date' => \Carbon\Carbon::parse($response->prRequest->transaction_date)->format('Y-m-d'),
            ];
        }

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

    /**
     * Generate unique reference number for supplier response.
     *
     * @param int $businessId
     * @param string $prRefNo
     * @return string
     */
    protected function generateSupplierResponseRefNo($businessId, $prRefNo)
    {
        // Count existing responses for this PR
        $count = PrSupplierResponse::where('business_id', $businessId)
            ->whereHas('prRequest', function ($q) use ($prRefNo) {
                $q->where('ref_no', $prRefNo);
            })
            ->count();

        // Generate ref_no: PR-YYYYMMDDXXXX-S01, PR-YYYYMMDDXXXX-S02, etc.
        return $prRefNo . '-S' . str_pad($count + 1, 2, '0', STR_PAD_LEFT);
    }
}
