<?php

namespace App\Http\Controllers\Modules\Manufacturing;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Models\SkuMaster as Sku;
use App\Models\SkuApproval;
use App\Models\SkuMovement;
use App\Models\CustomerVendor;
use App\Services\Manufacturing\SkuService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;

/**
 * Unified SKU Controller
 *
 * Handles SKU (Stock Keeping Unit) management for all roles.
 * Reference: SuperAdminSKUController
 */
class SkuController extends Controller
{
    use HasRoleViews;

    protected SkuService $skuService;

    public function __construct(SkuService $skuService)
    {
        $this->skuService = $skuService;
    }

    /**
     * Display the SKU master page
     */
    public function index()
    {
        $categories = Sku::distinct()->pluck('category');
        $items = Sku::distinct()->pluck('item_name');

        return $this->roleView('sku.skumaster', compact('categories', 'items'));
    }

    /**
     * Alias for index - backward compatibility
     */
    public function skuMaster()
    {
        return $this->index();
    }

    /**
     * Get SKU data for DataTable (AJAX)
     */
    public function skuData(): JsonResponse
    {
        $skus = Sku::all();

        $data = [];
        foreach ($skus as $i => $sku) {
            $isLowStock = $sku->current_stock < $sku->min_order_level;
            $data[] = [
                'slno' => $i + 1,
                'item_name' => $sku->item_name,
                'category' => $sku->category,
                'uom' => $sku->uom,
                'current_stock' => $sku->current_stock,
                'is_low_stock' => $isLowStock,
                'default_price' => $sku->default_price,
                'stock_status' => $sku->current_stock > 0 ? 'In Stock' : 'Out of Stock',
                'min_order_level' => $sku->min_order_level,
                'max_order_level' => $sku->max_order_level,
                'actions' => view($this->resolveView('sku.partials.actions'), compact('sku'))->render(),
                'DT_RowClass' => $isLowStock ? 'table-warning' : '',
            ];
        }

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

    /**
     * Store a newly created SKU
     */
    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'item_name' => 'required|string|max:255',
            'category' => 'required|string|max:255',
            'uom' => 'required|string|max:255',
            'tax_rate' => 'required|numeric',
            'current_stock' => 'required|integer',
            'default_price' => 'required|numeric',
            'min_order_level' => 'required|integer',
            'max_order_level' => 'required|integer',
        ]);

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

        Sku::create($request->only([
            'item_name', 'category', 'uom', 'tax_rate', 'current_stock',
            'default_price', 'discount_price', 'tcs', 'min_order_level',
            'max_order_level', 'hsn_code', 'supplier_name', 'supplier_phone',
            'supplier_email', 'reason',
        ]));

        return response()->json(['success' => 'SKU added successfully!']);
    }

    /**
     * Get SKU for editing (AJAX)
     */
    public function edit(int $id): JsonResponse
    {
        $sku = Sku::findOrFail($id);
        return response()->json($sku);
    }

    /**
     * Update the specified SKU
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $sku = Sku::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'item_name' => 'required|string|max:255',
            'category' => 'required|string|max:255',
            'uom' => 'required|string|max:255',
            'tax_rate' => 'required|numeric',
            'current_stock' => 'required|integer',
            'default_price' => 'required|numeric',
            'min_order_level' => 'required|integer',
            'max_order_level' => 'required|integer',
        ]);

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

        $sku->update($request->only([
            'item_name', 'category', 'uom', 'tax_rate', 'current_stock',
            'default_price', 'discount_price', 'tcs', 'min_order_level',
            'max_order_level', 'hsn_code', 'supplier_name', 'supplier_phone',
            'supplier_email', 'reason',
        ]));

        return response()->json(['success' => 'SKU updated successfully!']);
    }

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

        $sku = Sku::findOrFail($id);

        // Check if SKU has movements
        if ($sku->movements()->count() > 0 && !$this->isSuperAdmin()) {
            return response()->json([
                'success' => false,
                'message' => 'Cannot delete SKU with existing movements. Contact SuperAdmin.'
            ], 403);
        }

        $sku->delete();

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

    // ==================== SKU APPROVAL ====================

    /**
     * Display the SKU approval page
     */
    public function skuApproval()
    {
        $customers = CustomerVendor::where('company_role', 'Customer')->pluck('company', 'id');
        $items = Sku::pluck('item_name', 'id');

        return $this->roleView('sku.skuapproval', compact('customers', 'items'));
    }

    /**
     * Get SKU approval list for DataTable (AJAX)
     */
    public function skuApprovalList(): JsonResponse
    {
        $approvals = SkuApproval::with('customer')->orderBy('id', 'desc')->get();
        $allSkus = Sku::pluck('item_name', 'id');

        $data = [];
        foreach ($approvals as $approval) {
            $itemIds = is_array($approval->items) ? $approval->items : explode(',', $approval->items);
            $itemNames = [];
            foreach ($itemIds as $id) {
                $id = trim($id);
                if (isset($allSkus[$id])) {
                    $itemNames[] = $allSkus[$id];
                }
            }

            $data[] = [
                'id' => $approval->id,
                'customer' => $approval->customer ? $approval->customer->company : '',
                'items' => implode(', ', $itemNames),
                'date' => $approval->date ? $approval->date->format('d-m-Y') : '',
                'approved_date' => $approval->approved_date ? $approval->approved_date->format('d-m-Y') : '',
                'status' => $approval->status,
                'action_date' => $approval->action_date ? $approval->action_date->format('d-m-Y') : '',
                'action_by' => $approval->action_by,
                'created_by' => $approval->created_by,
                'stock_status' => $approval->stock_status,
            ];
        }

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

    /**
     * Store a new SKU approval
     */
    public function skuApprovalStore(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'customer' => 'required',
            'items' => 'required|string',
            'date' => 'required|date',
            'approved_date' => 'nullable|date',
            'status' => 'required|string|max:50',
            'action_date' => 'nullable|date',
            'action_by' => 'nullable|string|max:255',
            'created_by' => 'required|string|max:255',
            'stock_status' => 'required|string|max:50',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $data = $request->only([
            'items', 'date', 'approved_date', 'status',
            'action_date', 'action_by', 'created_by', 'stock_status',
        ]);
        $data['customer_id'] = $request->input('customer');

        SkuApproval::create($data);

        return response()->json(['success' => true]);
    }

    /**
     * Get SKU approval for editing (AJAX)
     */
    public function skuApprovalShow(int $id): JsonResponse
    {
        $approval = SkuApproval::with('customer')->findOrFail($id);

        return response()->json([
            'id' => $approval->id,
            'customer_id' => $approval->customer_id,
            'customer_name' => $approval->customer ? $approval->customer->company : '',
            'items' => $approval->items,
            'date' => $approval->date ? date('Y-m-d', strtotime($approval->date)) : '',
            'approved_date' => $approval->approved_date ? date('Y-m-d', strtotime($approval->approved_date)) : '',
            'status' => $approval->status,
            'action_date' => $approval->action_date ? date('Y-m-d', strtotime($approval->action_date)) : '',
            'action_by' => $approval->action_by,
            'created_by' => $approval->created_by,
            'stock_status' => $approval->stock_status,
        ]);
    }

    /**
     * Update SKU approval
     */
    public function skuApprovalUpdate(Request $request, int $id): JsonResponse
    {
        $approval = SkuApproval::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'customer' => 'required',
            'items' => 'required|string',
            'date' => 'required|date',
            'status' => 'required|string|max:50',
            'stock_status' => 'required|string|max:50',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $data = $request->only([
            'items', 'date', 'approved_date', 'status',
            'action_date', 'action_by', 'created_by', 'stock_status',
        ]);
        $data['customer_id'] = $request->input('customer');

        $approval->update($data);

        return response()->json(['success' => true]);
    }

    /**
     * Delete SKU approval
     */
    public function skuApprovalDestroy(int $id): JsonResponse
    {
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);
        }

        $approval = SkuApproval::findOrFail($id);
        $approval->delete();

        return response()->json(['success' => true]);
    }

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

        $approval = SkuApproval::findOrFail($id);
        $approval->status = 'approved';
        $approval->approved_date = now();
        $approval->action_by = auth()->user()->name ?? 'SuperAdmin';
        $approval->action_date = now();
        $approval->save();

        return response()->json(['success' => true, 'message' => 'SKU Approval approved!']);
    }

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

        $approval = SkuApproval::findOrFail($id);
        $approval->status = 'rejected';
        $approval->action_by = auth()->user()->name ?? 'SuperAdmin';
        $approval->action_date = now();
        $approval->save();

        return response()->json(['success' => true, 'message' => 'SKU Approval rejected!']);
    }

    // ==================== SKU MOVEMENT ====================

    /**
     * Display the SKU movement page
     */
    public function skuMovement()
    {
        $items = Sku::pluck('item_name', 'id');
        $skus = Sku::all();

        // Get unique locations from existing movements, plus default locations
        $existingLocations = SkuMovement::pluck('from_location')
            ->merge(SkuMovement::pluck('to_location'))
            ->filter()
            ->unique()
            ->values()
            ->toArray();

        $defaultLocations = ['Warehouse', 'Production', 'Inventory', 'Shipping', 'Receiving'];
        $locations = collect(array_merge($defaultLocations, $existingLocations))->unique()->sort()->values();

        return $this->roleView('sku.skumovement', compact('items', 'skus', 'locations'));
    }

    /**
     * Get SKU movement list (AJAX)
     */
    public function skuMovementList(): JsonResponse
    {
        $movements = SkuMovement::with('sku')->orderBy('id', 'desc')->get();

        $data = [];
        foreach ($movements as $movement) {
            $data[] = [
                'id' => $movement->id,
                'reference' => $movement->reference ?? $movement->reference_no ?? '-',
                'item_name' => $movement->sku ? $movement->sku->item_name : ($movement->product ?? ''),
                'type' => $movement->type ?? $movement->movement_type ?? 'inbound',
                'quantity' => $movement->quantity ?? 0,
                'from_location' => $movement->from_location ?? '',
                'to_location' => $movement->to_location ?? '',
                'date' => $movement->date ?? ($movement->created_at ? $movement->created_at->format('Y-m-d H:i') : ''),
                'status' => $movement->status ?? 'completed',
                'notes' => $movement->notes ?? $movement->remarks ?? '',
            ];
        }

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