<?php

namespace App\Http\Controllers;
use App\Enums\RecordStatusEnum;
use App\Http\Controllers\Helper\GlobalController;
use App\Models\BaseModel;
use App\Models\Invoice;
use App\Models\Repayment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;

class RepaymentController extends Controller
{
    protected $model;
    protected $baseLabId;
    protected $base;
    protected $invoiceModel;


    public function __construct(){
        $this->model = new Repayment();
        $this->invoiceModel = new Invoice();
        $this->baseLabId = Session::get('base_lab_id');
        $this->base = Session::get('base_lab');
    }

    public function index(Request $request){
        if(!GlobalController::user_can(Auth::user()->role_id, ['view_repayment'])) return redirect(url('my-profile'));
        $recordStatusConditions = Auth::id()==1 ? [RecordStatusEnum::ACTIVE , RecordStatusEnum::DELETE] : [RecordStatusEnum::ACTIVE];
        $invoices = $this->invoiceModel::with(['sample.patient'])->where(['lab_id' => $this->baseLabId, BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE])
            ->where('balance','>', 0)->get();
        $repayments = $this->model::query()
            ->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE)
            ->where('lab_id', $this->baseLabId)
            ->when(!empty($request->from_date) && !empty($request->to_date), function ($inv) use ($request){
                $inv->whereBetween('repayment_date',[date('Y-m-d',strtotime($request->from_date)), date('Y-m-d',strtotime($request->to_date))]);
            })->when(!empty(trim($request->kword)), function ($inv) use($request, $recordStatusConditions){
                $inv->whereIn('invoice_id', $this->invoiceModel::query()
                    ->whereRaw("replace(invoice_code, ' ','') like '%".str_replace(" ","",$request->kword)."%'")
                    ->orWhere('patient_uuid','like','%'.$request->kword.'%')->pluck('id')->toArray()
                )->where('lab_id', $this->baseLabId)->whereIn(BaseModel::RECORD_STATUS_FIELD, $recordStatusConditions);
            })->orderBy('repayment_date','desc')->paginate(20);
        return view('repayment', ['oweInvoices' => $invoices, 'repayments' => $repayments, 'labSettings' => (object) $this->location()]);
    }

    public function store(Request $request){
        DB::beginTransaction();
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['create_repayment'])) return false;
            $data = array(
                'invoice_id' => $request->invoice_id,
                'amount_to_pay' => $request->amount_to_pay,
                'discount' => $request->discount,
                'amount_after_discount' => $request->amount_after_discount,
                'discount_type' => $request->discount_type,
                'cash_repayment_amount' => $request->cash_repayment_amount,
                'bank_repayment_amount' => $request->bank_repayment_amount,
                'repayment_date' => date('Y-m-d', strtotime($request->repayment_date)),
                'payment_method' => $request->payment_method,
                'bank_name' => $request->bank_name,
                'transaction_ref' => $request->transaction_ref,
                'exchange_rate' => $request->exchange_rate,
                'lab_id' => $this->baseLabId,
                BaseModel::CREATED_AT => date('Y-m-d H:i:s'),
                BaseModel::CREATED_BY_FIELD => Auth::id()
            );
            $repayment = $this->model::query()->create($data);
            if($repayment){
                $invoice = $this->invoiceModel::query()->find($request->invoice_id);
                $totalRepayment = ($invoice->balance - ($request->cash_repayment_amount + $request->bank_repayment_amount));
                $invoice->deposit = ($invoice->deposit + $request->cash_repayment_amount);
                $invoice->bank_deposit = ($invoice->bank_deposit+$request->bank_repayment_amount);
                $invoice->balance = ($totalRepayment);
                $invoice->discount = $request->discount;
                $invoice->save();
            }
            else DB::rollBack();
            DB::commit();
            return response()->json(['success' => true, 'message' => __('invoice.create_success'), 'data' => $repayment]);
        } catch (\Exception $e){
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e]);
        }
    }


    public function update(Request $request){
        DB::beginTransaction();
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['update_repayment'])) return false;
            $data = array(
                'cash_repayment_amount' => $request->cash_repayment_amount,
                'bank_repayment_amount' => $request->bank_repayment_amount,
                'repayment_date' => date('Y-m-d', strtotime($request->repayment_date)),
                'payment_method' => $request->payment_method,
                'bank_name' => $request->bank_name,
                'transaction_ref' => $request->transaction_ref,
                'exchange_rate' => $request->exchange_rate
            );

            $prevRepayment = $this->model::query()->find($request->uid);

            $repayment = $this->model::query()->where(['id' => $request->uid, 'lab_id' => $this->baseLabId])->update($data);
            if($repayment){

                $reviseInvoice = $this->invoiceModel::query()->find($request->invoice_id);
                $totalRepayment = ($reviseInvoice->balance + $prevRepayment->cash_repayment_amount + $prevRepayment->bank_repayment_amount);
                $reviseInvoice->deposit = (($reviseInvoice->deposit + $prevRepayment->cash_repayment_amount) - $request->cash_repayment_amount);
                $reviseInvoice->bank_deposit = (($reviseInvoice->bank_deposit + $prevRepayment->bank_repayment_amount) - $request->bank_repayment_amount);
                $reviseInvoice->balance = $totalRepayment - ($request->cash_repayment_amount + $request->bank_repayment_amount);
                $reviseInvoice->save();
            }
            else DB::rollBack();
            DB::commit();
            return response()->json(['success' => true, 'message' => __('invoice.create_success'), 'data' => $repayment]);
        } catch (\Exception $e){
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()]);
        }
    }

    /** Perform by ajax function
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */

    public function delete(Request $request){
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['delete_repayment'])) return redirect(url('my-profile'));
            $repayment = $this->model::query()->where(['id' => $request->uid, 'lab_id' => $this->baseLabId])->get()->first();
            $reviseInvoice = $this->invoiceModel::query()->find($repayment->invoice_id);
            $totalRepayment = ($reviseInvoice->balance + $repayment->cash_repayment_amount + $repayment->bank_repayment_amount);
            $reviseInvoice->deposit = ($reviseInvoice->deposit - $repayment->cash_repayment_amount);
            $reviseInvoice->bank_deposit = ($reviseInvoice->bank_deposit - $repayment->bank_repayment_amount);
            $reviseInvoice->balance = $totalRepayment;
            $reviseInvoice->save();
            $repayment->update(array(BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::DELETE));
            return response()->json(['success' => true, 'message' => __('invoice.delete_success')]);
        } catch (\Exception $e){
            return response()->json(['success' => false, 'message' => __('invoice.delete_fail'), 'errors' => $e->getMessage()]);
        }
    }

    public function get(Request $request){
        try{
            $data = $this->model::with(['invoice.sample.patient'])->find($request->uid);
            return response()->json(['success' => true, 'message' => __('invoice.get_success'), 'data' => $data]);
        } catch (\Exception $e){
            return response()->json(['success' => false, 'message' => __('invoice.get_fail'), 'errors' => $e->getMessage()]);
        }
    }

    public function getInvoice(Request $request){
        try{
            $data = $this->invoiceModel::query()->find($request->uid);
            return response()->json(['success' => true, 'message' => __('invoice.get_success'), 'data' => $data]);
        } catch (\Exception $e){
            return response()->json(['success' => false, 'message' => __('invoice.get_fail'), 'errors' => $e->getMessage()]);
        }
    }


}
