<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Product;
use App\Models\ProductImage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class AdminProductController extends Controller
{
    /**
     * Display a listing of the products with search and filtering.
     */
    public function index(Request $request)
    {
        $query = Product::with(['category', 'images']);

        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('sku', 'like', "%{$search}%");
            });
        }

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

        if ($request->filled('product_type')) {
            $type = strtolower($request->input('product_type'));
            if ($type === 'impon') {
                $query->where('product_type', 'impon');
            } elseif ($type === 'normal') {
                $query->where(function ($q) {
                    $q->where('product_type', 'normal')
                      ->orWhereNull('product_type')
                      ->orWhere('product_type', '');
                });
            }
        }

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

        if ($request->filled('stock')) {
            if ($request->input('stock') === 'in_stock') {
                $query->where('stock', '>', 0);
            } elseif ($request->input('stock') === 'out_of_stock') {
                $query->where('stock', '<=', 0);
            }
        }

        if ($request->filled('featured') && $request->input('featured') === '1') {
            $query->where('is_featured', true);
        }

        $products = $query->latest()->paginate(15)->withQueryString();
        $categories = Category::all();

        return view('admin.products.index', compact('products', 'categories'));
    }

    /**
     * Show the form for creating a new product.
     */
    public function create()
    {
        $categories = Category::all();
        return view('admin.products.create', compact('categories'));
    }

    /**
     * Store a newly created product in storage with multi-image handling.
     */
    public function store(Request $request)
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'sku' => ['nullable', 'string', 'max:100', 'unique:products,sku'],
            'product_type' => ['required', 'in:normal,impon'],
            'category_id' => ['required', 'exists:categories,id'],
            'short_description' => ['nullable', 'string'],
            'description' => ['nullable', 'string'],
            'price' => ['required', 'numeric', 'min:0'],
            'original_price' => ['nullable', 'numeric', 'min:0'],
            'stock' => ['required', 'integer', 'min:0'],
            'status' => ['required', 'in:active,inactive,sold_out'],
            'primary_image_file' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'hover_image_file' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'gallery_files.*' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'image' => ['nullable', 'string'],
            'hover_image' => ['nullable', 'string'],
            'badge' => ['nullable', 'string', 'max:50'],
        ]);

        $uploadedPaths = [];

        try {
            DB::transaction(function () use ($request, &$uploadedPaths) {
                
                $price = (float) $request->input('price');
                $originalPrice = $request->filled('original_price') ? (float) $request->input('original_price') : null;
                
                // Automatic discount percentage calculation
                $discount = 0;
                if ($originalPrice && $originalPrice > $price) {
                    $discount = (int) round((($originalPrice - $price) / $originalPrice) * 100);
                }

                $product = Product::create([
                    'name' => $request->input('name'),
                    'slug' => Str::slug($request->input('name')) . '-' . Str::random(5),
                    'sku' => $request->input('sku'),
                    'product_type' => $request->input('product_type', 'normal'),
                    'category_id' => $request->input('category_id'),
                    'short_description' => $request->input('short_description'),
                    'description' => $request->input('description'),
                    'price' => $price,
                    'original_price' => $originalPrice,
                    'discount' => $discount,
                    'stock' => (int) $request->input('stock'),
                    'status' => $request->input('status'),
                    'is_new' => $request->has('is_new'),
                    'is_best_seller' => $request->has('is_best_seller'),
                    'is_featured' => $request->has('is_featured'),
                    'is_trending' => $request->has('is_trending'),
                    'is_sold_out' => $request->has('is_sold_out') || ((int) $request->input('stock') === 0),
                    'badge' => $request->input('badge'),
                    'image' => $request->input('image'),
                    'hover_image' => $request->input('hover_image'),
                ]);

                // 1. Primary Image Upload
                if ($request->hasFile('primary_image_file')) {
                    $path = $request->file('primary_image_file')->store('products/' . date('Y/m'), 'public');
                    $uploadedPaths[] = $path;
                    
                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $path,
                        'image_type' => 'primary',
                        'is_primary' => true,
                        'sort_order' => 0,
                    ]);
                    $product->update(['image' => $path]);
                } elseif ($request->filled('image')) {
                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $request->input('image'),
                        'image_type' => 'primary',
                        'is_primary' => true,
                        'sort_order' => 0,
                    ]);
                }

                // 2. Hover Image Upload
                if ($request->hasFile('hover_image_file')) {
                    $path = $request->file('hover_image_file')->store('products/' . date('Y/m'), 'public');
                    $uploadedPaths[] = $path;

                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $path,
                        'image_type' => 'hover',
                        'is_primary' => false,
                        'sort_order' => 1,
                    ]);
                    $product->update(['hover_image' => $path]);
                } elseif ($request->filled('hover_image')) {
                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $request->input('hover_image'),
                        'image_type' => 'hover',
                        'is_primary' => false,
                        'sort_order' => 1,
                    ]);
                }

                // 3. Gallery Images Upload
                $galleryPaths = [];
                if ($request->hasFile('gallery_files')) {
                    $sortOrder = 2;
                    foreach ($request->file('gallery_files') as $file) {
                        if ($file->isValid()) {
                            $path = $file->store('products/' . date('Y/m'), 'public');
                            $uploadedPaths[] = $path;
                            $galleryPaths[] = $path;

                            ProductImage::create([
                                'product_id' => $product->id,
                                'image_path' => $path,
                                'image_type' => 'gallery',
                                'is_primary' => false,
                                'sort_order' => $sortOrder++,
                            ]);
                        }
                    }
                }
                if (!empty($galleryPaths)) {
                    $product->update(['additional_images' => $galleryPaths]);
                }
            });

            return redirect()->route('admin.products.index')
                ->with('success', 'Product created successfully with image uploads.');
        } catch (\Exception $e) {
            // Clean up files on failure
            foreach ($uploadedPaths as $path) {
                Storage::disk('public')->delete($path);
            }
            return back()->withInput()->with('error', 'Error creating product: ' . $e->getMessage());
        }
    }

    /**
     * Display full details of a specific product.
     */
    public function show(Product $product)
    {
        $product->load(['category', 'images']);
        return view('admin.products.show', compact('product'));
    }

    /**
     * Show the form for editing the specified product.
     */
    public function edit(Product $product)
    {
        $product->load(['category', 'images']);
        $categories = Category::all();
        return view('admin.products.edit', compact('product', 'categories'));
    }

    /**
     * Update the specified product with multi-image handling.
     */
    public function update(Request $request, Product $product)
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'sku' => ['nullable', 'string', 'max:100', 'unique:products,sku,' . $product->id],
            'product_type' => ['required', 'in:normal,impon'],
            'category_id' => ['required', 'exists:categories,id'],
            'short_description' => ['nullable', 'string'],
            'description' => ['nullable', 'string'],
            'price' => ['required', 'numeric', 'min:0'],
            'original_price' => ['nullable', 'numeric', 'min:0'],
            'stock' => ['required', 'integer', 'min:0'],
            'status' => ['required', 'in:active,inactive,sold_out'],
            'primary_image_file' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'hover_image_file' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'gallery_files.*' => ['nullable', 'image', 'mimes:jpeg,jpg,png,webp', 'max:5120'],
            'badge' => ['nullable', 'string', 'max:50'],
        ]);

        $uploadedPaths = [];

        try {
            DB::transaction(function () use ($request, $product, &$uploadedPaths) {
                $price = (float) $request->input('price');
                $originalPrice = $request->filled('original_price') ? (float) $request->input('original_price') : null;
                
                $discount = 0;
                if ($originalPrice && $originalPrice > $price) {
                    $discount = (int) round((($originalPrice - $price) / $originalPrice) * 100);
                }

                $product->update([
                    'name' => $request->input('name'),
                    'sku' => $request->input('sku'),
                    'product_type' => $request->input('product_type', 'normal'),
                    'category_id' => $request->input('category_id'),
                    'short_description' => $request->input('short_description'),
                    'description' => $request->input('description'),
                    'price' => $price,
                    'original_price' => $originalPrice,
                    'discount' => $discount,
                    'stock' => (int) $request->input('stock'),
                    'status' => $request->input('status'),
                    'is_new' => $request->has('is_new'),
                    'is_best_seller' => $request->has('is_best_seller'),
                    'is_featured' => $request->has('is_featured'),
                    'is_trending' => $request->has('is_trending'),
                    'is_sold_out' => $request->has('is_sold_out') || ((int) $request->input('stock') === 0),
                    'badge' => $request->input('badge'),
                ]);

                // Update Primary Image if new file uploaded
                if ($request->hasFile('primary_image_file')) {
                    $path = $request->file('primary_image_file')->store('products/' . date('Y/m'), 'public');
                    $uploadedPaths[] = $path;

                    // Unset old primary
                    ProductImage::where('product_id', $product->id)->where('is_primary', true)->update(['is_primary' => false]);
                    
                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $path,
                        'image_type' => 'primary',
                        'is_primary' => true,
                        'sort_order' => 0,
                    ]);
                    $product->update(['image' => $path]);
                }

                // Update Hover Image if new file uploaded
                if ($request->hasFile('hover_image_file')) {
                    $path = $request->file('hover_image_file')->store('products/' . date('Y/m'), 'public');
                    $uploadedPaths[] = $path;

                    // Remove old hover image record
                    ProductImage::where('product_id', $product->id)->where('image_type', 'hover')->delete();

                    ProductImage::create([
                        'product_id' => $product->id,
                        'image_path' => $path,
                        'image_type' => 'hover',
                        'is_primary' => false,
                        'sort_order' => 1,
                    ]);
                    $product->update(['hover_image' => $path]);
                }

                // Append Gallery Images if new files uploaded
                if ($request->hasFile('gallery_files')) {
                    $lastSortOrder = ProductImage::where('product_id', $product->id)->max('sort_order') ?? 2;
                    foreach ($request->file('gallery_files') as $file) {
                        if ($file->isValid()) {
                            $path = $file->store('products/' . date('Y/m'), 'public');
                            $uploadedPaths[] = $path;

                            ProductImage::create([
                                'product_id' => $product->id,
                                'image_path' => $path,
                                'image_type' => 'gallery',
                                'is_primary' => false,
                                'sort_order' => ++$lastSortOrder,
                            ]);
                        }
                    }
                }
            });

            return redirect()->route('admin.products.index')
                ->with('success', 'Product updated successfully.');
        } catch (\Exception $e) {
            foreach ($uploadedPaths as $path) {
                Storage::disk('public')->delete($path);
            }
            return back()->withInput()->with('error', 'Error updating product: ' . $e->getMessage());
        }
    }

    /**
     * Delete an individual product image record and remove its physical file from storage.
     */
    public function destroyImage(ProductImage $image)
    {
        try {
            if (!empty($image->image_path) && !str_starts_with($image->image_path, 'http')) {
                Storage::disk('public')->delete($image->image_path);
            }

            $image->delete();

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

            return back()->with('success', 'Image removed successfully.');
        } catch (\Exception $e) {
            if (request()->expectsJson()) {
                return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
            }
            return back()->with('error', 'Failed to remove image: ' . $e->getMessage());
        }
    }

    /**
     * Soft deactivation of product.
     */
    public function destroy(Product $product)
    {
        $product->update(['status' => 'inactive']);

        return redirect()->route('admin.products.index')
            ->with('success', 'Product deactivated successfully.');
    }

    /**
     * Show the Excel product import form.
     */
    public function showImportForm()
    {
        return view('admin.products.import');
    }

    /**
     * Clean and sanitize imported HTML description fragments.
     */
    private function sanitizeDescription(?string $html): ?string
    {
        if (empty($html)) {
            return null;
        }

        $clean = trim($html);
        if (str_contains($clean, 'PlaygroundEditorTheme') || str_contains($clean, 'class=') || str_contains($clean, 'style=')) {
            $clean = strip_tags($clean, '<p><br><b><strong><i><em><ul><ol><li>');
            $clean = preg_replace('/class="[^"]*"/i', '', $clean);
            $clean = preg_replace('/style="[^"]*"/i', '', $clean);
        }

        return trim($clean) ?: null;
    }

    /**
     * Process Excel/CSV product import with validation and summary.
     */
    public function importExcel(Request $request)
    {
        $request->validate([
            'excel_file' => ['required', 'file', 'max:10240'],
        ]);

        $file = $request->file('excel_file');
        $extension = strtolower($file->getClientOriginalExtension());
        $path = $file->getRealPath();

        $rows = [];
        if (in_array($extension, ['csv', 'txt', 'tsv'])) {
            $handle = fopen($path, 'r');
            $header = null;
            $delimiter = ($extension === 'tsv') ? "\t" : ',';
            while (($data = fgetcsv($handle, 4096, $delimiter)) !== false) {
                if (!$header) {
                    $header = array_map(fn($h) => strtolower(trim(preg_replace('/[^a-zA-Z0-9_]/', '', str_replace([' ', '-'], '_', $h)))), $data);
                } else {
                    if (count($header) === count($data)) {
                        $rows[] = array_combine($header, $data);
                    }
                }
            }
            fclose($handle);
        } else {
            $content = file_get_contents($path);
            $lines = explode("\n", str_replace("\r", "", $content));
            $header = null;
            foreach ($lines as $line) {
                $line = trim($line);
                if (empty($line)) continue;
                $delimiter = str_contains($line, "\t") ? "\t" : (str_contains($line, ';') ? ';' : ',');
                $data = str_getcsv($line, $delimiter);
                if (!$header) {
                    $header = array_map(fn($h) => strtolower(trim(preg_replace('/[^a-zA-Z0-9_]/', '', str_replace([' ', '-'], '_', $h)))), $data);
                } else {
                    if (count($header) === count($data)) {
                        $rows[] = array_combine($header, $data);
                    }
                }
            }
        }

        $totalRows = count($rows);
        $successCount = 0;
        $failedCount = 0;
        $skippedCount = 0;
        $errors = [];

        foreach ($rows as $index => $row) {
            $rowNum = $index + 2;
            
            $name = $row['product_name'] ?? $row['name'] ?? $row['title'] ?? null;
            if (empty($name)) {
                $failedCount++;
                $errors[] = "Row {$rowNum}: Missing product_name or name.";
                continue;
            }

            try {
                $sku = !empty($row['sku']) ? trim($row['sku']) : 'SKU-' . strtoupper(Str::random(6));
                
                // Normalize Product Type
                $typeRaw = strtolower($row['product_type'] ?? $row['type'] ?? 'normal');
                $productType = (str_contains($typeRaw, 'impon')) ? 'impon' : 'normal';

                // Find or create Category
                $categoryName = $row['category'] ?? $row['category_name'] ?? 'Jewellery';
                $category = Category::where('name', 'like', "%{$categoryName}%")->first();
                if (!$category) {
                    $category = Category::create([
                        'name' => $categoryName,
                        'slug' => Str::slug($categoryName),
                    ]);
                }

                $price = (float) ($row['selling_price'] ?? $row['price'] ?? 0);
                $mrp = !empty($row['mrp']) ? (float) $row['mrp'] : (!empty($row['original_price']) ? (float) $row['original_price'] : null);
                
                $discount = 0;
                if ($mrp && $mrp > $price) {
                    $discount = (int) round((($mrp - $price) / $mrp) * 100);
                }

                $stock = isset($row['stock']) ? (int) $row['stock'] : 10;
                $status = !empty($row['status']) ? strtolower($row['status']) : 'active';
                if (!in_array($status, ['active', 'inactive', 'sold_out'])) {
                    $status = 'active';
                }

                $isNew = filter_var($row['is_new'] ?? false, FILTER_VALIDATE_BOOLEAN);
                $isBestSeller = filter_var($row['is_best_seller'] ?? false, FILTER_VALIDATE_BOOLEAN);
                $isFeatured = filter_var($row['is_featured'] ?? false, FILTER_VALIDATE_BOOLEAN);
                $isTrending = filter_var($row['is_trending'] ?? false, FILTER_VALIDATE_BOOLEAN);

                $primaryImage = $row['primary_image'] ?? $row['image'] ?? null;
                $hoverImage = $row['hover_image'] ?? null;

                if ($primaryImage && str_contains($primaryImage, 'C:\\')) {
                    $primaryImage = null;
                }
                if ($hoverImage && str_contains($hoverImage, 'C:\\')) {
                    $hoverImage = null;
                }

                Product::updateOrCreate(
                    ['sku' => $sku],
                    [
                        'name' => $name,
                        'slug' => Str::slug($name) . '-' . Str::random(4),
                        'product_type' => $productType,
                        'category_id' => $category->id,
                        'short_description' => $this->sanitizeDescription($row['short_description'] ?? null),
                        'description' => $this->sanitizeDescription($row['description'] ?? null),
                        'price' => $price,
                        'original_price' => $mrp,
                        'discount' => $discount,
                        'stock' => $stock,
                        'status' => $status,
                        'is_new' => $isNew,
                        'is_best_seller' => $isBestSeller,
                        'is_featured' => $isFeatured,
                        'is_trending' => $isTrending,
                        'is_sold_out' => $stock <= 0 || $status === 'sold_out',
                        'image' => $primaryImage,
                        'hover_image' => $hoverImage,
                    ]
                );

                $successCount++;
            } catch (\Exception $e) {
                $failedCount++;
                $errors[] = "Row {$rowNum} ({$name}): " . $e->getMessage();
            }
        }

        $importSummary = [
            'total' => $totalRows,
            'success' => $successCount,
            'failed' => $failedCount,
            'skipped' => $skippedCount,
            'errors' => $errors,
        ];

        return redirect()->route('admin.products.import')
            ->with('importSummary', $importSummary)
            ->with('success', "Import completed: {$successCount} products processed successfully.");
    }
}
