<?php

namespace App\Http\Controllers;

use App\Models\SalesDashboard;
use App\Models\Product;
use App\Models\Service;
use App\Models\Particular;
use App\Models\BankAccount;
use App\Models\Quotation;
use App\Models\DigitalPayment;
use App\Models\ExpenseType;
use App\Models\Segment;
use App\Models\Transaction;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Customer;
use Illuminate\Http\Request;

class SalesDashboardController extends Controller
{
    public function index()
    {
        $salesDashboards = SalesDashboard::orderBy('created_at', 'desc')->get();
        return view('sales-dashboard.index', compact('salesDashboards'));
    }

    public function create()
    {
        $products = Product::orderBy('name', 'asc')->get();
        $services = Service::orderBy('name', 'asc')->get();
        $particulars = Particular::orderBy('particulars', 'asc')->get();
        $bankAccounts = BankAccount::orderBy('bank_name', 'asc')->get();
        $digitalPayments = DigitalPayment::orderBy('provider', 'asc')->get();
        $expenseTypes = ExpenseType::orderBy('name', 'asc')->get();
        $segments = Segment::orderBy('name', 'asc')->get();
        $quotations = Quotation::orderBy('quotation_number', 'desc')->get();
        $customers = Customer::where('user_id', auth()->id())->orderBy('name', 'asc')->get();
        return view('sales-dashboard.create', compact('products', 'services', 'particulars', 'bankAccounts', 'digitalPayments', 'expenseTypes', 'segments', 'quotations', 'customers'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'date' => 'nullable|date',
            'invoice' => 'nullable|string|max:255',
            'customer_id' => 'required|exists:customers,id',
            'quotation_id' => 'nullable|exists:quotations,id',
            'product' => 'nullable|string|max:255',
            'service_id' => 'nullable|exists:services,id',
            'qty' => 'nullable|integer|min:0',
            'sales' => 'nullable|numeric|min:0',
            'total_sales' => 'nullable|numeric',
            'particulars' => 'nullable|string',
            'payment' => 'nullable|numeric|min:0',
            'payment_method' => 'nullable|in:cash,bank,digital',
            'bank_account_id' => 'required_if:payment_method,bank|nullable|exists:bank_accounts,id',
            'digital_payment_id' => 'required_if:payment_method,digital|nullable|exists:digital_payments,id',
            'due' => 'nullable|numeric|min:0',
            'cogs' => 'nullable|numeric|min:0',
            'gross_profit' => 'nullable|numeric',
            'percentage' => 'nullable|numeric',
            'cash_received_by' => 'nullable|string|max:255',
            'segment' => 'nullable|string|max:255',
            'amount' => 'nullable|numeric|min:0',
            'kpi' => 'nullable|numeric|min:0',
            'revenue' => 'nullable|numeric|min:0',
            'achiv' => 'nullable|numeric|min:0',
        ]);

        // Remove fields that shouldn't be stored in database
        unset($validated['total_sales']);

        // Add user_id
        $validated['user_id'] = auth()->id();

        // Calculate total sales
        $totalSales = ($validated['qty'] ?? 0) * ($validated['sales'] ?? 0);
        $due = $totalSales - ($validated['payment'] ?? 0);

        // Determine invoice status based on payment
        $status = 'unpaid';
        if ($validated['payment'] > 0 && $validated['payment'] >= $totalSales) {
            $status = 'paid';
        } elseif ($validated['payment'] > 0 && $validated['payment'] < $totalSales) {
            $status = 'partial';
        }

        // Create Invoice first
        $invoice = Invoice::create([
            'user_id' => auth()->id(),
            'customer_id' => $validated['customer_id'],
            'date' => $validated['date'] ?? now(),
            'status' => $status,
            'notes' => $validated['particulars'] ?? null,
            'subtotal' => $totalSales,
            'tax' => 0,
            'discount' => 0,
            'total' => $totalSales,
            'paid' => $validated['payment'] ?? 0,
            'due' => max(0, $due),
        ]);

        // Create Invoice Item if product is selected and qty is valid
        if (!empty($validated['product']) && !empty($validated['qty']) && $validated['qty'] > 0) {
            // Use case-insensitive search and trim whitespace
            $productName = trim($validated['product']);
            $product = Product::whereRaw('LOWER(name) = ?', [strtolower($productName)])->first();

            if ($product) {
                $cogs = $product->purchase_price * $validated['qty'];
                $subtotal = $validated['qty'] * $validated['sales'];

                InvoiceItem::create([
                    'invoice_id' => $invoice->id,
                    'product_id' => $product->id,
                    'quantity' => $validated['qty'],
                    'unit_price' => $validated['sales'],
                    'total' => $subtotal,
                    'purchase_price' => $product->purchase_price,
                    'cogs' => $cogs,
                    'profit' => $subtotal - $cogs,
                ]);

                // Decrement stock directly
                if ($product->current_stock >= $validated['qty']) {
                    $product->decrement('current_stock', $validated['qty']);
                }
            }
        }

        // Create Invoice Item if service is selected
        if (!empty($validated['service_id'])) {
            $service = Service::find($validated['service_id']);
            if ($service) {
                $cogs = ($service->cost_price ?? 0) * ($validated['qty'] ?? 1);
                $subtotal = ($validated['qty'] ?? 1) * ($validated['sales'] ?? $service->price);

                InvoiceItem::create([
                    'invoice_id' => $invoice->id,
                    'service_id' => $service->id,
                    'quantity' => $validated['qty'] ?? 1,
                    'unit_price' => $validated['sales'] ?? $service->price,
                    'total' => $subtotal,
                    'purchase_price' => $service->cost_price ?? 0,
                    'cogs' => $cogs,
                    'profit' => $subtotal - $cogs,
                ]);
            }
        }

        // Add invoice_id to validated data
        $validated['invoice_id'] = $invoice->id;

        // Process payment if applicable
        if ($validated['payment'] > 0) {
            $paymentMethod = $validated['payment_method'] ?? 'cash';  // Default to cash

            if ($paymentMethod === 'bank') {
                $bankAccount = BankAccount::findOrFail($validated['bank_account_id']);

                // Add payment amount to bank account
                $balanceBefore = $bankAccount->balance;
                $bankAccount->update(['balance' => $bankAccount->balance + $validated['payment']]);

                // Create transaction record
                Transaction::create([
                    'user_id' => auth()->id(),
                    'date' => $validated['date'] ?? now(),
                    'type' => 'income',
                    'details' => 'Sales Payment: ' . ($validated['invoice'] ?? 'N/A'),
                    'payment_method' => 'bank',
                    'bank_account_id' => $bankAccount->id,
                    'amount' => $validated['payment'],
                    'balance_before' => $balanceBefore,
                    'balance_after' => $bankAccount->balance,
                    'reference' => 'Sales Payment',
                    'notes' => 'Payment received for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                ]);

            } elseif ($paymentMethod === 'digital') {
                $digitalPayment = DigitalPayment::findOrFail($validated['digital_payment_id']);

                // Add payment amount to digital payment account
                $balanceBefore = $digitalPayment->balance;
                $digitalPayment->update(['balance' => $digitalPayment->balance + $validated['payment']]);

                // Create transaction record
                Transaction::create([
                    'user_id' => auth()->id(),
                    'date' => $validated['date'] ?? now(),
                    'type' => 'income',
                    'details' => 'Sales Payment: ' . ($validated['invoice'] ?? 'N/A'),
                    'payment_method' => 'digital',
                    'digital_payment_id' => $digitalPayment->id,
                    'amount' => $validated['payment'],
                    'balance_before' => $balanceBefore,
                    'balance_after' => $digitalPayment->balance,
                    'reference' => 'Sales Payment',
                    'notes' => 'Payment received for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                ]);

            } else {
                // Default to cash
                $cashAccount = BankAccount::where('account_name', 'like', '%Cash%')
                    ->where('user_id', auth()->id())
                    ->first();

                // If no cash account exists, create one
                if (!$cashAccount) {
                    $cashAccount = BankAccount::create([
                        'user_id' => auth()->id(),
                        'account_name' => 'Cash',
                        'account_number' => 'CASH-' . auth()->id(),
                        'bank_name' => 'Cash Account',
                        'branch' => 'Main',
                        'balance' => 0,
                        'is_active' => true
                    ]);
                }

                $balanceBefore = $cashAccount->balance;
                $cashAccount->update(['balance' => $cashAccount->balance + $validated['payment']]);

                Transaction::create([
                    'user_id' => auth()->id(),
                    'date' => $validated['date'] ?? now(),
                    'type' => 'income',
                    'details' => 'Sales Payment (Cash): ' . ($validated['invoice'] ?? 'N/A'),
                    'payment_method' => 'cash',
                    'bank_account_id' => $cashAccount->id,
                    'amount' => $validated['payment'],
                    'balance_before' => $balanceBefore,
                    'balance_after' => $cashAccount->balance,
                    'reference' => 'Sales Payment',
                    'notes' => 'Cash payment received for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                ]);
            }
        }

        // Update quotation status to 'sale' if quotation_id is provided
        if (!empty($validated['quotation_id'])) {
            $quotation = Quotation::find($validated['quotation_id']);
            if ($quotation) {
                $quotation->update(['status' => 'sale']);
            }
        }

        SalesDashboard::create($validated);

        return redirect()->route('sales-dashboard.index')
            ->with('success', 'Sales dashboard record created successfully.');
    }

    public function edit(SalesDashboard $salesDashboard)
    {
        $bankAccounts = BankAccount::orderBy('bank_name', 'asc')->get();
        $digitalPayments = DigitalPayment::orderBy('provider', 'asc')->get();
        $customers = Customer::where('user_id', auth()->id())->orderBy('name', 'asc')->get();
        $quotations = Quotation::orderBy('quotation_number', 'desc')->get();
        $products = Product::orderBy('name', 'asc')->get();
        $services = Service::orderBy('name', 'asc')->get();
        return view('sales-dashboard.edit', compact('salesDashboard', 'bankAccounts', 'digitalPayments', 'customers', 'quotations', 'products', 'services'));
    }

    public function update(Request $request, SalesDashboard $salesDashboard)
    {
        $validated = $request->validate([
            'date' => 'nullable|date',
            'invoice' => 'nullable|string|max:255',
            'customer_id' => 'required|exists:customers,id',
            'quotation_id' => 'nullable|exists:quotations,id',
            'product' => 'nullable|string|max:255',
            'service_id' => 'nullable|exists:services,id',
            'qty' => 'nullable|integer|min:0',
            'sales' => 'nullable|numeric|min:0',
            'total_sales' => 'nullable|numeric',
            'particulars' => 'nullable|string',
            'payment' => 'nullable|numeric|min:0',
            'payment_method' => 'nullable|in:cash,bank,digital',
            'bank_account_id' => 'required_if:payment_method,bank|nullable|exists:bank_accounts,id',
            'digital_payment_id' => 'required_if:payment_method,digital|nullable|exists:digital_payments,id',
            'due' => 'nullable|numeric|min:0',
            'cogs' => 'nullable|numeric|min:0',
            'gross_profit' => 'nullable|numeric',
            'percentage' => 'nullable|numeric',
            'cash_received_by' => 'nullable|string|max:255',
            'segment' => 'nullable|string|max:255',
            'amount' => 'nullable|numeric|min:0',
            'kpi' => 'nullable|numeric|min:0',
            'revenue' => 'nullable|numeric|min:0',
            'achiv' => 'nullable|numeric|min:0',
        ]);

        // Remove fields that shouldn't be stored in database
        unset($validated['total_sales']);

        // Handle payment changes
        $oldPayment = $salesDashboard->payment ?? 0;
        $newPayment = $validated['payment'] ?? 0;
        $paymentDifference = $newPayment - $oldPayment;
        $oldPaymentMethod = $salesDashboard->payment_method ?? 'cash';
        $newPaymentMethod = $validated['payment_method'] ?? 'cash';

        if (abs($paymentDifference) > 0.01) {
            // If payment was previously from an account, reverse that transaction
            if ($oldPayment > 0) {
                if ($oldPaymentMethod === 'bank' && $salesDashboard->bank_account_id) {
                    $bankAccount = BankAccount::find($salesDashboard->bank_account_id);
                    if ($bankAccount) {
                        $bankAccount->update(['balance' => $bankAccount->balance - $oldPayment]);
                    }
                } elseif ($oldPaymentMethod === 'digital' && $salesDashboard->digital_payment_id) {
                    $digitalPayment = DigitalPayment::find($salesDashboard->digital_payment_id);
                    if ($digitalPayment) {
                        $digitalPayment->update(['balance' => $digitalPayment->balance - $oldPayment]);
                    }
                } else {
                    // Default to cash
                    $cashAccount = BankAccount::where('account_name', 'like', '%Cash%')
                        ->where('user_id', auth()->id())
                        ->first();
                    if ($cashAccount) {
                        $cashAccount->update(['balance' => $cashAccount->balance - $oldPayment]);
                    }
                }
            }

            // Add new payment to the new account if specified
            if ($newPayment > 0) {
                if ($newPaymentMethod === 'bank') {
                    $bankAccount = BankAccount::findOrFail($validated['bank_account_id']);
                    $balanceBefore = $bankAccount->balance;
                    $bankAccount->update(['balance' => $bankAccount->balance + $newPayment]);

                    Transaction::create([
                        'user_id' => auth()->id(),
                        'date' => $validated['date'] ?? now(),
                        'type' => 'income',
                        'details' => 'Sales Payment Updated: ' . ($validated['invoice'] ?? 'N/A'),
                        'payment_method' => 'bank',
                        'bank_account_id' => $bankAccount->id,
                        'amount' => $newPayment,
                        'balance_before' => $balanceBefore,
                        'balance_after' => $bankAccount->balance,
                        'reference' => 'Sales Payment Updated',
                        'notes' => 'Payment updated for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                    ]);

                } elseif ($newPaymentMethod === 'digital') {
                    $digitalPayment = DigitalPayment::findOrFail($validated['digital_payment_id']);
                    $balanceBefore = $digitalPayment->balance;
                    $digitalPayment->update(['balance' => $digitalPayment->balance + $newPayment]);

                    Transaction::create([
                        'user_id' => auth()->id(),
                        'date' => $validated['date'] ?? now(),
                        'type' => 'income',
                        'details' => 'Sales Payment Updated: ' . ($validated['invoice'] ?? 'N/A'),
                        'payment_method' => 'digital',
                        'digital_payment_id' => $digitalPayment->id,
                        'amount' => $newPayment,
                        'balance_before' => $balanceBefore,
                        'balance_after' => $digitalPayment->balance,
                        'reference' => 'Sales Payment Updated',
                        'notes' => 'Payment updated for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                    ]);

                } else {
                    // Default to cash
                    $cashAccount = BankAccount::where('account_name', 'like', '%Cash%')
                        ->where('user_id', auth()->id())
                        ->first();

                    // If no cash account exists, create one
                    if (!$cashAccount) {
                        $cashAccount = BankAccount::create([
                            'user_id' => auth()->id(),
                            'account_name' => 'Cash',
                            'account_number' => 'CASH-' . auth()->id(),
                            'bank_name' => 'Cash Account',
                            'branch' => 'Main',
                            'balance' => 0,
                            'is_active' => true
                        ]);
                    }

                    $balanceBefore = $cashAccount->balance;
                    $cashAccount->update(['balance' => $cashAccount->balance + $newPayment]);

                    Transaction::create([
                        'user_id' => auth()->id(),
                        'date' => $validated['date'] ?? now(),
                        'type' => 'income',
                        'details' => 'Sales Payment Updated (Cash): ' . ($validated['invoice'] ?? 'N/A'),
                        'payment_method' => 'cash',
                        'bank_account_id' => $cashAccount->id,
                        'amount' => $newPayment,
                        'balance_before' => $balanceBefore,
                        'balance_after' => $cashAccount->balance,
                        'reference' => 'Sales Payment Updated',
                        'notes' => 'Cash payment updated for sale. Invoice: ' . ($validated['invoice'] ?? 'N/A')
                    ]);
                }
            }
        }

        // Update linked invoice if exists
        if ($salesDashboard->invoice_id) {
            $invoice = Invoice::find($salesDashboard->invoice_id);
            if ($invoice) {
                $totalSales = ($validated['qty'] ?? 0) * ($validated['sales'] ?? 0);
                $due = $totalSales - ($validated['payment'] ?? 0);

                // Determine invoice status
                $status = 'unpaid';
                if ($validated['payment'] > 0 && $validated['payment'] >= $totalSales) {
                    $status = 'paid';
                } elseif ($validated['payment'] > 0 && $validated['payment'] < $totalSales) {
                    $status = 'partial';
                }

                $invoice->update([
                    'customer_id' => $validated['customer_id'],
                    'date' => $validated['date'] ?? now(),
                    'status' => $status,
                    'notes' => $validated['particulars'] ?? null,
                    'total' => $totalSales,
                    'paid' => $validated['payment'] ?? 0,
                    'due' => max(0, $due),
                ]);

                // Update invoice item
                if (!empty($validated['product']) && !empty($validated['qty']) && $validated['qty'] > 0) {
                    // Use case-insensitive search and trim whitespace
                    $productName = trim($validated['product']);
                    $product = Product::whereRaw('LOWER(name) = ?', [strtolower($productName)])->first();

                    // Get old values for stock adjustment
                    $oldQty = $salesDashboard->qty ?? 0;
                    $oldProductName = $salesDashboard->product;

                    // Calculate stock adjustment - restore old stock
                    if ($oldProductName && $oldQty > 0) {
                        $oldProduct = Product::whereRaw('LOWER(name) = ?', [strtolower(trim($oldProductName))])->first();
                        if ($oldProduct) {
                            // Restore old stock
                            $oldProduct->increment('current_stock', $oldQty);
                        }
                    }

                    if ($product) {
                        $cogs = $product->purchase_price * $validated['qty'];
                        $subtotal = $validated['qty'] * $validated['sales'];

                        // Delete old items and create new one
                        $invoice->items()->delete();

                        InvoiceItem::create([
                            'invoice_id' => $invoice->id,
                            'product_id' => $product->id,
                            'quantity' => $validated['qty'],
                            'unit_price' => $validated['sales'],
                            'total' => $subtotal,
                            'purchase_price' => $product->purchase_price,
                            'cogs' => $cogs,
                            'profit' => $subtotal - $cogs,
                        ]);

                        // Decrement new stock
                        if ($product->current_stock >= $validated['qty']) {
                            $product->decrement('current_stock', $validated['qty']);
                        }
                    }
                }

                // Update invoice item for service
                if (!empty($validated['service_id'])) {
                    $service = Service::find($validated['service_id']);
                    if ($service) {
                        $cogs = ($service->cost_price ?? 0) * ($validated['qty'] ?? 1);
                        $subtotal = ($validated['qty'] ?? 1) * ($validated['sales'] ?? $service->price);

                        // Delete old items and create new one
                        $invoice->items()->delete();

                        InvoiceItem::create([
                            'invoice_id' => $invoice->id,
                            'service_id' => $service->id,
                            'quantity' => $validated['qty'] ?? 1,
                            'unit_price' => $validated['sales'] ?? $service->price,
                            'total' => $subtotal,
                            'purchase_price' => $service->cost_price ?? 0,
                            'cogs' => $cogs,
                            'profit' => $subtotal - $cogs,
                        ]);
                    }
                }
            }
        }

        $salesDashboard->update($validated);

        return redirect()->route('sales-dashboard.index')
            ->with('success', 'Sales dashboard record updated successfully.');
    }

    public function destroy(SalesDashboard $salesDashboard)
    {
        // Restore stock before deletion if product was associated
        if (!empty($salesDashboard->product) && !empty($salesDashboard->qty)) {
            $product = Product::whereRaw('LOWER(name) = ?', [strtolower(trim($salesDashboard->product))])->first();
            if ($product) {
                $product->increment('current_stock', $salesDashboard->qty);
            }
        }

        // Delete linked invoice if exists
        if ($salesDashboard->invoice_id) {
            $invoice = Invoice::find($salesDashboard->invoice_id);
            if ($invoice) {
                $invoice->delete();
            }
        }

        $salesDashboard->delete();

        return redirect()->route('sales-dashboard.index')
            ->with('success', 'Sales dashboard record deleted successfully.');
    }
}
