<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Invoice;
use App\Models\Customer;
use App\Models\CustomerContact;
use App\Models\Quote;
use Illuminate\Http\Request;
use App\Models\Item;
use App\Models\Account;



class InvoiceController extends Controller
{
    public function checkInvoiceNumber(Request $request)
    {
        $exists = \App\Models\Invoice::where('invoice_number', $request->invoice_number)->exists();

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


    public function show(Invoice $invoice)
    {
        return view('admin.invoices.show', compact('invoice'));
    }

    public function index()
    {
        $invoices = Invoice::with('customer', 'customerContact', 'quote')->get();
        return view('admin.invoices.index', compact('invoices'));
    }

    public function create()
    {
        $customers = Customer::all();
        $customerContacts = CustomerContact::all();
        $quotes = Quote::all();
        $items = Item::all();

        return view('admin.invoices.create', compact('customers', 'customerContacts', 'quotes', 'items'));
    }

    public function store(Request $request)
    {
        // Validate request data
        $request->validate([
            'invoice_number' => 'required|unique:invoices',
            'invoice_date' => 'required|date',
            'customer_id' => 'required|exists:customers,id',
            'subtotal' => 'required|numeric',
            'discount' => 'nullable|numeric',
            'taxable_total' => 'nullable|numeric',
            'tax_total' => 'nullable|numeric',
            'total' => 'nullable|numeric',
            'items' => 'required|array',
            'items.*.item_code' => 'required|exists:items,code',
            'items.*.quantity' => 'required|numeric',
            'items.*.unit_price' => 'required|numeric',
            'items.*.duration' => 'required|numeric',
        ]);

        // Calculate taxable total, tax total, and total based on line items
        $subtotal = 0;
        $taxableTotal = 0;
        $taxTotal = 0;

        foreach ($request->input('items') as $item) {
            $subtotal += $item['quantity'] * $item['unit_price'] * $item['duration'];
            // Assuming tax is calculated based on some predefined rate or logic
            $taxTotal += $item['tax'] ?? 0; // If tax is passed, use it, otherwise default to 0
        }

        $taxableTotal = $subtotal - ($request->input('discount') ?? 0);
        $total = $taxableTotal + $taxTotal;

        // Create invoice
        $invoice = Invoice::create([
            'invoice_number' => $request->invoice_number,
            'invoice_date' => $request->invoice_date,
            'customer_id' => $request->customer_id,
            'customer_contact_id' => $request->customer_contact_id,
            'quote_id' => $request->quote_id,
            'project_site' => $request->project_site,
            'rental_start' => $request->rental_start,
            'rental_end' => $request->rental_end,
            'subtotal' => $subtotal,
            'discount' => $request->discount ?? 0,
            'taxable_total' => $taxableTotal,
            'tax_total' => $taxTotal,
            'total' => $total,
            'status' => 'created', // Set default status
        ]);

        // Store invoice items
        foreach ($request->input('items') as $item) {
            $quantity = $item['quantity'];
            $unitPrice = $item['unit_price'];
            $duration = $item['duration'];
            $tax = $item['tax'] ?? 0;
            $lineTotal = $quantity * $unitPrice * $duration;
            $lineTotalWithTax = $lineTotal + $tax;

            $invoice->items()->create([
                'item_code' => $item['item_code'],
                'description' => $item['description'],
                'quantity' => $quantity,
                'unit_price' => $unitPrice,
                'duration' => $duration,
                'duration_unit' => $item['duration_unit'],
                'line_total' => $lineTotal,
                'tax' => $tax,
                'line_total_with_tax' => $lineTotalWithTax,
            ]);
        }


        return redirect()->route('invoices.index')->with('success', 'Invoice created successfully.');
    }


    public function edit(Invoice $invoice)
    {
        $customers = Customer::all();
        $contacts = CustomerContact::all();
        $quotes = Quote::all();
        return view('admin.invoices.edit', compact('invoice', 'customers', 'contacts', 'quotes'));
    }


    public function update(Request $request, Invoice $invoice)
    {
        $request->validate([
            'invoice_number'     => 'required|string|unique:invoices,invoice_number,' . $invoice->id,
            'invoice_date'       => 'required|date',
            'subject'            => 'required|string|max:255',
            'project_site'       => 'nullable|string|max:255',
            'rental_start'       => 'nullable|date',
            'rental_end'         => 'nullable|date|after_or_equal:rental_start',
            'customer_id'        => 'required|exists:customers,id',
            'quote_id'           => 'nullable|exists:quotes,id',
            'subtotal'           => 'nullable|numeric',
            'discount'           => 'nullable|numeric',
            'taxable_total'      => 'nullable|numeric',
            'tax_total'          => 'nullable|numeric',
            'total'              => 'required|numeric',
            'status'             => 'required|in:created,submitted,partially_paid,paid,cancelled',
        ]);

        $invoice->update([
            'invoice_number'     => $request->invoice_number,
            'invoice_date'       => $request->invoice_date,
            'subject'            => $request->subject,
            'project_site'       => $request->project_site,
            'rental_start'       => $request->rental_start,
            'rental_end'         => $request->rental_end,
            'customer_id'        => $request->customer_id,
            'quote_id'           => $request->quote_id,
            'subtotal'           => $request->subtotal ?? 0,
            'discount'           => $request->discount ?? 0,
            'taxable_total'      => $request->taxable_total ?? 0,
            'tax_total'          => $request->tax_total ?? 0,
            'total'              => $request->total,
            'status'             => $request->status,
        ]);

        return redirect()->route('invoices.index')->with('success', 'Invoice updated successfully.');
    }



    public function destroy(Invoice $invoice)
    {
        $invoice->delete();
        return redirect()->route('invoices.index')->with('success', 'Invoice deleted.');
    }

    public function createManual()
    {

        $customers = Customer::all();
        $quotes = Quote::all();
        $lastNumber = Invoice::max('invoice_number');
        $nextInvoiceNumber = $lastNumber ? (int)$lastNumber + 1 : 1001;

        return view('admin.invoices.add_invoice', compact('customers', 'quotes', 'nextInvoiceNumber'));
    }

   public function storeManual(Request $request)
    {
        $request->validate([
            'invoice_number'   => 'required|unique:invoices,invoice_number',
            'invoice_date'     => 'required|date',
            'subject'          => 'required|string',
            'project_site'     => 'nullable|string|max:255',
            'rental_start'     => 'nullable|date',
            'rental_end'       => 'nullable|date|after_or_equal:rental_start',
            'customer_id'      => 'required|exists:customers,id',
            'quote_id'         => 'nullable|exists:quotes,id',
            'subtotal'         => 'nullable|numeric',
            'discount'         => 'nullable|numeric',
            'taxable_total'    => 'nullable|numeric',
            'tax_total'        => 'nullable|numeric',
            'total'            => 'required|numeric',
            'status'           => 'required|in:created,submitted,partially_paid,paid,cancelled',

        ]);

        Invoice::create([
            'invoice_number'   => $request->invoice_number,
            'invoice_date'     => $request->invoice_date,
            'subject'          => $request->subject,
            'project_site'     => $request->project_site,
            'rental_start'     => $request->rental_start,
            'rental_end'       => $request->rental_end,
            'customer_id'      => $request->customer_id,
            'quote_id'         => $request->quote_id,
            'subtotal'         => $request->subtotal ?? 0,
            'discount'         => $request->discount ?? 0,
            'taxable_total'    => $request->taxable_total ?? 0,
            'tax_total'        => $request->tax_total ?? 0,
            'total'            => $request->total,
            'status'           => $request->status,
        ]);

        return redirect()->route('invoices.index')->with('success', 'Manual invoice added.');
    }

    public function statusForm(Invoice $invoice)
    {
        return view('admin.invoices.status', compact('invoice'));
    }

    public function updateStatus(Request $request, Invoice $invoice)
    {
        try {
            $statuses = ['created', 'submitted', 'partially_paid', 'paid', 'cancelled'];
            $currentIndex = array_search($invoice->status, $statuses);
            $newStatus = $request->status;
            $newIndex = array_search($newStatus, $statuses);

            if ($newIndex < $currentIndex) {
                return response()->json(['error' => 'Cannot revert to a previous status.'], 422);
            }

            $invoice->status = $newStatus;
            $invoice->save();

            if ($newStatus === 'cancelled') {
                return response()->json(['redirect' => route('invoices.index')]);
            }

            // Redirect to journal entry form
            return response()->json([
                'redirect' => route('admin.journals.createFromInvoice', $invoice->id)
            ]);
        } catch (\Throwable $e) {
            \Log::error('Invoice status update failed: ' . $e->getMessage());
            return response()->json(['error' => 'Status update failed: ' . $e->getMessage()], 500);
        }
    }




    public function statusModal(Invoice $invoice)
    {
        return view('admin.invoices.partials.status_modal_form', compact('invoice'));
    }

    public function receivePayment(Invoice $invoice)
    {
        $invoice->load(['customer', 'journalEntries.transactions.account']);

        $cashAccounts = Account::whereIn('code', [1001, 1002, 1003])->get();
        $receivableAccount = Account::where('code', 1100)->firstOrFail();

        return view('admin.invoices.receive_payment', compact(
            'invoice', 'cashAccounts', 'receivableAccount'
        ));
    }

    public function storePayment(Request $request, Invoice $invoice)
    {
        $request->validate([
            'date' => 'required|date',
            'description' => 'required|string',
            'transactions' => 'required|array|min:1',
            'transactions.*.debit_account_id' => 'required|exists:accounts,id',
            'transactions.*.debit' => 'required|numeric|min:0.01',
            'credit_account_id' => 'required|exists:accounts,id',
            'credit_amount' => 'required|numeric|min:0.01',
        ]);

        $totalDebit = collect($request->transactions)->sum('debit');
        $creditAmount = $request->credit_amount;

        // ✅ Match total debit with credit
        if (abs($totalDebit - $creditAmount) > 0.01) {
            return back()->withErrors(['credit_amount' => 'Credit must equal total debit amount.'])->withInput();
        }

        // ✅ Prevent overpayment
        $remaining = $invoice->total - $invoice->amount_paid - $invoice->discount_given;
        if ($creditAmount > $remaining) {
            return back()->withErrors(['credit_amount' => 'Payment exceeds remaining invoice balance.'])->withInput();
        }

        // ✅ Create journal entry
        $journal = \App\Models\JournalEntry::create([
            'user_id'     => auth()->id(),
            'date'        => $request->date,
            'description' => $request->description,
            'inv_id'      => $invoice->invoice_number,
            'inv_date'    => $invoice->invoice_date,
            'customer_id' => $invoice->customer_id,
        ]);

        // 🔁 Debit entries
        foreach ($request->transactions as $tx) {
            $journal->transactions()->create([
                'user_id'    => auth()->id(),
                'account_id' => $tx['debit_account_id'],
                'debit'      => $tx['debit'],
                'credit'     => 0,
                'description'=> 'Payment Received',
            ]);
        }

        // ➕ Credit entry
        $journal->transactions()->create([
            'user_id'    => auth()->id(),
            'account_id' => $request->credit_account_id,
            'debit'      => 0,
            'credit'     => $creditAmount,
            'description'=> 'Payment Received',
        ]);

        // 🧾 Update invoice
        $invoice->amount_paid += $creditAmount;
        $invoice->is_recorded_in_journal = true;

        if ($invoice->amount_paid >= $invoice->total - $invoice->discount_given) {
            $invoice->status = 'paid';
        } else {
            $invoice->status = 'partially_paid';
        }

        $invoice->save();

        return redirect()->route('invoices.index')->with('success', 'Payment recorded successfully.');
    }






}
