<?php

namespace App\Http\Controllers;

use App\Http\Requests\ItemVariation\StoreItemVariationRequest;
use App\Http\Requests\ItemVariation\UpdateItemVariationRequest;
use App\Models\Item;
use App\Models\ItemVariation;
use App\Traits\LogsActivity;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables;

class ItemVariationController extends Controller
{
	use LogsActivity;

	public function index(Item $item, Request $request)
	{
		if ($request->ajax()) {
			$query = $item->variations()->select('item_variations.*');
			return DataTables::of($query)
				->addColumn('full_sku', function (ItemVariation $variation) {
					return $variation->full_sku;
				})
				->addColumn('dimensions', function (ItemVariation $variation) {
					return $variation->dimensions ?: '-';
				})
				->addColumn('weight_display', function (ItemVariation $variation) {
					return $variation->formatted_weight;
				})
				->addColumn('cost_price_display', function (ItemVariation $variation) {
					return $variation->formatted_cost_price;
				})
				->addColumn('selling_price_display', function (ItemVariation $variation) {
					return $variation->formatted_selling_price;
				})
				->addColumn('stock_info', function (ItemVariation $variation) {
					$total = $variation->total_stock;
					$available = $variation->available_stock;
					return "Total: {$total} | Available: {$available}";
				})
				->addColumn('status_badge', function (ItemVariation $variation) {
					$class = $variation->is_active ? 'success' : 'danger';
					$label = $variation->is_active ? 'Active' : 'Inactive';
					return '<span class="badge bg-' . $class . '">' . $label . '</span>';
				})
				->addColumn('actions', function (ItemVariation $variation) use ($item) {
					$editUrl = route('items.variations.edit', [$item, $variation]);
					$showUrl = route('items.variations.show', [$item, $variation]);
					$deleteUrl = route('items.variations.destroy', [$item, $variation]);
					$csrf = csrf_field();
					$method = method_field('DELETE');

					return '<div class="btn-group" role="group">'
						.'<a href="'.$showUrl.'" class="btn btn-sm btn-info">View</a>'
						.'<a href="'.$editUrl.'" class="btn btn-sm btn-warning">Edit</a>'
						.'<form action="'.$deleteUrl.'" method="POST" style="display:inline;" onsubmit="return confirm(\'Are you sure you want to delete this variation?\')">'
						.$csrf.$method
						.'<button type="submit" class="btn btn-sm btn-danger">Delete</button>'
						.'</form>'
						.'</div>';
				})
				->rawColumns(['status_badge', 'actions'])
				->toJson();
		}

		return view('item_variations.index', compact('item'));
	}

	public function create(Item $item): View
	{
		return view('item_variations.create', compact('item'));
	}

	public function store(Item $item, StoreItemVariationRequest $request): RedirectResponse
	{
		try {
			$variation = null;
			DB::transaction(function () use ($item, $request, &$variation) {
				$variation = $item->variations()->create($request->validated());
			});

			$this->logActivity('Item Variation created', $variation, [
				'action' => 'store',
				'item_id' => $item->id,
				'item_name' => $item->name,
				'variation_name' => $variation->name
			]);

			return redirect()->route('items.variations.index', $item)->with('success', 'Variation created successfully.');
		} catch (\Throwable $e) {
			$this->logError('Item Variation creation failed', $e, [
				'action' => 'store',
				'item_id' => $item->id,
				'request_data' => $request->validated()
			]);

			report($e);
			return back()->withInput()->withErrors(['error' => 'Failed to create variation.']);
		}
	}

	public function show(Item $item, ItemVariation $variation): View
	{
		$variation->load(['item', 'inventories', 'itemSuppliers']);
		return view('item_variations.show', compact('item', 'variation'));
	}

	public function edit(Item $item, ItemVariation $variation): View
	{
		return view('item_variations.edit', compact('item', 'variation'));
	}

	public function update(Item $item, UpdateItemVariationRequest $request, ItemVariation $variation): RedirectResponse
	{
		try {
			$oldData = $variation->toArray();
			DB::transaction(function () use ($request, $variation) {
				$variation->update($request->validated());
			});

			$this->logActivity('Item Variation updated', $variation, [
				'action' => 'update',
				'item_id' => $item->id,
				'item_name' => $item->name,
				'old_data' => $oldData,
				'new_data' => $request->validated()
			]);

			return redirect()->route('items.variations.index', $variation->item)->with('success', 'Variation updated successfully.');
		} catch (\Throwable $e) {
			$this->logError('Item Variation update failed', $e, [
				'action' => 'update',
				'item_id' => $item->id,
				'variation_id' => $variation->id,
				'request_data' => $request->validated()
			]);

			report($e);
			return back()->withInput()->withErrors(['error' => 'Failed to update variation.']);
		}
	}

	public function destroy(Item $item, ItemVariation $variation): RedirectResponse
	{
		try {
			$variationData = $variation->toArray();
			DB::transaction(function () use ($variation) {
				$variation->delete();
			});

			$this->logActivity('Item Variation deleted', null, [
				'action' => 'destroy',
				'item_id' => $item->id,
				'item_name' => $item->name,
				'variation_data' => $variationData
			]);

			return redirect()->route('items.variations.index', $item)->with('success', 'Variation deleted successfully.');
		} catch (\Throwable $e) {
			$this->logError('Item Variation deletion failed', $e, [
				'action' => 'destroy',
				'item_id' => $item->id,
				'variation_id' => $variation->id
			]);

			report($e);
			return back()->withErrors(['error' => 'Failed to delete variation.']);
		}
	}

	public function search(Request $request)
	{
		$itemId = (int) $request->get('item_id');
		$q = (string) $request->get('q', '');
		$variations = ItemVariation::query()
			->where('item_id', $itemId)
			->when($q !== '', function($qr) use ($q){
				$qr->where('name', 'like', "%{$q}%")
				   ->orWhere('sku_suffix', 'like', "%{$q}%")
				   ->orWhere('size', 'like', "%{$q}%")
				   ->orWhere('color', 'like', "%{$q}%");
			})
			->orderBy('name')
			->limit(20)
			->get(['id','name','sku_suffix', 'size', 'color']);
		return response()->json([
			'results' => $variations->map(fn($v)=>[
				'id'=>$v->id,
				'text'=>$v->name.($v->sku_suffix?" (".$v->sku_suffix.")":'').($v->size?" - ".$v->size:'').($v->color?" - ".$v->color:'')
			]),
		]);
	}

	public function toggleActive(Item $item, ItemVariation $variation): RedirectResponse
	{
		try {
			$variation->update(['is_active' => !$variation->is_active]);

			$status = $variation->is_active ? 'activated' : 'deactivated';

			$this->logActivity('Item Variation status toggled', $variation, [
				'action' => 'toggle_active',
				'item_id' => $item->id,
				'item_name' => $item->name,
				'new_status' => $variation->is_active
			]);

			return redirect()->route('items.variations.index', $item)
				->with('success', "Variation {$status} successfully.");
		} catch (\Throwable $e) {
			$this->logError('Item Variation status toggle failed', $e, [
				'action' => 'toggle_active',
				'item_id' => $item->id,
				'variation_id' => $variation->id
			]);

			report($e);
			return back()->withErrors(['error' => 'Failed to toggle variation status.']);
		}
	}
}
