<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Support\DocumentNumberHelper;
use App\Models\GeneralLedgerSubaccount;

class ClientInvoiceController extends Controller
{
    public function clientInvoice()
    {
        $clients = \App\Models\Client::all();
        $accounts = GeneralLedgerSubaccount::query()
            ->with('parent')
            ->orderBy('parent_id')
            ->orderBy('sub_code')
            ->get();
        $glAccounts = $accounts;
        $taxes = \App\Models\Tax::all();
        $currencies = \App\Models\Currency::all();
        $clientTransactions = \App\Models\ClientInvoice::with('client')->get();
        $nextInvoiceNumber = DocumentNumberHelper::nextClientInvoiceNumber();

        return view('modules.processing.client-invoice', compact('clients', 'accounts', 'glAccounts', 'taxes', 'currencies', 'clientTransactions', 'nextInvoiceNumber'));
    }

public function storeClientInvoice(Request $request)
    {
        $validated = $request->validate([
            'client_id' => 'required|integer|exists:clients,id',
            'invoice_number' => 'nullable|string|max:255',
            'invoice_date' => 'required|date',
            'due_date' => 'nullable|date',
            'amount' => 'required|numeric|min:0',
            'description' => 'nullable|string',
            'account' => 'nullable|string|max:255',
            'narration' => 'nullable|string',
            'reference' => 'nullable|string|max:255',
            'gl_account' => 'nullable|string|max:255',
            'gl_items' => 'nullable|array',
            'gl_items.*.gl_account_id' => 'nullable|integer|exists:general_ledger_subaccounts,id',
            'gl_items.*.gl_account_code' => 'nullable|string|max:255',
            'gl_items.*.gl_account' => 'nullable|string|max:255',
            'gl_items.*.amount' => 'nullable|numeric|min:0',
            'gl_items.*.line_type' => 'nullable|string|max:50',
            'gl_items.*.description' => 'nullable|string|max:255',
            'tax_id' => 'nullable|string|exists:taxes,tax_id',
            'discount' => 'nullable|numeric|min:0|max:100',
            'price' => 'required|numeric|min:0',
            'quantity' => 'nullable|integer|min:1',
            'currency_id' => 'nullable|integer|exists:currencies,id',
            'operation_cost' => 'nullable|boolean',
            'tax_amount' => 'nullable|numeric|min:0',
            'case_reference' => 'nullable|string|max:255',
            'responsible_lawyer' => 'nullable|string|max:255',
            'disbursements' => 'nullable|numeric|min:0',
            'total' => 'nullable|numeric|min:0',
        ]);


        if (empty($validated['invoice_number'])) {
            $validated['invoice_number'] = DocumentNumberHelper::nextClientInvoiceNumber();
        }

        $validated['total'] = ($validated['amount'] ?? 0) + ($validated['tax_amount'] ?? 0) + ($validated['disbursements'] ?? 0);

        $invoice = \App\Models\ClientInvoice::create($validated);

        $glLines = [];
        foreach (($validated['gl_items'] ?? []) as $item) {
            $amount = (float) ($item['amount'] ?? 0);
            if ($amount <= 0) {
                continue;
            }
            $glLines[] = [
                'gl_account_id' => $item['gl_account_id'] ?? null,
                'gl_account_code' => $item['gl_account_code'] ?? ($item['gl_account'] ?? null),
                'amount' => $amount,
                'line_type' => $item['line_type'] ?? null,
                'description' => $item['description'] ?? null,
                'created_by' => auth()->id(),
                'updated_by' => auth()->id(),
            ];
        }
        if (empty($glLines) && !empty($validated['gl_account'])) {
            $glLines[] = [
                'gl_account_code' => $validated['gl_account'],
                'amount' => (float) ($validated['total'] ?? 0),
                'line_type' => 'invoice',
                'description' => $validated['description'] ?? null,
                'created_by' => auth()->id(),
                'updated_by' => auth()->id(),
            ];
        }
        if (!empty($glLines)) {
            $invoice->glAccounts()->createMany($glLines);
        }

        return redirect()->back()->with('success', 'Client invoice created successfully.');
    }

    public function updateClientInvoice(Request $request, $id)
    {
        $invoice = \App\Models\ClientInvoice::findOrFail($id);

        $validated = $request->validate([
            'client_id' => 'required|integer|exists:clients,id',
            'invoice_number' => 'required|string|max:255',
            'invoice_date' => 'required|date',
            'due_date' => 'nullable|date',
            'amount' => 'required|numeric|min:0',
            'description' => 'nullable|string',
            'account' => 'nullable|string|max:255',
            'narration' => 'nullable|string',
            'reference' => 'nullable|string|max:255',
            'gl_account' => 'nullable|string|max:255',
            'gl_items' => 'nullable|array',
            'gl_items.*.gl_account_id' => 'nullable|integer|exists:general_ledger_subaccounts,id',
            'gl_items.*.gl_account_code' => 'nullable|string|max:255',
            'gl_items.*.gl_account' => 'nullable|string|max:255',
            'gl_items.*.amount' => 'nullable|numeric|min:0',
            'gl_items.*.line_type' => 'nullable|string|max:50',
            'gl_items.*.description' => 'nullable|string|max:255',
            'tax_id' => 'nullable|integer|exists:taxes,id',
            'discount' => 'nullable|numeric|min:0|max:100',
            'price' => 'required|numeric|min:0',
            'quantity' => 'nullable|integer|min:1',
            'currency_id' => 'nullable|integer|exists:currencies,id',
            'operation_cost' => 'nullable|boolean',
            'tax_amount' => 'nullable|numeric|min:0',
            'case_reference' => 'nullable|string|max:255',
            'responsible_lawyer' => 'nullable|string|max:255',
            'disbursements' => 'nullable|numeric|min:0',
            'total' => 'nullable|numeric|min:0',
        ]);

        $validated['total'] = ($validated['amount'] ?? 0) + ($validated['tax_amount'] ?? 0) + ($validated['disbursements'] ?? 0);

        $invoice->update($validated);

        $glLines = [];
        foreach (($validated['gl_items'] ?? []) as $item) {
            $amount = (float) ($item['amount'] ?? 0);
            if ($amount <= 0) {
                continue;
            }
            $glLines[] = [
                'gl_account_id' => $item['gl_account_id'] ?? null,
                'gl_account_code' => $item['gl_account_code'] ?? ($item['gl_account'] ?? null),
                'amount' => $amount,
                'line_type' => $item['line_type'] ?? null,
                'description' => $item['description'] ?? null,
                'created_by' => auth()->id(),
                'updated_by' => auth()->id(),
            ];
        }
        if (empty($glLines) && !empty($validated['gl_account'])) {
            $glLines[] = [
                'gl_account_code' => $validated['gl_account'],
                'amount' => (float) ($validated['total'] ?? 0),
                'line_type' => 'invoice',
                'description' => $validated['description'] ?? null,
                'created_by' => auth()->id(),
                'updated_by' => auth()->id(),
            ];
        }

        $invoice->glAccounts()->delete();
        if (!empty($glLines)) {
            $invoice->glAccounts()->createMany($glLines);
        }

        return redirect()->back()->with('success', 'Client invoice updated successfully.');
    }

    public function destroyClientInvoice($id)
    {
        $invoice = \App\Models\ClientInvoice::findOrFail($id);
        $invoice->delete();

        return redirect()->back()->with('success', 'Client invoice deleted successfully.');
    }

    public function processClientInvoice($invoice = null)
    {
        // Process client invoice(s)
        if ($invoice) {
            $invoice = \App\Models\ClientInvoice::findOrFail($invoice);
            $invoice->update(['status' => 'Processed']);
            $message = 'Client invoice processed successfully.';
        } else {
            $invoices = \App\Models\ClientInvoice::where('status', '!=', 'Processed')->get();
            foreach ($invoices as $inv) {
                $inv->update(['status' => 'Processed']);
            }
            $message = 'All client invoices processed successfully.';
        }

        return redirect()->back()->with('success', $message);
    }
}
