<?php

namespace App\Http\Controllers\Admin\Accounting;

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

class IncomeController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:Income List', ['only' => ['index']]);
        $this->middleware('permission:Income Create', ['only' => ['store','create']]);
        $this->middleware('permission:Income Edit', ['only' => ['store','create']]);
        $this->middleware('permission:Income Delete', ['only' => ['destroy']]);
    }
    public function getIncome(Request $request){
        $data = Income::where(function($query) use ($request){
            $query->whereIn('branch_id',Helper::byBranch());
            $query->where('currency_id',Helper::byCurrency());
            if($request->income_list == 1){
                $query->search($request->search_text);
            } else {
                $chart_of_acc_id = $request->chart_of_acc_id;
                if($chart_of_acc_id!=null){
                    $query->where('incomes.chart_of_acc_id',$chart_of_acc_id);
                }
                $query->where('incomes.invoice_number', 'LIKE',isset($request->invoice_number)? $request->invoice_number:NULL);
                if($request->income_date)
                {
                    $query->whereBetween(DB::raw("DATE_FORMAT(income_date, '%Y-%m-%d')"), $request->income_date ?? CustomDateFilter::thisMonth());
                }
            }
        })
        ->orderBy('incomes.id','DESC')
        ->orderBy('incomes.income_date','DESC')
        ->groupby('incomes.parent_id');
        return $data;
    }

    public function index(Request $request)
    {
        $per_page = $request->per_page == null?25:$request->per_page;
        $funGetIncome = $this->getIncome($request)->paginate($per_page);

        $page =  json_encode($funGetIncome);
        $paginate = json_decode($page);
        $data = $funGetIncome->map(function($value){
            return [
                'id'              => $value->id,
                'parent_id'       => $value->parent_id,
                'invoice_number'  => $value->invoice_number,
                'income_date'     => $value->income_date,
                'desc'            => $value->desc,
                'debit'           => $value->debit,
                'credit'          => $value->credit,
                'chart_of_acc_id' => Income::where('parent_id',$value->parent_id)->where('debit',0)->max('chart_of_acc_id'),
                'payment_model_id'=> $value->payment_model_id,
                'chart_code'      => $value->chartOfAcc->chart_code,
                'chart_name'      => $value->chartOfAcc->chart_name,
                'created_by'      => $value->createdBy->name,
                'sub_income'      => Income::where('incomes.parent_id',$value->parent_id)->get()->map(function($val){
                    return [
                        'id'         => $val->id,
                        'debit'      => $val->debit,
                        'credit'     => $val->credit,
                        'parent_id'  => $val->parent_id,
                        'chart_code' => $val->chartOfAcc->chart_code,
                        'chart_name' => $val->chartOfAcc->chart_name,
                    ];
                }),
                'sum_debit' => Income::where('incomes.parent_id',$value->parent_id)->sum('incomes.debit'),
                'sum_credit'=> Income::where('incomes.parent_id',$value->parent_id)->sum('incomes.credit'),
            ];
        });

        $res = [
            'data'  => $data,
            'links'    => [
                'first'=> $paginate->first_page_url,
                'last' => $paginate->last_page_url,
                'next' => $paginate->next_page_url,
                'prev' => $paginate->prev_page_url,
            ],
            'meta'   => [
                'current_page'  => $funGetIncome->currentPage(),
                'last_page'     => $funGetIncome->lastPage(),
                'per_page'      => $funGetIncome->perPage(),
                'total'         => $funGetIncome->total(),
                'to'            => $paginate->to,
            ],
        ];
        return response()->json($res, 200);
    }

    public function store(Request $request)
    {
        $request->validate([
            'desc'                 => 'required',
            'invoice_number'       => 'required|max:255',
            'income_date'         => 'required',
            'income_rows.*.credit'=> 'required',
            'income_rows.*.debit' => 'required',
            'income_rows.*.chart_of_acc_id' => 'required',
        ]);
        DB::beginTransaction();
        try {
            $income = $request->income_rows;
            $income_parent_id = Helper::findParentIdIncome();
            $journal_parent_id = Helper::findParentId();
            foreach($income as $value){

                $income_debit = new Income();
                $income_debit->parent_id  = $income_parent_id;
                $income_debit->branch_id  = Auth::user()->branch_id;
                $income_debit->currency_id  = Auth::user()->currency_id;
                $income_debit->debit      = $value['debit'];
                $income_debit->desc       = $request->desc;
                $income_debit->created_by = Auth::user()->id;
                $income_debit->invoice_number = $request->invoice_number;
                $income_debit->chart_of_acc_id = $value['chart_of_acc_id'];
                $income_debit->income_date  = $request->income_date;
                $income_debit->save();

                $journal_debit = new Journal();
                $journal_debit->parent_id  = $journal_parent_id;
                $journal_debit->branch_id  = Auth::user()->branch_id;
                $journal_debit->currency_id  = Auth::user()->currency_id;
                $journal_debit->debit      = $value['debit'];
                $journal_debit->desc       = $request->desc;
                $journal_debit->created_by = Auth::user()->id;
                $journal_debit->invoice_number = $request->invoice_number;
                $journal_debit->chart_of_acc_id = $value['chart_of_acc_id'];
                $journal_debit->journal_date  = $request->income_date;
                $journal_debit->payment_model_type  = get_class($income_debit);
                $journal_debit->payment_model_id  = $income_debit->id;
                $journal_debit->save();

                $detail_credit = new Income();
                $detail_credit->parent_id  = $income_parent_id;
                $detail_credit->branch_id  = Auth::user()->branch_id;
                $detail_credit->currency_id  = Auth::user()->currency_id;
                $detail_credit->credit      = $value['debit'];
                $detail_credit->desc       = $request->desc;
                $detail_credit->created_by = Auth::user()->id;
                $detail_credit->invoice_number = $request->invoice_number;
                $detail_credit->chart_of_acc_id = $request->chart_of_acc_id;
                $detail_credit->income_date  = $request->income_date;
                $detail_credit->save();

                $journal_detail_credit = new Journal();
                $journal_detail_credit->parent_id  = $journal_parent_id;
                $journal_detail_credit->branch_id  = Auth::user()->branch_id;
                $journal_detail_credit->currency_id  = Auth::user()->currency_id;
                $journal_detail_credit->credit      = $value['debit'];
                $journal_detail_credit->desc       = $request->desc;
                $journal_detail_credit->created_by = Auth::user()->id;
                $journal_detail_credit->invoice_number = $request->invoice_number;
                $journal_detail_credit->chart_of_acc_id = $request->chart_of_acc_id;
                $journal_detail_credit->journal_date  = $request->income_date;
                $journal_detail_credit->payment_model_type  = get_class($detail_credit);
                $journal_detail_credit->payment_model_id  = $detail_credit->id;
                $journal_detail_credit->save();
            }
            DB::commit();
            return response()->json(["message" => "$request->invoice_number successfully created."], 200);
        } catch (\Exception $e) {
            DB::rollback();
            return response()->json(["message" => "Something wrong, Please check it !"], 200);
        }
    }

    public function show($id)
    {
        $data = Income::select(
            'incomes.*',
            DB::raw("CONCAT(chart_of_accounts.chart_code,'-',chart_of_accounts.chart_name) as chart_code_name"),
        )
        ->leftjoin('chart_of_accounts','chart_of_accounts.id','incomes.chart_of_acc_id')
        ->where('incomes.parent_id',$id)
        ->where('incomes.credit',0)
        ->orderBy('incomes.id','ASC')
        ->get();
        return $data;
    }
    public function update(Request $request)
    {
        $request->validate([
            'desc'                 => 'required',
            'invoice_number'       => 'required|max:255',
            'income_date'         => 'required',
            'income_rows.*.credit'=> 'required',
            'income_rows.*.debit' => 'required',
            'income_rows.*.chart_of_acc_id' => 'required',
        ]);
        DB::beginTransaction();
        try {
            $income = $request->income_rows;
            foreach($income as $value){

                $income_debit = Income::where('parent_id',$request->parent_id)->where('id',$request->id)->first();
                $income_debit->debit      = $value['debit'];
                $income_debit->desc       = $request->desc;
                $income_debit->created_by = Auth::user()->id;
                $income_debit->invoice_number = $request->invoice_number;
                $income_debit->chart_of_acc_id = $value['chart_of_acc_id'];
                $income_debit->income_date  = $request->income_date;
                $income_debit->update();

                $journal_debit = Journal::where('payment_model_type',get_class($income_debit))->where('payment_model_id',$income_debit->id)->first();
                $journal_debit->debit      = $value['debit'];
                $journal_debit->desc       = $request->desc;
                $journal_debit->created_by = Auth::user()->id;
                $journal_debit->invoice_number = $request->invoice_number;
                $journal_debit->chart_of_acc_id = $value['chart_of_acc_id'];
                $journal_debit->journal_date  = $request->income_date;
                $journal_debit->payment_model_type  = get_class($income_debit);
                $journal_debit->payment_model_id  = $income_debit->id;
                $journal_debit->update();

                $detail_credit = Income::where('parent_id',$request->parent_id)->where('id','!=',$request->id)->first();
                $detail_credit->credit      = $value['debit'];
                $detail_credit->desc       = $request->desc;
                $detail_credit->created_by = Auth::user()->id;
                $detail_credit->invoice_number = $request->invoice_number;
                $detail_credit->chart_of_acc_id = $request->chart_of_acc_id;
                $detail_credit->income_date  = $request->income_date;
                $detail_credit->update();

                $journal_detail_credit =Journal::where('payment_model_type',get_class($detail_credit))->where('payment_model_id',$detail_credit->id)->first();
                $journal_detail_credit->credit      = $value['debit'];
                $journal_detail_credit->desc       = $request->desc;
                $journal_detail_credit->created_by = Auth::user()->id;
                $journal_detail_credit->invoice_number = $request->invoice_number;
                $journal_detail_credit->chart_of_acc_id = $request->chart_of_acc_id;
                $journal_detail_credit->journal_date  = $request->income_date;
                $journal_detail_credit->payment_model_type  = get_class($detail_credit);
                $journal_detail_credit->payment_model_id  = $detail_credit->id;
                $journal_detail_credit->update();
            }
            DB::commit();
            $res = [
                "status" => 1,
                "message" => "update successfully."
            ];
        } catch (\Exception $e) {
            DB::rollback();
            $res = [
                'status'  => 0,
                'message' => 'update not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }
    public function destroy($id)
    {
        DB::beginTransaction();
        try {

            $income = Income::where('parent_id',$id)->get();

            foreach($income as $key=>$val)
            {
                Journal::where('payment_model_type',get_class($val))->where('payment_model_id',$val->id)->delete();
            }
            Income::where('parent_id',$id)->delete();
            DB::commit();
            $res = [
                "status" => 1,
                "message" => "delete successfully."
            ];
        } catch (\Exception $e) {
            DB::rollback();
            $res = [
                'status'  => 0,
                'message' => 'delete not success',
                'data'    => $e->getMessage(),
            ];
        }
        return response()->json($res,200);
    }
}