<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Ramsey\Uuid\Uuid;

class StatTreeLine extends Model
{
    protected $table = 'stat_tree_line';
    public $timestamps = false;

    public function getRouteKeyName()
    {
        return 'uid';
    }

    public function lineClauses(){
        return $this->hasMany(StatTreeLineClause::class, 'stat_tree_line_id', 'id')
            ->orderBy('position_index');
    }
    public function statTree(){
        return $this->hasOne(StatTree::class, 'id', 'stat_tree_id');
    }
    public function parent(){
        return $this->hasOne(StatTreeLine::class, 'id', 'parent_stat_tree_line_id');
    }
    public function children(){
        return $this->hasMany(StatTreeLine::class, 'parent_stat_tree_line_id', 'id')
            ->orderBy('tree_order_position_index');
    }
    public function reportColumns(){
        return $this->hasMany(StatTreeLineReportColumn::class, 'stat_tree_line_id', 'id')
            ->orderBy('position_index');
    }
    public function displayLabel() {
        $lastStatTreeLineClause = StatTreeLineClause::where('stat_tree_line_id', $this->id)
            ->orderBy('position_index', 'DESC')
            ->first();
        if($lastStatTreeLineClause) {
            return $lastStatTreeLineClause->clause_label;
        }
        return '-';
    }
    public function displayLineClause() {
        $lastStatTreeLineClause = StatTreeLineClause::where('stat_tree_line_id', $this->id)
            ->orderBy('position_index', 'DESC')
            ->first();
        if($lastStatTreeLineClause) {
            return $lastStatTreeLineClause;
        }
        return null;
    }
    public function columnsJSON() {
        $columns = [];
        foreach ($this->reportColumns as $column) {
            $columns[] = [
                "label" => $column->label,
                "display_key" => $column->display_key,
            ];
        }
        return json_encode($columns);
    }
    public function argsJSON() {
        $args = [];
        $displayLineClause = $this->displayLineClause();
        if(!!$displayLineClause) {
            foreach($displayLineClause->lineClauseArgs as $stlcArg) {
                $args[] = [
                    "uid" => $stlcArg->uid,
                    "arg_text" => $stlcArg->clauseArg->arg_text,
                    "field_type" => $stlcArg->clauseArg->field_type,
                    "value" => $stlcArg->value,
                    "access_level" => $stlcArg->access_level,
                ];
            }
        }
        return json_encode($args);
    }

    public function copy($newParentStatTreeLine, StatTree $newStatTree) {

        // create line
        $newStatTreeLine = new StatTreeLine;
        $nextId = DB::select("select nextval('stat_tree_line_id_seq')");
        $newStatTreeLine->id = $nextId[0]->nextval;
        $newStatTreeLine->uid = Uuid::uuid4();
        $newStatTreeLine->stat_tree_id = $newStatTree->id;
        $newStatTreeLine->tree_order_position_index = $this->tree_order_position_index;
        $newStatTreeLine->parent_stat_tree_line_id = $newParentStatTreeLine ? $newParentStatTreeLine->id : null;
        $newStatTreeLine->save();

        // line clauses
        foreach ($this->lineClauses as $srcLineClause) {
            $nextId = DB::select("select nextval('stat_tree_line_clause_id_seq')");
            $newStatTreeLineClause = new StatTreeLineClause;
            $newStatTreeLineClause->id = $nextId[0]->nextval;
            $newStatTreeLineClause->uid = Uuid::uuid4();
            $newStatTreeLineClause->stat_tree_line_id = $newStatTreeLine->id;
            $newStatTreeLineClause->clause_id = $srcLineClause->clause_id;
            $newStatTreeLineClause->clause_label = $srcLineClause->clause_label;
            $newStatTreeLineClause->position_index = $srcLineClause->position_index;
            $newStatTreeLineClause->stat_tree_id = $newStatTree->id;
            $newStatTreeLineClause->save();

            // line clause args
            foreach ($srcLineClause->lineClauseArgs as $srcLineClauseArg) {
                $newStatTreeLineClauseArg = new StatTreeLineClauseArg();
                $nextId = DB::select("select nextval('stat_tree_line_clause_arg_id_seq')");
                $newStatTreeLineClauseArg->id = $nextId[0]->nextval;
                $newStatTreeLineClauseArg->stat_tree_line_clause_id = $newStatTreeLineClause->id;
                $newStatTreeLineClauseArg->clause_arg_id = $srcLineClauseArg->clause_arg_id;
                $newStatTreeLineClauseArg->access_level = $srcLineClauseArg->access_level;
                $newStatTreeLineClauseArg->stat_tree_id = $newStatTree->id;
                $newStatTreeLineClauseArg->value = $srcLineClauseArg->value;
                $newStatTreeLineClauseArg->save();
            }
        }

        // report columns
        foreach ($this->reportColumns as $srcReportColumn) {
            $newStatTreeLineReportColumn = new StatTreeLineReportColumn();
            $nextId = DB::select("select nextval('stat_tree_line_report_column_id_seq')");
            $newStatTreeLineReportColumn->id = $nextId[0]->nextval;
            $newStatTreeLineReportColumn->uid = Uuid::uuid4();
            $newStatTreeLineReportColumn->stat_tree_line_id = $newStatTreeLine->id;
            $newStatTreeLineReportColumn->label = $srcReportColumn->label;
            $newStatTreeLineReportColumn->position_index = $srcReportColumn->position_index;
            $newStatTreeLineReportColumn->display_key = $srcReportColumn->display_key;
            $newStatTreeLineReportColumn->field_type = $srcReportColumn->field_type;
            $newStatTreeLineReportColumn->display_function = $srcReportColumn->display_function;
            $newStatTreeLineReportColumn->record_route_name = $srcReportColumn->record_route_name;
            $newStatTreeLineReportColumn->stat_tree_id = $newStatTree->id;
            $newStatTreeLineReportColumn->save();
        }

        foreach ($this->children as $child) {
            $child->copy($newStatTreeLine, $newStatTree);
        }

    }
}
