<?php

namespace App\Services;

use App\Models\LedgerEntry;
use App\Models\ChartOfAccount;
use App\Models\Payment;
use App\Models\Wage;
use Carbon\Carbon;

class LedgerService
{
    /**
     * Create a ledger entry from a payment (income)
     */
    public function recordPayment(Payment $payment): LedgerEntry
    {
        $incomeAccount = ChartOfAccount::where('type', 'income')
            ->where('category', 'revenue')
            ->first();

        return LedgerEntry::create([
            'entry_date' => $payment->payment_date,
            'chart_of_account_id' => $incomeAccount?->id,
            'currency_id' => $payment->invoice->currency_id,
            'amount' => $payment->amount,
            'description' => "Payment received - {$payment->payment_number}",
            'source_type' => 'payment',
            'source_id' => $payment->id,
            'created_by' => $payment->received_by,
        ]);
    }

    /**
     * Create a ledger entry for a wage (expense)
     */
    public function recordWage(Wage $wage): LedgerEntry
    {
        $expenseAccount = ChartOfAccount::where('type', 'expense')
            ->where('category', 'operating_expense')
            ->first();

        return LedgerEntry::create([
            'entry_date' => $wage->period_end,
            'chart_of_account_id' => $expenseAccount?->id,
            'currency_id' => $wage->currency_id,
            'amount' => -$wage->total_amount, // negative for expense
            'description' => "Wage payment - {$wage->user->name} ({$wage->period_start} to {$wage->period_end})",
            'source_type' => 'wage',
            'source_id' => $wage->id,
            'created_by' => $wage->created_by,
        ]);
    }

    /**
     * Get income summary for a period
     */
    public function getIncomeSummary(string $startDate, string $endDate): array
    {
        $entries = LedgerEntry::income()
            ->whereBetween('entry_date', [$startDate, $endDate])
            ->with('chartOfAccount')
            ->get();

        $byAccount = $entries->groupBy('chart_of_account_id')
            ->map(fn($group) => [
                'account_name' => $group->first()->chartOfAccount->name,
                'total' => $group->sum('amount'),
            ])
            ->values();

        return [
            'total_income' => $entries->sum('amount'),
            'by_account' => $byAccount,
        ];
    }

    /**
     * Get expense summary for a period
     */
    public function getExpenseSummary(string $startDate, string $endDate): array
    {
        $entries = LedgerEntry::expense()
            ->whereBetween('entry_date', [$startDate, $endDate])
            ->with('chartOfAccount')
            ->get();

        $byAccount = $entries->groupBy('chart_of_account_id')
            ->map(fn($group) => [
                'account_name' => $group->first()->chartOfAccount->name,
                'total' => abs($group->sum('amount')),
            ])
            ->values();

        return [
            'total_expenses' => abs($entries->sum('amount')),
            'by_account' => $byAccount,
        ];
    }

    /**
     * Get net profit for a period
     */
    public function getNetProfit(string $startDate, string $endDate): float
    {
        $income = $this->getIncomeSummary($startDate, $endDate)['total_income'];
        $expenses = $this->getExpenseSummary($startDate, $endDate)['total_expenses'];
        
        return $income - $expenses;
    }

    /**
     * Get full P&L report
     */
    public function getProfitLossReport(string $startDate, string $endDate): array
    {
        $income = $this->getIncomeSummary($startDate, $endDate);
        $expenses = $this->getExpenseSummary($startDate, $endDate);
        
        return [
            'period' => [
                'start' => $startDate,
                'end' => $endDate,
            ],
            'income' => $income,
            'expenses' => $expenses,
            'net_profit' => $income['total_income'] - $expenses['total_expenses'],
        ];
    }
}
