<?php

namespace App\Http\Controllers\Warehouse;

use App\Http\Controllers\Controller;
use App\Services\Warehouse\SupplierService;
use App\Services\Auth\RoleBasedAccessService;
use App\Models\Warehouse\Supplier;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class SupplierController extends Controller
{
    protected $supplierService;
    protected $accessService;

    public function __construct(SupplierService $supplierService, RoleBasedAccessService $accessService)
    {
        $this->supplierService = $supplierService;
        $this->accessService = $accessService;

        $this->middleware('warehouse.access');
        $this->middleware('warehouse.permission:warehouse.suppliers.view')->only(['index', 'show', 'data']);
        $this->middleware('warehouse.permission:warehouse.suppliers.create')->only(['create', 'store']);
        $this->middleware('warehouse.permission:warehouse.suppliers.edit')->only(['edit', 'update']);
        $this->middleware('warehouse.permission:warehouse.suppliers.delete')->only(['destroy']);
    }

    /**
     * Display a listing of suppliers.
     */
    public function index(Request $request)
    {
        if ($request->expectsJson()) {
            return $this->getDataForTable($request);
        }

        // Get suppliers with filters and pagination
        $query = Supplier::query();

        // Apply filters
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('supplier_code', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('contact_person', 'like', "%{$search}%");
            });
        }

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

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

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

        if ($request->filled('rating_min')) {
            $query->where('rating', '>=', $request->rating_min);
        }

        if ($request->filled('rating_max')) {
            $query->where('rating', '<=', $request->rating_max);
        }

        // Get paginated results
        $suppliers = $query->orderBy('created_at', 'desc')->paginate(25);
        $suppliers->appends($request->query());

        $filterOptions = $this->supplierService->getFilterOptions();
        $statistics = $this->supplierService->getDashboardStatistics();

        return view('warehouse.suppliers.index', compact('filterOptions', 'statistics', 'suppliers'));
    }

    /**
     * Get data for DataTables Ajax request.
     */
    public function data(Request $request)
    {
        return $this->getDataForTable($request);
    }

    /**
     * Show the form for creating a new supplier.
     */
    public function create()
    {
        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.create

        $filterOptions = $this->supplierService->getFilterOptions();

        return view('warehouse.suppliers.create', compact('filterOptions'));
    }

    /**
     * Store a newly created supplier.
     */
    public function store(Request $request)
    {
        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.create

        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'supplier_code' => 'nullable|string|max:50|unique:suppliers,supplier_code',
            'contact_person' => 'nullable|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'mobile' => 'nullable|string|max:20',
            'address' => 'nullable|string|max:500',
            'city' => 'nullable|string|max:100',
            'state' => 'nullable|string|max:100',
            'country' => 'nullable|string|max:100',
            'postal_code' => 'nullable|string|max:20',
            'tax_number' => 'nullable|string|max:50',
            'website' => 'nullable|url|max:255',
            'bank_name' => 'nullable|string|max:255',
            'bank_account' => 'nullable|string|max:50',
            'payment_terms' => 'nullable|string|max:100',
            'credit_limit' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|size:3',
            'status' => 'required|in:active,inactive,suspended',
            'notes' => 'nullable|string|max:1000',
            'rating' => 'nullable|numeric|min:0|max:5',
        ]);

        try {
            \Log::info('Supplier creation started', ['validated_data' => $validatedData]);
            
            $supplier = $this->supplierService->create($validatedData);
            
            \Log::info('Supplier created successfully', [
                'supplier_id' => $supplier->id,
                'supplier_name' => $supplier->name,
                'supplier_code' => $supplier->supplier_code
            ]);

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'data' => $supplier,
                    'message' => 'Supplier created successfully'
                ], 201);
            }

            return redirect()->route('warehouse.suppliers.index')
                           ->with('success', "Supplier '{$supplier->name}' created successfully");

        } catch (\Exception $e) {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => $e->getMessage()
                ], 400);
            }

            return back()->withErrors(['error' => $e->getMessage()])->withInput();
        }
    }

    /**
     * Display the specified supplier.
     */
    public function show($id)
    {
        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            abort(404, 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.view

        $performanceData = $this->supplierService->getPerformanceData($id);

        return view('warehouse.suppliers.show', compact('supplier', 'performanceData'));
    }

    /**
     * Show the form for editing the specified supplier.
     */
    public function edit($id)
    {
        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            if (request()->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Supplier not found'
                ], 404);
            }
            abort(404, 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.edit

        if (request()->expectsJson()) {
            return response()->json([
                'success' => true,
                'data' => $supplier,
                'filterOptions' => $this->supplierService->getFilterOptions()
            ]);
        }

        $filterOptions = $this->supplierService->getFilterOptions();
        return view('warehouse.suppliers.edit', compact('supplier', 'filterOptions'));
    }

    /**
     * Update the specified supplier.
     */
    public function update(Request $request, $id)
    {
        \Log::info('Supplier update started', ['id' => $id, 'data' => $request->all()]);

        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            \Log::error('Supplier not found', ['id' => $id]);
            abort(404, 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.edit

        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'supplier_code' => [
                'nullable',
                'string',
                'max:50',
                Rule::unique('suppliers', 'supplier_code')->ignore($id)
            ],
            'contact_person' => 'nullable|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'mobile' => 'nullable|string|max:20',
            'address' => 'nullable|string|max:500',
            'city' => 'nullable|string|max:100',
            'state' => 'nullable|string|max:100',
            'country' => 'nullable|string|max:100',
            'postal_code' => 'nullable|string|max:20',
            'tax_number' => 'nullable|string|max:50',
            'website' => 'nullable|url|max:255',
            'bank_name' => 'nullable|string|max:255',
            'bank_account' => 'nullable|string|max:50',
            'payment_terms' => 'nullable|string|max:100',
            'credit_limit' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|size:3',
            'status' => 'required|in:active,inactive,suspended',
            'notes' => 'nullable|string|max:1000',
            'rating' => 'nullable|numeric|min:0|max:5',
        ]);

        try {
            \Log::info('Updating supplier with validated data', ['data' => $validatedData]);
            $updatedSupplier = $this->supplierService->update($id, $validatedData);
            \Log::info('Supplier updated successfully', ['supplier' => $updatedSupplier->toArray()]);

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'data' => $updatedSupplier,
                    'message' => 'Supplier updated successfully'
                ]);
            }

            \Log::info('Redirecting to supplier show page');
            return redirect()->route('warehouse.suppliers.show', $updatedSupplier)
                           ->with('success', 'Supplier updated successfully');

        } catch (\Exception $e) {
            \Log::error('Supplier update failed', ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => $e->getMessage()
                ], 400);
            }

            return back()->withErrors(['error' => $e->getMessage()])->withInput();
        }
    }

    /**
     * Remove the specified supplier.
     */
    public function destroy($id)
    {
        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            if (request()->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Supplier not found'
                ], 404);
            }
            
            return redirect()->route('warehouse.suppliers.index')
                           ->with('error', 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.delete

        try {
            $supplierName = $supplier->name;
            $this->supplierService->delete($id);

            if (request()->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Supplier deleted successfully'
                ]);
            }

            return redirect()->route('warehouse.suppliers.index')
                           ->with('success', "Supplier '{$supplierName}' deleted successfully");

        } catch (\Exception $e) {
            if (request()->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => $e->getMessage()
                ], 400);
            }
            
            return redirect()->route('warehouse.suppliers.index')
                           ->with('error', $e->getMessage());
        }
    }

    /**
     * Import suppliers from Excel file.
     */
    public function import(Request $request)
    {
        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.create

        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls,csv|max:10240' // 10MB max
        ]);

        try {
            \Log::info('Starting supplier import', [
                'file_name' => $request->file('file')->getClientOriginalName(),
                'file_size' => $request->file('file')->getSize(),
                'user_id' => auth()->id()
            ]);

            $results = $this->supplierService->importFromExcel($request->file('file'));

            \Log::info('Supplier import completed', [
                'success_count' => $results['success'],
                'error_count' => count($results['errors']),
                'warning_count' => count($results['warnings']),
                'created_suppliers' => collect($results['created_suppliers'])->pluck('id')->toArray()
            ]);

            // Debug: Check if suppliers were actually saved
            $actualCount = Supplier::count();
            \Log::info('Total suppliers in database after import', ['count' => $actualCount]);

            return response()->json([
                'success' => true,
                'imported' => $results['success'],
                'updated' => 0, // Currently we only create new suppliers
                'skipped' => count($results['errors']) + count($results['warnings']),
                'total_suppliers_in_db' => $actualCount, // Debug info
                'errors' => $results['errors'],
                'warnings' => $results['warnings'],
                'created_ids' => collect($results['created_suppliers'])->pluck('id')->toArray(), // Debug info
                'data' => $results,
                'message' => "Import completed. {$results['success']} suppliers imported successfully."
            ]);

        } catch (\Exception $e) {
            \Log::error('Supplier import failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
                'debug_info' => [
                    'error_type' => get_class($e),
                    'line' => $e->getLine(),
                    'file' => $e->getFile()
                ]
            ], 422);
        }
    }

    /**
     * Download the supplier import template.
     */
    public function downloadTemplate()
    {
        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.view

        try {
            $filePath = $this->supplierService->generateImportTemplate();
            $filename = 'suppliers_import_template.xlsx';

            return response()->download($filePath, $filename)->deleteFileAfterSend(true);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Export suppliers to Excel.
     */
    public function export(Request $request)
    {
        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.view

        $filters = $request->only([
            'status', 'country', 'city', 'rating_min', 'rating_max',
            'created_from', 'created_to'
        ]);

        try {
            $filePath = $this->supplierService->exportToExcel($filters);
            $filename = basename($filePath);

            return response()->download($filePath, $filename)->deleteFileAfterSend(true);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Update supplier rating.
     */
    public function updateRating(Request $request, $id)
    {
        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            abort(404, 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.edit

        $request->validate([
            'rating' => 'required|numeric|min:0|max:5',
            'notes' => 'nullable|string|max:1000'
        ]);

        try {
            $updatedSupplier = $this->supplierService->updateRating(
                $id,
                $request->rating,
                $request->notes
            );

            return response()->json([
                'success' => true,
                'data' => $updatedSupplier,
                'message' => 'Supplier rating updated successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get supplier performance data.
     */
    public function performance($id)
    {
        $supplier = $this->supplierService->findById($id);

        if (!$supplier) {
            abort(404, 'Supplier not found');
        }

        // Authorization is handled by middleware: warehouse.permission:warehouse.suppliers.view

        try {
            $performanceData = $this->supplierService->getPerformanceData($id);

            return response()->json([
                'success' => true,
                'data' => $performanceData,
                'message' => 'Performance data retrieved successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get filter options for dropdowns.
     */
    public function filterOptions()
    {
        return response()->json([
            'success' => true,
            'data' => $this->supplierService->getFilterOptions()
        ]);
    }

    /**
     * Get suppliers for dropdown (active suppliers only).
     */
    public function dropdown()
    {
        try {
            $suppliers = $this->supplierService->getRepository()->getActiveForDropdown();

            return response()->json([
                'success' => true,
                'data' => $suppliers
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get data for DataTables.
     */
    protected function getDataForTable(Request $request)
    {
        try {
            $data = $this->supplierService->getForDataTable($request->all());

            return response()->json($data);

        } catch (\Exception $e) {
            return response()->json([
                'error' => $e->getMessage(),
                'draw' => $request->input('draw', 1),
                'recordsTotal' => 0,
                'recordsFiltered' => 0,
                'data' => []
            ], 400);
        }
    }
}