<?php

namespace App\Controllers;

use App\Models\RecipeInputsModel;
use App\Models\RecipesModel;
use App\Models\InputsModel;

use App\Entities\RecipeInput;
use App\Entities\Recipe;
use App\Entities\Input;

use App\Controllers\Recipes;

use CodeIgniter\Database\Exceptions\DatabaseException;

use CodeIgniter\Exceptions\PageNotFoundException;

class Recipeinputs extends BaseController
{
    private RecipeInputsModel $model;
    private RecipesModel $recipesmodel;
    private InputsModel $inputsmodel;

    public function __construct()
    {
        $this->model = new RecipeInputsModel;
        $this->recipesmodel = new RecipesModel;
        $this->inputsmodel = new InputsModel;
    }
    
    public function create($recipeid)
    {
        $recipeinput = new RecipeInput($this->request->getPost());
        $inputid = $recipeinput->InputID;
        $recipeinput->RecipeID = $recipeid;
        $input = $this->getInputOr404($inputid);
        $iscoffee = $input->IsCoffee;

        //if ($iscoffee == 1){

        $qty = $recipeinput->Qty;

        $recipe = $this->getRecipeOr404($recipeid);
        $wastepercent = $recipe->WastePercent;
        $packqty = (int)$recipe->PackQty;

        $qtys = $this->getQtyTotalOr404($recipeid);
        $qtytotal = (int)$qtys->QtyTotal;
        $qtyinc = (int)($packqty * (1+($wastepercent/100)));
        $qtyleft = (int)($qtyinc  - $qtytotal);

        //dd($recipeid, $qty, $qtyleft, $qtyinc, $qtytotal, $packqty, $wastepercent );

        //dd($input);
        if ($iscoffee == 1){
            //dd($qty, $qtyleft);
            if($qty > $qtyleft){
                //$errors = [];
                if($qtyleft > 0){
                $errors = ["Qty" => "Total exceeds Finished Weight of <b>$qtyinc</b>g taking into account $wastepercent% Production Wastage<br/>
                The maximum of this Input you can add is <b>$qtyleft</b>g"];
                }else{
                    $errors = ["Qty" => "Total exceeds Finished Weight of <b>$qtyinc</b>g taking into account $wastepercent% Production Wastage<br/>
                    The finished weight has already been reached."];
                }
                // (New Final Weight would be $newqty g - Required Final Weight is $packqty g)<br/>

                //dd($errors);
                return redirect()->back()->with("errors", $errors)->withInput();
            }
            $qtytogo = $qtyinc - ($qtytotal + $qty);
        }

        $id = $this->model->insert($recipeinput);

        if($id === false){
            //dd($this->model->errors());
            return redirect()->back()->with("errors", $this->model->errors())->withInput();
        }

        $rec = $this->getRecipeRecOr404($recipeid);
        $rec->users_id = auth()->getUser()->id;
        //dd($rec);
        $this->recipesmodel->save($rec);

        if ($iscoffee == 1) {
            if ($qtytogo > 0 ) {
                $msg = "Added succesfully."; // - {$qtytogo}g to go";
            }else{
                $msg = "Added succesfully - Finished weight reached";
            }
        }else{
            if ($qtyleft > 0 ) {
                $msg = "Added successfully."; // - (Still {$qtyleft}g of coffee to go)";
            }else{
                $msg = "Added successfully.";
            }
        }

        // Update Sell Price, ValidFrom etc. in recipe after adding new line
        $recipes = new Recipes;
        $recipes->updateSellPrices($recipeid);

        return redirect()
            ->to("recipes/$recipeid")
            ->with("inputmessage", $msg);

    }

    public function createWithInputWaste($recipeid)
    {
   
        $recipeinput = new RecipeInput($this->request->getPost());
        $recipeinput->RecipeID = $recipeid;
        $qty = $recipeinput->Qty;
        $inputid = $recipeinput->InputID;
        $input = $this->getInputOr404($inputid);
        $wastepercent = $input->WastePercent;

        // This the proportion of the new input qty that contributes to the final weight (PackQty)
        // 120g with waste of 20% contributes 100g to final weight
        $qtyfinal = ceil($qty / (1 + ($wastepercent/100)));

        $row = $this->getQtyLeftOr404($recipeid);
        $qtytotal = (int)$row->QtyTotal;
        $packqty = (int)$row->PackQty;
        $newqty = $qtytotal + $qtyfinal;

        $qtyleft = (int)(($packqty - $qtytotal) * (1 + ($wastepercent/100)));

        if($qtytotal + $qtyfinal > $packqty){
            //$errors = [];
            $errors = ["Qty" => "Total exceeds Finished Weight after taking into account Production Wastage<br/>
            The maximum of this Input you can add is <b>$qtyleft</b>g taking into $wastepercent% production wastage"];

            // (New Final Weight would be $newqty g - Required Final Weight is $packqty g)<br/>

            //dd($errors);
            return redirect()->back()->with("errors", $errors)->withInput();
        }

        $id = $this->model->insert($recipeinput);

        if($id === false){
            //dd($this->model->errors());
            return redirect()->back()->with("errors", $this->model->errors())->withInput();
        }

        return redirect()->to("recipes/$recipeid")->with("message","Recipe Input saved.");

    }

    private function getQtyLeftOr404($id): object
    {

        $row = $this->model->query("SELECT recipes.PackQty, 
        SUM(recipeinputs.Qty / (1 + (inputs.WastePercent/100))) AS QtyTotal,
        SUM(recipeinputs.Qty) as QtySum
 FROM recipeinputs
 LEFT JOIN recipes ON recipeinputs.RecipeID=recipes.RecipeID
 LEFT JOIN inputs ON recipeinputs.InputID=inputs.InputID
 LEFT JOIN inputtypes ON inputs.InputTypeID=inputtypes.InputTypeID
 WHERE ifnull(inputtypes.IsCoffee,0) = 1
 AND recipeinputs.RecipeID=?",[$id])->getRow();

        if($row === null){
            throw new PageNotFoundException("Recipe with id $id not found or Qty = null");
        }
//dd($row);
//dd($qtyleft);
        return $row;
    }

    private function getInputOr404($inputid): Input
    {
        $input = $this->inputsmodel
        ->select('inputs.*, inputtypes.IsCoffee')
        ->join('inputtypes','inputs.InputTypeID=inputtypes.InputTypeID',"left")
        ->find($inputid);
      

        if($input === null){
            throw new PageNotFoundException("Input with id $inputid not found");
        }

        return $input;
    }
    
    private function getRecipeOr404($recipeid): object
    {
        $row = $this->model->query("SELECT recipes.PackQty, 
        recipes.WastePercent
    FROM recipes
    WHERE recipes.RecipeID=?",[$recipeid])->getRow();

        if($row === null){
            throw new PageNotFoundException("Recipe with id $recipeid not found or Qty = null");
        }

        return $row;
    }

    private function getQtyTotalOr404($recipeid): object
    {
        $row = $this->model->query("SELECT
        ifnull(SUM(recipeinputs.Qty),0) as QtyTotal
 FROM recipeinputs
  LEFT JOIN inputs ON recipeinputs.InputID=inputs.InputID
 LEFT JOIN inputtypes ON inputs.InputTypeID=inputtypes.InputTypeID
 WHERE ifnull(inputtypes.IsCoffee,0) = 1
 AND recipeinputs.RecipeID=?",[$recipeid])->getRow();

        if($row === null){
            throw new PageNotFoundException("Recipe with id $recipeid not found or Qty = null");
        }

        return $row;
    }


    public function delete($recipeid, $id)
    {
        try{
			if (! auth()->user()->can_edit_by_controller( substr(strrchr(__CLASS__, '\\'), 1) ) ) {
				return redirect()->to( "recipes" );
			}

            $this->model->delete($id);

            $rec = $this->getRecipeRecOr404($recipeid);
            $rec->users_id = auth()->getUser()->id;
            $this->recipesmodel->save($rec);
    
        } catch (DatabaseException $e) {
            return redirect()->back()->with("errors",$this->model->errors())->withInput();
        }

        // Update Sell Price, ValidFrom etc. in recipe after deleting input
        $recipes = new Recipes;
        $recipes->updateSellPrices($recipeid);

        return redirect()
            ->to("recipes/$recipeid")
            ->with("inputmessage","Input deleted.");

    }

    private function getRecipeRecOr404($id): Recipe
    {
        $recipe = $this->recipesmodel->find($id);

        if($recipe === null){
            throw new PageNotFoundException("Recipe with id $id not found");
        }

        return $recipe;
    }

}
