<?php

namespace App\Http\Controllers\Modules\Purchase;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Models\CustomerVendor;
use App\Models\PurchaseRFQ as RFQ;
use App\Models\PurchaseRFQItem as RFQItem;
use App\Models\PurchaseRFQFiles as RfqFile;
use App\Models\RfqType;
use App\Models\StockItem;
use App\Services\Purchase\PurchaseRfqService;
use App\Http\Requests\Purchase\StorePurchaseRfqRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

/**
 * Unified Purchase RFQ Controller
 *
 * Handles purchase RFQ management for all roles.
 * Views are automatically resolved based on the logged-in user's role.
 */
class PurchaseRfqController extends Controller
{
    use HasRoleViews;

    protected PurchaseRfqService $purchaseRfqService;

    public function __construct(PurchaseRfqService $purchaseRfqService)
    {
        $this->purchaseRfqService = $purchaseRfqService;
    }

    /**
     * Display the purchase RFQ creation form
     * Alias: rfq() for backward compatibility
     */
    public function rfq()
    {
        return $this->create();
    }

    /**
     * Display the purchase RFQ creation form
     */
    public function create()
    {
        $vendors = CustomerVendor::whereIn('company_role', ['Vendor', 'Both'])->get();
        $rfqTypes = RfqType::all();
        $stock_items = StockItem::all();

        return $this->roleView('purchasebom.rfq.rfq', compact('vendors', 'rfqTypes', 'stock_items'));
    }

    /**
     * Generate a new Purchase RFQ ID (AJAX)
     */
    public function generateRfqId(): JsonResponse
    {
        $rfqId = $this->purchaseRfqService->generateRfqNumber();
        return response()->json(['rfqId' => $rfqId]);
    }

    /**
     * Store a newly created purchase RFQ
     */
    public function store(StorePurchaseRfqRequest $request)
    {
        try {
            Log::info('[PURCHASE RFQ STORE] Processing started');

            // Validation handled by StorePurchaseRfqRequest
            $validated = $request->validated();

            Log::info('[PURCHASE RFQ STORE] Validation passed');

            DB::beginTransaction();

            $rfq = RFQ::create([
                'rfq_no' => $request->rfqNo,
                'rfq_date' => $request->rfqDate,
                'vendor_id' => $request->vendor,
                'vendor_reference_no' => $request->venRefNo,
                'rfq_type' => $request->rfqType,
                'description' => $request->input('description_main'),
                'delivery_terms' => $request->deliveryTerms,
                'note' => $request->note,
            ]);

            Log::info("[PURCHASE RFQ STORE] RFQ created with ID: {$rfq->id}");

            // Store RFQ Items
            if ($request->has('item') && is_array($request->item)) {
                foreach ($request->item as $index => $item) {
                    RFQItem::create([
                        'rfq_id' => $rfq->id,
                        'item' => $item,
                        'description' => $request->description[$index] ?? null,
                        'quantity' => $request->quantity[$index] ?? 0,
                        'uom' => $request->uom[$index] ?? '',
                        'required_by' => $request->requiredBy[$index] ?? null,
                    ]);
                }
            }

            Log::info('[PURCHASE RFQ STORE] RFQ items stored successfully');

            // Handle file uploads
            if ($request->hasFile('annexureFiles')) {
                foreach ($request->file('annexureFiles') as $file) {
                    $path = $file->store("rfq_files/annexure", 'public');

                    RfqFile::create([
                        'rfq_id' => $rfq->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_type' => 'annexure',
                    ]);

                    Log::info("[PURCHASE RFQ STORE] Annexure file saved: {$path}");
                }
            }

            DB::commit();

            return $this->redirectToRoute('purchasebom.rfq.rfqdetails')
                ->with('success', 'Purchase RFQ created successfully.');

        } catch (\Illuminate\Validation\ValidationException $ve) {
            Log::error('[PURCHASE RFQ STORE] Validation failed:', $ve->errors());
            return back()->withErrors($ve->errors())->withInput();
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('[PURCHASE RFQ STORE] Exception:', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);
            return back()->with('error', 'Something went wrong while creating Purchase RFQ.');
        }
    }

    /**
     * Display the purchase RFQ list page
     * Alias: rfqDetails() for backward compatibility
     */
    public function rfqDetails()
    {
        return $this->index();
    }

    /**
     * Display the purchase RFQ list page
     */
    public function index()
    {
        $rfqs = RFQ::with('vendor')->latest()->get();
        return $this->roleView('purchasebom.rfq.rfqdetails', compact('rfqs'));
    }

    /**
     * Display the specified purchase RFQ
     */
    public function show(int $id)
    {
        $rfq = RFQ::with(['vendor', 'customerInfo', 'items', 'rfqFiles'])->findOrFail($id);
        return $this->roleView('purchasebom.rfq.view', compact('rfq'));
    }

    /**
     * Display the edit form
     */
    public function edit(int $id)
    {
        $rfq = RFQ::with(['vendor', 'customerInfo', 'items', 'rfqFiles'])->findOrFail($id);
        $vendors = CustomerVendor::whereIn('company_role', ['Vendor', 'Both'])->get();
        $rfqTypes = RfqType::all();
        $stock_items = StockItem::all();

        return $this->roleView('purchasebom.rfq.edit', compact('rfq', 'vendors', 'rfqTypes', 'stock_items'));
    }

    /**
     * Update the specified purchase RFQ
     */
    public function update(Request $request, int $id)
    {
        try {
            $rfq = RFQ::findOrFail($id);

            $validated = $request->validate([
                'rfqNo' => 'required|string|unique:purchase_rfqs,rfq_no,' . $id,
                'rfqDate' => 'required|date',
                'vendor' => 'required|exists:customer_vendors,id',
                'venRefNo' => 'nullable|string',
                'rfqType' => 'required|string',
                'description_main' => 'nullable|string',
                'deliveryTerms' => 'nullable|string',
                'note' => 'nullable|string',
            ]);

            DB::beginTransaction();

            $rfq->update([
                'rfq_no' => $request->rfqNo,
                'rfq_date' => $request->rfqDate,
                'vendor_id' => $request->vendor,
                'vendor_reference_no' => $request->venRefNo,
                'rfq_type' => $request->rfqType,
                'description' => $request->input('description_main'),
                'delivery_terms' => $request->deliveryTerms,
                'note' => $request->note,
            ]);

            // Update items
            $rfq->items()->delete();
            if ($request->has('item') && is_array($request->item)) {
                foreach ($request->item as $index => $item) {
                    RFQItem::create([
                        'rfq_id' => $rfq->id,
                        'item' => $item,
                        'description' => $request->description[$index] ?? null,
                        'quantity' => $request->quantity[$index] ?? 0,
                        'uom' => $request->uom[$index] ?? '',
                        'required_by' => $request->requiredBy[$index] ?? null,
                    ]);
                }
            }

            // Handle new file uploads
            if ($request->hasFile('annexureFiles')) {
                foreach ($request->file('annexureFiles') as $file) {
                    $path = $file->store("rfq_files/annexure", 'public');

                    RfqFile::create([
                        'rfq_id' => $rfq->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_type' => 'annexure',
                    ]);
                }
            }

            DB::commit();

            return $this->redirectToRoute('purchasebom.rfq.rfqdetails')
                ->with('success', 'Purchase RFQ updated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Purchase RFQ Update Error: ' . $e->getMessage());
            return back()->with('error', 'Something went wrong while updating Purchase RFQ.');
        }
    }

    /**
     * Remove the specified purchase RFQ
     */
    public function destroy(int $id): JsonResponse
    {
        // Authorization: Only SuperAdmin or Manager can delete
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized. Only SuperAdmin or Manager can delete purchase RFQs.',
            ], 403);
        }

        try {
            $rfq = RFQ::with('rfqFiles')->findOrFail($id);

            // Prevent deletion of approved RFQs by non-SuperAdmin
            if ($rfq->status === 'approved' && !$this->isSuperAdmin()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot delete approved RFQs. Only SuperAdmin can delete approved records.',
                ], 403);
            }

            // Delete files
            foreach ($rfq->rfqFiles as $file) {
                if (Storage::disk('public')->exists($file->file_path)) {
                    Storage::disk('public')->delete($file->file_path);
                }
                $file->delete();
            }

            // Delete items
            $rfq->items()->delete();
            $rfq->delete();

            return response()->json(['success' => true, 'message' => 'Purchase RFQ deleted successfully.']);
        } catch (\Exception $e) {
            Log::error('Purchase RFQ Delete Error: ' . $e->getMessage());
            return response()->json(['success' => false, 'message' => 'Failed to delete Purchase RFQ.'], 500);
        }
    }

    /**
     * Approve a purchase RFQ (SuperAdmin only)
     */
    public function approve(int $id): JsonResponse
    {
        if (!$this->isSuperAdmin()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $rfq = RFQ::findOrFail($id);
        $rfq->status = 'approved';
        $rfq->save();

        return response()->json(['message' => 'Purchase RFQ approved!']);
    }

    /**
     * Reject a purchase RFQ (SuperAdmin only)
     */
    public function reject(int $id): JsonResponse
    {
        if (!$this->isSuperAdmin()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $rfq = RFQ::findOrFail($id);
        $rfq->status = 'rejected';
        $rfq->save();

        return response()->json(['message' => 'Purchase RFQ rejected!']);
    }

    /**
     * Print purchase RFQ
     */
    public function print(int $id)
    {
        $rfq = RFQ::with(['vendor', 'customerInfo', 'items'])->findOrFail($id);
        return $this->roleView('purchasebom.rfq.print', compact('rfq'));
    }

    /**
     * Delete a specific file
     */
    public function deleteFile(int $id): JsonResponse
    {
        $file = RfqFile::find($id);

        if (!$file) {
            return response()->json(['success' => false, 'message' => 'File not found.']);
        }

        if (Storage::disk('public')->exists($file->file_path)) {
            Storage::disk('public')->delete($file->file_path);
        }

        $file->delete();

        return response()->json(['success' => true, 'message' => 'File deleted successfully.']);
    }
}
