<?php

namespace App\Http\Controllers;

use App\Models\Tender;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use PDF;

class TenderController extends Controller
{
    // GET /api/tenders
    public function index(Request $request)
    {
        $user = Auth::user();
        if (!$user) {
            return response()->json(['status' => 'error', 'message' => 'Unauthenticated'], 401);
        }

        $query = DB::table('tenders');

        // Society-scoped access
        if ($user->society_id) {
            $query->where('society_id', $user->society_id);
        }

        // Vendors see only "open" tenders
        if ($user->role === 'vendor') {
            $query->where('approval_status', 'open');
        }

        if ($request->has('search')) {
            $search = $request->query('search');
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('description', 'like', "%{$search}%")
                    ->orWhere('category', 'like', "%{$search}%");
            });
        }

        $tenders = $query->orderBy('created_at', 'desc')->paginate(10);

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

    // POST /api/tenders
    public function store(Request $request)
    {
        $user = Auth::user();
        if (!$user || !$user->society_id) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'tender_type' => 'required|string',
            'location' => 'nullable|string',
            'description' => 'nullable|string',
            'budget' => 'nullable|numeric',
            'emd_amount' => 'nullable|numeric',
            'tender_fee' => 'nullable|numeric',
            'bid_submission_start' => 'nullable|date',
            'deadline' => 'nullable|date',
        ]);

        $tender = Tender::create([
            'society_id' => $user->society_id,
            'created_by' => $user->id,
            'title' => $validated['title'],
            'tender_type' => $validated['tender_type'] ?? 'open',
            'location' => $validated['location'] ?? null,
            'description' => $validated['description'] ?? null,
            'budget' => $validated['budget'] ?? null,
            'emd_amount' => $validated['emd_amount'] ?? 0,
            'tender_fee' => $validated['tender_fee'] ?? 0,
            'bid_submission_start' => $validated['bid_submission_start'] ?? null,
            'deadline' => $validated['deadline'] ?? null,
            'category' => $request->category ?? 'maintenance',
            'status' => 'open',
            'approval_status' => 'draft'
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Tender created successfully',
            'id' => $tender->id
        ], 201);
    }

    // GET /api/tenders/{id}
    public function show($id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender) {
            return response()->json(['status' => 'error', 'message' => 'Tender not found'], 404);
        }

        // Enforce society scoping
        if ($user->society_id && $tender->society_id != $user->society_id) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

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

    // PUT /api/tenders/{id}
    public function update(Request $request, $id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Tender not found or unauthorized'], 404);
        }

        $validated = $request->validate([
            'title' => 'sometimes|required|string|max:255',
            'tender_type' => 'nullable|string',
            'location' => 'nullable|string',
            'description' => 'nullable|string',
            'budget' => 'nullable|numeric',
            'emd_amount' => 'nullable|numeric',
            'tender_fee' => 'nullable|numeric',
            'deadline' => 'nullable|date',
            'bid_submission_start' => 'nullable|date',
            'status' => 'nullable|string|max:50',
        ]);

        DB::table('tenders')->where('id', $id)->update(array_merge($validated, ['updated_at' => now()]));

        return response()->json([
            'status' => 'success',
            'message' => 'Tender updated successfully'
        ]);
    }

    // DELETE /api/tenders/{id}
    public function destroy($id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Tender not found or unauthorized'], 404);
        }

        DB::table('tenders')->where('id', $id)->delete();

        return response()->json([
            'status' => 'success',
            'message' => 'Tender deleted successfully'
        ]);
    }

    // POST /api/tenders/{id}/bids (Vendor submits bid)
    public function submitBid(Request $request, $id)
    {
        $user = Auth::user();
        $isAdmin = in_array($user->role, ['society_admin', 'secretary']);

        // Admin can submit on behalf of vendor, vendor submits for themselves
        if (!$user) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 401);
        }

        if (!$isAdmin && $user->role !== 'vendor') {
            return response()->json(['status' => 'error', 'message' => 'Only vendors or admins can submit bids'], 403);
        }

        $tender = DB::table('tenders')->where('id', $id)->first();
        if (!$tender || $tender->approval_status !== 'open') {
            return response()->json(['status' => 'error', 'message' => 'Tender not available for bidding'], 404);
        }

        // Determine vendor ID
        $vendorId = $isAdmin && $request->vendor_id ? $request->vendor_id : $user->id;

        $validator = Validator::make($request->all(), [
            'quoted_amount' => 'required|numeric|min:0',
            'proposal_details' => 'nullable|string',
            'vendor_id' => $isAdmin ? 'nullable|exists:users,id' : 'nullable',
            'documents.*' => 'nullable|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120' // 5MB
        ]);

        if ($validator->fails()) {
            return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422);
        }

        // Check if vendor already submitted a bid
        $existingBid = DB::table('tender_bids')
            ->where('tender_id', $id)
            ->where('vendor_id', $vendorId)
            ->first();

        if ($existingBid) {
            return response()->json(['status' => 'error', 'message' => 'A bid has already been submitted for this vendor'], 422);
        }

        // Handle file uploads
        $documentPaths = [];
        if ($request->hasFile('documents')) {
            foreach ($request->file('documents') as $file) {
                $path = $file->store('bid_documents', 'public');
                $documentPaths[] = [
                    'name' => $file->getClientOriginalName(),
                    'path' => $path,
                    'size' => $file->getSize(),
                    'uploaded_at' => now()->toDateTimeString()
                ];
            }
        }

        DB::table('tender_bids')->insert([
            'tender_id' => $id,
            'vendor_id' => $vendorId,
            'quoted_amount' => $request->quoted_amount,
            'proposal_details' => $request->proposal_details,
            'documents' => !empty($documentPaths) ? json_encode($documentPaths) : null,
            'status' => 'submitted',
            'created_at' => now(),
            'updated_at' => now()
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Bid submitted successfully'
        ], 201);
    }

    // GET /api/tenders/{id}/bids (Admin views all bids)
    public function getBids($id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $bids = DB::table('tender_bids')
            ->join('users', 'tender_bids.vendor_id', '=', 'users.id')
            ->where('tender_bids.tender_id', $id)
            ->select('tender_bids.*', 'users.name as vendor_name', 'users.email as vendor_email')
            ->orderBy('tender_bids.quoted_amount', 'asc')
            ->get();

        return response()->json(['status' => 'success', 'data' => $bids]);
    }

    // POST /api/tenders/{id}/award/{bidId} (Admin awards tender)
    public function awardTender($id, $bidId)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $bid = DB::table('tender_bids')->where('id', $bidId)->where('tender_id', $id)->first();
        if (!$bid) {
            return response()->json(['status' => 'error', 'message' => 'Bid not found'], 404);
        }

        // Update tender status
        DB::table('tenders')->where('id', $id)->update([
            'approval_status' => 'awarded',
            'status' => 'closed',
            'awarded_vendor_id' => $bid->vendor_id,
            'approved_by' => $user->id,
            'approved_at' => now(),
            'updated_at' => now()
        ]);

        // Update bid status
        DB::table('tender_bids')->where('id', $bidId)->update(['status' => 'accepted', 'updated_at' => now()]);
        DB::table('tender_bids')->where('tender_id', $id)->where('id', '!=', $bidId)->update(['status' => 'rejected', 'updated_at' => now()]);

        return response()->json([
            'status' => 'success',
            'message' => 'Tender awarded successfully',
            'work_order_url' => url("/api/tenders/{$id}/work-order")
        ]);
    }

    public function downloadWorkOrder($id)
    {
        $tender = DB::table('tenders')
            ->leftJoin('societies', 'tenders.society_id', '=', 'societies.id')
            ->select('tenders.*', 'societies.name as society_name', 'societies.address as society_address', 'societies.logo as society_logo')
            ->where('tenders.id', $id)
            ->first();

        if (!$tender) {
            return response()->json(['status' => 'error', 'message' => 'Tender not found'], 404);
        }

        if ($tender->approval_status !== 'awarded' || !$tender->awarded_vendor_id) {
            return response()->json(['status' => 'error', 'message' => 'Tender is not awarded yet'], 400);
        }

        $vendor = DB::table('users')->where('id', $tender->awarded_vendor_id)->first();

        $bid = DB::table('tender_bids')
            ->where('tender_id', $id)
            ->where('vendor_id', $tender->awarded_vendor_id)
            ->where('status', 'accepted')
            ->first();

        if (!$vendor || !$bid) {
            return response()->json(['status' => 'error', 'message' => 'Vendor or Bid data missing'], 404);
        }

        $data = [
            'tender' => $tender,
            'vendor' => $vendor,
            'bid' => $bid
        ];

        $pdf = PDF::loadView('tenders.work_order', $data)->setOptions(['isRemoteEnabled' => true]);

        // Sanitize filename
        $vendorName = preg_replace('/[^A-Za-z0-9\-]/', '_', $vendor->name);
        return $pdf->download("WorkOrder_{$tender->tender_number}_{$vendorName}.pdf");
    }

    // POST /api/tenders/{id}/approve (Admin approves tender to open for bidding)
    public function approveTender($id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        DB::table('tenders')->where('id', $id)->update([
            'approval_status' => 'open',
            'approved_by' => $user->id,
            'approved_at' => now(),
            'updated_at' => now()
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Tender approved and opened for bidding'
        ]);
    }

    // POST /api/tenders/{id}/suspend
    public function suspendTender(Request $request, $id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        // Only admins can suspend
        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $request->validate(['reason' => 'required|string']);

        DB::table('tenders')->where('id', $id)->update([
            'is_suspended' => true,
            'suspended_reason' => $request->reason,
            'updated_at' => now()
        ]);

        return response()->json(['status' => 'success', 'message' => 'Tender suspended successfully']);
    }

    // POST /api/tenders/{id}/resume
    public function resumeTender($id)
    {
        $user = Auth::user();
        $tender = DB::table('tenders')->where('id', $id)->first();

        if (!$tender || ($user->society_id && $tender->society_id != $user->society_id)) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        DB::table('tenders')->where('id', $id)->update([
            'is_suspended' => false,
            'suspended_reason' => null,
            'updated_at' => now()
        ]);

        return response()->json(['status' => 'success', 'message' => 'Tender resumed successfully']);
    }

    // GET /api/tenders/{id}/pdf
    public function downloadPdf($id)
    {
        $user = Auth::user();
        // Use eager loading for society/creator if needed, but simple query is fine
        $tender = DB::table('tenders')
            ->leftJoin('societies', 'tenders.society_id', '=', 'societies.id')
            ->select('tenders.*', 'societies.name as society_name', 'societies.address as society_address', 'societies.logo as society_logo')
            ->where('tenders.id', $id)
            ->first();

        if (!$tender) {
            return response()->json(['status' => 'error', 'message' => 'Tender not found'], 404);
        }

        // Society check
        if ($user->role !== 'vendor' && $user->society_id && $tender->society_id != $user->society_id) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }
        // Vendors can access any open tender? Or assuming filtered earlier.
        // If vendor, they can download if status is open/etc. Checking same logic as show().
        // For simplicity, allow if they can view it.

        $data = ['tender' => $tender];
        $pdf = PDF::loadView('tenders.pdf', $data)->setOptions(['isRemoteEnabled' => true]);

        return $pdf->download('Tender_' . $tender->tender_number . '.pdf');
    }

    // Download bid document
    public function downloadBidDocument($bidId, $index)
    {
        $bid = DB::table('tender_bids')->where('id', $bidId)->first();

        if (!$bid) {
            return response()->json(['status' => 'error', 'message' => 'Bid not found'], 404);
        }

        if (!$bid->documents) {
            return response()->json(['status' => 'error', 'message' => 'No documents found'], 404);
        }

        $documents = json_decode($bid->documents, true);

        if (!isset($documents[$index])) {
            return response()->json(['status' => 'error', 'message' => 'Document not found'], 404);
        }

        $filePath = storage_path('app/public/' . $documents[$index]['path']);

        if (!file_exists($filePath)) {
            return response()->json(['status' => 'error', 'message' => 'File not found on server'], 404);
        }

        // return response()->file($filePath);
        $headers = [
            'Content-Type' => mime_content_type($filePath),
            'Content-Disposition' => 'inline; filename="' . $documents[$index]['name'] . '"',
        ];

        return response(file_get_contents($filePath), 200, $headers);
    }
}
