<?php

namespace App\Http\Controllers\Admin\Accounting;

use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Accounting\Journal;
use App\Models\Branch;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class NetProfitAndLossController extends Controller
{

    public function getJournal(Request $request){
        $data = Journal::select(
            DB::raw("SUM(journals.debit-journals.credit) AS total"),
            'journals.chart_of_acc_id',
        )
        ->leftjoin('chart_of_accounts','chart_of_accounts.id','journals.chart_of_acc_id')
        ->where(function($query) use($request){
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            if(!$request->journal_date==[])
            {
                $query->whereBetween(DB::raw("DATE_FORMAT(journal_date, '%Y-%m-%d')"), $request->journal_date);
            }
        })
        ->groupBy('journals.chart_of_acc_id')
        ->orderBy('chart_of_accounts.chart_code', 'ASC');
        return $data;
    }

    public function getProfitLoss(Request $request){
        $incomes = $this->getJournal($request)
            ->whereHas('chartOfAcc',function($query){
                $query->whereHas('typeAccDetails',function($sub_query){
                    $sub_query->where('type_of_acc_id',40);
                });
            })
            ->get()
            ->filter(function($value) {
                return $value->total != 0;
            })
            ->values()
            ->map(function($value){
                return [
                    'total' => -$value->total,
                    'chart_code' => $value->chartOfAcc->chart_code??'',
                    'chart_name' => ($value->chartOfAcc->chart_name??'').' '.($value->chartOfAcc->desc??''),
                ];
            });

        $generalExep = $this->getJournal($request)
            ->whereHas('chartOfAcc',function($query){
                $query->whereHas('typeAccDetails',function($sub_query){
                    $sub_query->where('type_of_acc_id',50);
                });
            })->get()
            ->filter(function($value) {
                return $value->total != 0;
            })
            ->values()
            ->map(function($value){
                return [
                    'total' => $value->total,
                    'chart_code' => $value->chartOfAcc->chart_code??'',
                    'chart_name' => ($value->chartOfAcc->chart_name??'').' '.($value->chartOfAcc->desc??''),
                ];
            });

        $net_profit = 0;
        // $total_revenue = 0;
        $total_income  = 0;
        $total_expense_cost = 0;
        $total_glexpense = 0;

        foreach ($incomes as  $income) {
            $total_income += $income["total"];
        }
        foreach ($generalExep as  $expense) {
            $total_glexpense += $expense["total"];
        }
        //Net Income
        $net_profit = $total_income - $total_expense_cost - $total_glexpense;
        

        $branch = Branch::find(Auth::user()->branch_id);
        $branch_name = Auth::user()->branch_id==-1?'Head Quarter':$branch->branch_code.'-'.$branch->name_en;
        
        $data = [
            'incomes'         => $incomes,
            'total_income'    => $total_income,
            'glexspenses'     => $generalExep,
            'total_glexpense' => $total_glexpense,
            'net_profit'      => $net_profit,
            'total_cost_ogs'  => $total_expense_cost,
            'current_month'   => date('F'),
            'current_year'    => date('Y'),
            'branch_name'     => $branch_name,
        ];
        return $data;
    }


    public function getProfitAndLossStatementByMonth(Request $request)
    {
        $year = $request->input('year', date('Y'));
        $branch_id = $request->branch_id;
        
        $startDate = Carbon::createFromDate($year, 1, 1)->startOfYear();
        $endDate = Carbon::createFromDate($year, 12, 31)->endOfYear();

        $monthlyData = $this->getMonthlyData($startDate, $endDate, $branch_id);

        $branchs = Branch::find($branch_id);
        $branch_name = !empty($branch_id)?$branchs->branch_code.'-'.$branchs->name_en:'Head Quarter';

        return response()->json([
            'monthlyData' => $monthlyData,
            'year'        => $year,
            'branch'      => $branch_id,
            'branch_name' => $branch_name,
        ]);
    }

    private function getMonthlyData($startDate, $endDate, $branch)
    {
        $months = [];
        $currentDate = $startDate->copy();
        
        while ($currentDate <= $endDate) {
            $monthKey = $currentDate->format('M');
            $months[$monthKey] = [
                'income'  => 0,
                'expense' => 0,
                'profit'  => 0
            ];
            $currentDate->addMonth();
        }
        
        // Get income data
        $incomeQuery = Journal::leftjoin('chart_of_accounts', 'chart_of_accounts.id', 'journals.chart_of_acc_id')
            ->leftjoin('type_of_acc_details','type_of_acc_details.id', 'chart_of_accounts.type_of_acc_detail_id')
            ->where('type_of_acc_details.type_of_acc_id', 40) // Income accounts
            ->whereBetween('journals.journal_date', [$startDate, $endDate])
            ->where(function($query){
                $query->where('journals.currency_id',Helper::byCurrency());
            })
            ->select(
                DB::raw('MONTH(journals.journal_date) as month'),
                DB::raw('SUM(journals.credit - journals.debit) as total')
            )   
            ->groupBy(DB::raw('MONTH(journals.journal_date)'))
            ->orderby('journals.journal_date','ASC');
            
        if (!empty($branch)) {
            $incomeQuery->where('journals.branch_id',$branch);
        }
        
        $incomeData = $incomeQuery->get();
        
        // Get expense data
        $expenseQuery = Journal::leftjoin('chart_of_accounts', 'chart_of_accounts.id', 'journals.chart_of_acc_id')
            ->leftjoin('type_of_acc_details','type_of_acc_details.id', 'chart_of_accounts.type_of_acc_detail_id')
            ->where('type_of_acc_details.type_of_acc_id', 50) // Expense accounts
            ->whereBetween('journals.journal_date', [$startDate, $endDate])
            ->where(function($query){
                $query->where('journals.currency_id',Helper::byCurrency());
            })
            ->select(
                DB::raw('MONTH(journals.journal_date) as month'),
                DB::raw('SUM(journals.debit - journals.credit) as total')
            )
            ->groupBy(DB::raw('MONTH(journals.journal_date)'))
            ->orderby('journals.journal_date','ASC');
            
        if (!empty($branch)) {
            $expenseQuery->where('journals.branch_id',$branch);
        }
        
        $expenseData = $expenseQuery->get();
        
        // Process income data
        foreach ($incomeData as $item) {
            $monthName = Carbon::create()->month($item->month)->format('M');
            $months[$monthName]['income'] = abs($item->total); // Income is typically negative in journal entries
        }
        
        // Process expense data
        foreach ($expenseData as $item) {
            $monthName = Carbon::create()->month($item->month)->format('M');
            $months[$monthName]['expense'] = $item->total;
            // $months[$monthName]['profit']  = $months[$monthName]['income'] - $item->total;
        }

        $months = array_map(function($monthData) {
            $monthData['profit'] = ($monthData['income'] ?? 0) - ($monthData['expense'] ?? 0);
            return $monthData;
        }, $months);

        return $months;
    }

    public function getIncomeStatementByMonth(Request $request)
    {

    }
}