<?php

namespace App\Http\Controllers;

use App\Models\Sale;
use App\Models\Product;
use App\Models\Payment;
use App\Models\Setting;
use Illuminate\Http\Request;

class SaleController extends Controller
{
    public function create()
    {
        $tenant = app('tenant');
        // Fetch products and customers for the form
        $products = Product::where('tenant_id', $tenant->id)->get();
        $customers = \App\Models\Customer::where('tenant_id', $tenant->id)->get();
        return view('sales.create', compact('products', 'customers'));
    }

    public function invoice($id)
    {
        $tenant = app('tenant');
        $sale = Sale::with(['sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'payments', 'customer', 'exchanges.brand', 'exchanges.mobileModel'])
            ->where('tenant_id', $tenant->id)
            ->findOrFail($id);
        $all_settings = Setting::where('tenant_id', $tenant->id)->first();

        return view('sell.invoice', compact('sale', 'all_settings'));
    }

    public function ajaxInvoice($id)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::with(['sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'payments', 'customer', 'exchanges.brand', 'exchanges.mobileModel'])
                ->where('tenant_id', $tenant->id)
                ->findOrFail($id);
            $all_settings = Setting::where('tenant_id', $tenant->id)->first();

            $html = view('sell.invoice', compact('sale', 'all_settings'))->render();
            

            return response()->json(['html' => $html]);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to load invoice: ' . $e->getMessage()], 500);
        }
    }

    public function tableInvoice($id)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::with(['sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'payments', 'customer', 'exchanges.brand', 'exchanges.mobileModel'])
                ->where('tenant_id', $tenant->id)
                ->findOrFail($id);
            $all_settings = Setting::where('tenant_id', $tenant->id)->first();

            return view('sell.invoice-table', compact('sale', 'all_settings'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Failed to load invoice: ' . $e->getMessage());
        }
    }

    public function publicTableInvoice($id)
    {
        try {
            // Check if this is a direct sale (starts with DS- or is a direct sale ID)
            if (str_starts_with($id, 'DS-')) {
                // Extract the actual ID from DS-{id}
                $directSaleId = str_replace('DS-', '', $id);
                $sale = \App\Models\DirectSales::with('Customer')->findOrFail($directSaleId);

                // Transform direct sale to match regular sale structure for the view
                $sale = (object) [
                    'id' => 'DS-' . $sale->id,
                    'type' => 'direct_sale',
                    'created_at' => $sale->direct_date_time ? \Carbon\Carbon::parse($sale->direct_date_time) : now(),
                    'customer' => $sale->Customer,
                    'customer_name' => $sale->direct_customer_name,
                    'total_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                    'net_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                    'paid_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity, // Direct sales are fully paid
                    'due_amount' => 0, // Direct sales are typically fully paid
                    'discount' => 0, // Direct sales don't have exchange discounts
                    'payment_method' => 'cash', // Default for direct sales
                    'payment_status' => 'paid', // Direct sales are typically paid
                    'product_type' => $sale->product_type,
                    'quantity' => $sale->direct_sold_quantity,
                    'profit' => $sale->direct_profit,
                    'sellTransactions' => collect([
                        (object) [
                            'name' => $sale->product_type, // Product Type for direct sales
                            'sold_quantity' => $sale->direct_sold_quantity,
                            'sell_price' => $sale->direct_sell_price,
                            'buy_price' => $sale->direct_cost_price,
                            'total_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                            'product' => (object) [
                                'brand' => 'Direct Sale',
                                'model' => $sale->product_type,
                                'imei_or_sn' => 'N/A'
                            ]
                        ]
                    ]),
                    'exchanges' => collect(),
                    'original_model' => $sale,
                ];

                $all_settings = \App\Models\Setting::where('tenant_id', $sale->original_model->tenant_id)->first();
            } else {
                // Try to find as regular sale first
                $sale = Sale::with(['sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'payments', 'customer', 'exchanges.brand', 'exchanges.mobileModel'])
                    ->find($id);

                if (!$sale) {
                    // If not found as regular sale, try as direct sale
                    $sale = \App\Models\DirectSales::with('Customer')->find($id);
                    if ($sale) {
                        // Transform direct sale to match regular sale structure
                        $sale = (object) [
                            'id' => 'DS-' . $sale->id,
                            'type' => 'direct_sale',
                            'created_at' => $sale->direct_date_time ? \Carbon\Carbon::parse($sale->direct_date_time) : now(),
                            'customer' => $sale->Customer,
                            'customer_name' => $sale->direct_customer_name,
                            'total_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                            'net_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                            'paid_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity, // Direct sales are fully paid
                            'due_amount' => 0, // Direct sales are typically fully paid
                            'discount' => 0, // Direct sales don't have exchange discounts
                            'payment_method' => 'cash', // Default for direct sales
                            'payment_status' => 'paid', // Direct sales are typically paid
                            'sellTransactions' => collect([
                                (object) [
                                    'name' => $sale->product_type, // Product Type for direct sales
                                    'sold_quantity' => $sale->direct_sold_quantity,
                                    'sell_price' => $sale->direct_sell_price,
                                    'buy_price' => $sale->direct_cost_price,
                                    'total_amount' => $sale->direct_sell_price * $sale->direct_sold_quantity,
                                    'product' => (object) [
                                        'brand' => 'Direct Sale',
                                        'model' => $sale->product_type,
                                        'imei_or_sn' => 'N/A'
                                    ]
                                ]
                            ]),
                            'exchanges' => collect(),
                            'original_model' => $sale,
                        ];
                    }
                    $all_settings = \App\Models\Setting::where('tenant_id', $sale->original_model->tenant_id)->first();
                } else {
                    // Regular sale found
                    $all_settings = \App\Models\Setting::where('tenant_id', $sale->tenant_id)->first();
                }
            }

            if (!$sale) {
                return response()->view('errors.invoice-not-found', ['message' => 'Invoice not found'], 404);
            }

            return view('sell.invoice-table', compact('sale', 'all_settings'));
        } catch (\Exception $e) {
            return response()->view('errors.invoice-not-found', ['message' => 'Invoice not found'], 404);
        }
    }

    public function store(Request $request)
    {
        return $request;
        // Validate the request
        $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'products' => 'required|array',
            'payment_method' => 'required|in:cash,credit',
        ]);

        $tenant = app('tenant');

        // Create Sale
        $sale = Sale::create([
            'tenant_id' => $tenant->id,
            'customer_id' => $request->customer_id,
            'total_price' => array_sum(array_column($request->products, 'price')), // Calculate total price from products
            'payment_method' => $request->payment_method,
        ]);

        // Attach products to sale
        foreach ($request->products as $product) {
            $sale->products()->attach($product['id'], [
                'quantity' => $product['quantity'],
                'price' => $product['price'],
            ]);
        }

        // Process payment
        Payment::create([
            'tenant_id' => $tenant->id,
            'sale_id' => $sale->id,
            'payment_type' => $request->payment_method,
            'amount' => $sale->total_price,
        ]);

        return redirect()->route('sales.create')->with('success', 'Sale created successfully!');
    }

    public function edit(Sale $sale)
    {
        $tenant = app('tenant');
        $sale = Sale::where('tenant_id', $tenant->id)->findOrFail($sale->id);
        // Fetch products and customers for the form
        $products = Product::where('tenant_id', $tenant->id)->get();
        $customers = \App\Models\Customer::where('tenant_id', $tenant->id)->get();
        
        // Get settings for currency
        $all_settings = \App\Models\Setting::where('tenant_id', $tenant->id)->first();
        
        return view('sales.edit', compact('sale', 'products', 'customers', 'all_settings'));
    }

    public function update(Request $request, Sale $sale)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::where('tenant_id', $tenant->id)->findOrFail($sale->id);
            
            // Get settings for currency
            $all_settings = \App\Models\Setting::where('tenant_id', $tenant->id)->first();

            // Validate the request
            $request->validate([
                'customer_id' => 'required|exists:customers,id',
                'products' => 'required|array|min:1',
                'products.*.id' => 'required|exists:products,id',
                'products.*.quantity' => 'required|integer|min:1',
                'products.*.price' => 'required|numeric|min:0',
                'payment_method' => 'required|in:cash,credit,card,bank_transfer',
            ]);

            // Calculate total amount
            $totalAmount = 0;
            foreach ($request->products as $product) {
                $totalAmount += $product['quantity'] * $product['price'];
            }

            // Update Sale basic information
            $sale->update([
                'customer_id' => $request->customer_id,
                'total_amount' => $totalAmount,
                'net_amount' => $totalAmount,
                'payment_method' => $request->payment_method,
                'updated_at' => now(),
            ]);

            // Delete existing transactions to replace them
            $sale->sellTransactions()->delete();

            // Create new sell transactions
            foreach ($request->products as $productData) {
                \App\Models\SellTransaction::create([
                    'tenant_id' => $tenant->id,
                    'sale_id' => $sale->id,
                    'product_id' => $productData['id'],
                    'sold_quantity' => $productData['quantity'],
                    'sell_price' => $productData['price'],
                    'total_amount' => $productData['quantity'] * $productData['price'],
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);

                // Update product stock (decrease by sold quantity)
                $product = Product::find($productData['id']);
                if ($product) {
                    $product->decrement('quantity', $productData['quantity']);
                }
            }

            // Update payment records
            $sale->payments()->delete(); // Remove previous payments
            \App\Models\Payment::create([
                'tenant_id' => $tenant->id,
                'sale_id' => $sale->id,
                'payment_method' => $request->payment_method,
                'amount' => $totalAmount,
                'payment_date' => now(),
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            return redirect()->route('sales.history')->with('success', 'Sale updated successfully! Total: ' . ($all_settings->currency ?? 'BDT') . ' ' . number_format($totalAmount, 2));
        } catch (\Exception $e) {
            \Log::error('Sale update error: ' . $e->getMessage());
            return redirect()->back()->withInput()->with('error', 'Error updating sale: ' . $e->getMessage());
        }
    }

    public function show($id, Request $request = null)
    {
        $tenant = app('tenant');
        $sale = Sale::with(['customer', 'sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'payments', 'exchanges.brand', 'exchanges.mobileModel'])
            ->where('tenant_id', $tenant->id)
            ->findOrFail($id);

        // Transform sellTransactions to items for the view
        $sale->items = $sale->sellTransactions->map(function($transaction) {
            return (object) [
                'product_name' => $transaction->product ? $transaction->product->name : 'Unknown Product',
                'product' => $transaction->product,
                'quantity' => $transaction->sold_quantity,
                'unit_price' => $transaction->sell_price,
                'total_price' => $transaction->sell_price * $transaction->sold_quantity,
            ];
        });

        // Calculate totals
        $sale->subtotal = $sale->items->sum('total_price');
        $sale->tax_amount = $sale->tax_amount ?? 0;
        $sale->discount_amount = $sale->discount_amount ?? 0;

        // If this is an API request, return JSON
        if ($request && ($request->expectsJson() || $request->is('api/*'))) {
            return response()->json($sale);
        }

        return view('sales.show', compact('sale'));
    }

    public function index()
    {
        $tenant = app('tenant');
        
        // Get today's sales data
        $today = now()->startOfDay();
        $todaySales = Sale::where('tenant_id', $tenant->id)
            ->where('created_at', '>=', $today)
            ->get();
        
        // Calculate statistics
        $totalSales = $todaySales->count();
        $todayRevenue = $todaySales->sum('total_amount');
        $todayProfit = $todaySales->sum('profit_amount') ?? $todaySales->sum(function($sale) {
            return $sale->sellTransactions->sum('profit');
        });
        // Get today's direct sales total amount
        $todayDirectSalesAmount = \App\Models\DirectSales::where('tenant_id', $tenant->id)
            ->whereDate('direct_date_time', now()->toDateString())
            ->sum(\DB::raw('direct_sell_price * direct_sold_quantity'));
        
        // Use direct sales amount for the card
        $pendingPayments = $todayDirectSalesAmount;
        
        // Get recent sales (both regular and direct sales)
        $regularSales = Sale::with(['customer', 'sellTransactions'])
            ->where('tenant_id', $tenant->id)
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get();

        // Get recent direct sales
        $directSales = \App\Models\DirectSales::with('Customer')
            ->orderBy('direct_date_time', 'desc')
            ->limit(10)
            ->get();

        // Transform direct sales to match regular sales structure
        $transformedDirectSales = $directSales->map(function($directSale) {
            return (object) [
                'id' => 'DS-' . $directSale->id, // Prefix to distinguish direct sales
                'type' => 'direct_sale',
                'created_at' => $directSale->direct_date_time ? \Carbon\Carbon::parse($directSale->direct_date_time) : now(),
                'customer' => $directSale->Customer,
                'customer_name' => $directSale->direct_customer_name,
                'customer_phone' => $directSale->Customer ? $directSale->Customer->phone : null, // Add phone from customer relationship
                'total_amount' => $directSale->direct_sell_price * $directSale->direct_sold_quantity,
                'net_amount' => $directSale->direct_sell_price * $directSale->direct_sold_quantity,
                'due_amount' => 0, // Direct sales are typically fully paid
                'payment_method' => 'cash', // Default for direct sales
                'payment_status' => 'paid', // Direct sales are typically paid
                'product_type' => $directSale->product_type,
                'quantity' => $directSale->direct_sold_quantity,
                'profit' => $directSale->direct_profit,
                'sellTransactions' => collect([
                    (object) [
                        'product_name' => $directSale->product_type,
                        'sold_quantity' => $directSale->direct_sold_quantity,
                        'sell_price' => $directSale->direct_sell_price,
                        'buy_price' => $directSale->direct_cost_price,
                    ]
                ]),
                'exchanges' => collect(),
                'original_model' => $directSale, // Keep reference to original model
            ];
        });

        // Transform regular sales to match the structure
        $transformedRegularSales = $regularSales->map(function($sale) {
            $sale->type = 'regular_sale';
            $sale->original_model = $sale;
            return $sale;
        });

        // Merge and sort all recent sales by date, then take top 10
        $recentSales = $transformedRegularSales->concat($transformedDirectSales)
            ->sortByDesc('created_at')
            ->take(10)
            ->values();
        
        // Payment status counts
        $paidCount = Sale::where('tenant_id', $tenant->id)->where('payment_status', 'paid')->count();
        $unpaidCount = Sale::where('tenant_id', $tenant->id)->where('payment_status', 'unpaid')->count();
        $partialCount = Sale::where('tenant_id', $tenant->id)->where('payment_status', 'partial')->count();
        
        // Weekly sales data for chart
        $weeklyData = [];
        $weeklyLabels = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = now()->subDays($i);
            $weeklyLabels[] = $date->format('M d');
            $dayTotal = Sale::where('tenant_id', $tenant->id)
                ->whereDate('created_at', $date)
                ->sum('total_amount');
            $weeklyData[] = $dayTotal;
        }

        // Get settings for currency
        $all_settings = \App\Models\Setting::where('tenant_id', $tenant->id)->first();
        
        return view('sales.index', compact(
            'totalSales', 'todayRevenue', 'todayProfit', 'pendingPayments',
            'recentSales', 'paidCount', 'unpaidCount', 'partialCount',
            'weeklyData', 'weeklyLabels', 'all_settings'
        ));
    }

    public function history()
    {
        $tenant = app('tenant');
        
        // Get settings for currency
        $all_settings = \App\Models\Setting::where('tenant_id', $tenant->id)->first();
        
        // Load regular sales with related data
        $regularSales = Sale::with(['customer', 'sellTransactions', 'exchanges.brand', 'exchanges.mobileModel'])
            ->where('tenant_id', $tenant->id)
            ->orderBy('created_at', 'desc')
            ->get();
        
        // Load direct sales
        $directSales = \App\Models\DirectSales::with('Customer')
            ->orderBy('direct_date_time', 'desc')
            ->get();
        
        // Transform direct sales to match regular sales structure
        $transformedDirectSales = $directSales->map(function($directSale) {
            return (object) [
                'id' => 'DS-' . $directSale->id, // Prefix to distinguish direct sales
                'type' => 'direct_sale',
                'created_at' => $directSale->direct_date_time ? \Carbon\Carbon::parse($directSale->direct_date_time) : now(),
                'customer' => $directSale->Customer,
                'customer_name' => $directSale->direct_customer_name,
                'total_amount' => $directSale->direct_sell_price * $directSale->direct_sold_quantity,
                'net_amount' => $directSale->direct_sell_price * $directSale->direct_sold_quantity,
                'due_amount' => 0, // Direct sales are typically fully paid
                'payment_method' => 'cash', // Default for direct sales
                'payment_status' => 'paid', // Direct sales are typically paid
                'product_type' => $directSale->product_type,
                'quantity' => $directSale->direct_sold_quantity,
                'profit' => $directSale->direct_profit,
                'sellTransactions' => collect([
                    (object) [
                        'product_name' => $directSale->product_type,
                        'sold_quantity' => $directSale->direct_sold_quantity,
                        'sell_price' => $directSale->direct_sell_price,
                        'buy_price' => $directSale->direct_cost_price,
                    ]
                ]),
                'exchanges' => collect(),
                'original_model' => $directSale, // Keep reference to original model
            ];
        });
        
        // Transform regular sales to match the structure
        $transformedRegularSales = $regularSales->map(function($sale) {
            $sale->type = 'regular_sale';
            $sale->original_model = $sale;
            // Add exchange information
            $sale->has_exchanges = $sale->exchanges->count() > 0;
            $sale->exchange_count = $sale->exchanges->count();
            $sale->total_exchange_value = $sale->exchanges->sum('price');
            return $sale;
        });
        
        // Merge and sort all sales by date
        $allSales = $transformedRegularSales->concat($transformedDirectSales)
            ->sortByDesc('created_at')
            ->values();
        
        // Manual pagination
        $currentPage = request()->get('page', 1);
        $perPage = 25;
        $total = $allSales->count();
        $offset = ($currentPage - 1) * $perPage;
        
        $paginatedSales = $allSales->slice($offset, $perPage);
        
        // Create pagination instance
        $sales = new \Illuminate\Pagination\LengthAwarePaginator(
            $paginatedSales,
            $total,
            $perPage,
            $currentPage,
            [
                'path' => request()->url(),
                'pageName' => 'page',
            ]
        );
        
        return view('sales.history', compact('sales', 'all_settings'));
    }

    public function markAsPaid($id)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::where('tenant_id', $tenant->id)->findOrFail($id);
            
            $sale->update([
                'payment_status' => 'paid',
                'due_amount' => 0
            ]);
            
            return response()->json(['success' => true, 'message' => 'Sale marked as paid successfully']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Error updating sale status'], 500);
        }
    }

    public function destroy($id)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::where('tenant_id', $tenant->id)->findOrFail($id);
            
            // Use the model's built-in deletion logic which handles cleanup via booted() method
            $sale->delete();
            
            return response()->json(['success' => true, 'message' => 'Sale deleted successfully']);
        } catch (\Exception $e) {
            \Log::error('Sale deletion error: ' . $e->getMessage());
            return response()->json(['success' => false, 'message' => 'Error deleting sale: ' . $e->getMessage()], 500);
        }
    }

    public function getItems($id)
    {
        try {
            $tenant = app('tenant');
            $sale = Sale::with(['sellTransactions.product.ProductBrand', 'sellTransactions.product.ProductModel', 'exchanges.brand', 'exchanges.mobileModel'])
                ->where('tenant_id', $tenant->id)
                ->findOrFail($id);

            $transactions = $sale->sellTransactions->map(function($transaction) {
                return [
                    'id' => $transaction->id,
                    'product_name' => $transaction->product ? $transaction->product->name : 'N/A',
                    'brand' => $transaction->product ? ($transaction->product->ProductBrand ? $transaction->product->ProductBrand->name : 'N/A') : 'N/A',
                    'model' => $transaction->product ? ($transaction->product->ProductModel ? $transaction->product->ProductModel->name : 'N/A') : 'N/A',
                    'imei_or_sn' => $transaction->product ? $transaction->product->imei_or_sn : 'N/A',
                    'sold_quantity' => $transaction->sold_quantity,
                    'sell_price' => $transaction->sell_price,
                    'buy_price' => $transaction->product ? $transaction->product->buy_price : 0,
                    'warranty' => $transaction->warranty ?? 'No warranty',
                ];
            });

            $exchanges = $sale->exchanges->map(function($exchange) {
                return [
                    'id' => $exchange->id,
                    'brand_name' => $exchange->brand ? $exchange->brand->name : null,
                    'custom_brand' => $exchange->custom_brand,
                    'model_name' => $exchange->mobileModel ? $exchange->mobileModel->name : null,
                    'custom_model' => $exchange->custom_model,
                    'imei' => $exchange->imei,
                    'price' => $exchange->price,
                ];
            });

            return response()->json([
                'success' => true,
                'transactions' => $transactions,
                'exchanges' => $exchanges,
                'sale_id' => $sale->id
            ]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Error loading sale items'], 500);
        }
    }
}
