import { Injectable } from '@angular/core';
import { Milestone } from '../enums/milestone';
import { map, ReplaySubject } from 'rxjs';
import { TreeNode } from '../models/tree-node';
import { Header } from '../models/header';

@Injectable({ providedIn: 'root' })
export class MetaService {
  private data = [
    {
      label: 'School',
      data: 'node.school',
      children: [
        { data: Milestone.County, label: 'County' },
        { data: Milestone.School, label: 'Name' },
      ],
    },
    {
      label: 'Class',
      data: 'node.class',
      children: [
        { data: Milestone.Cohort, label: 'Cohort' },
        { data: Milestone.Year, label: 'Year' },
        { data: Milestone.Grade, label: 'Grade' },
      ],
    },
    {
      label: 'English Language Arts',
      data: 'node.ela',
      children: [
        { data: Milestone.ELACount, label: 'Count' },
        { data: Milestone.ELAMean, label: 'Mean' },
        { data: Milestone.ELARank, label: 'Rank' },
        { data: Milestone.ELA0, label: 'Beginning Learner %' },
        { data: Milestone.ELA1, label: 'Developing Learner %' },
        { data: Milestone.ELA2, label: 'Proficient Learner %' },
        { data: Milestone.ELA3, label: 'Advanced Learner %' },
      ],
    },
    {
      label: 'Mathematics',
      data: 'node.math',
      children: [
        { data: Milestone.MathCount, label: 'Count' },
        { data: Milestone.MathMean, label: 'Mean' },
        { data: Milestone.MathRank, label: 'Rank' },
        { data: Milestone.Math0, label: 'Beginning Learner %' },
        { data: Milestone.Math1, label: 'Developing Learner %' },
        { data: Milestone.Math2, label: 'Proficient Learner %' },
        { data: Milestone.Math3, label: 'Advanced Learner %' },
      ],
    },
    {
      label: 'Science',
      data: 'node.sci',
      children: [
        { data: Milestone.SciCount, label: 'Count' },
        { data: Milestone.SciMean, label: 'Mean' },
        { data: Milestone.SciRank, label: 'Rank' },
        { data: Milestone.Sci0, label: 'Beginning Learner %' },
        { data: Milestone.Sci1, label: 'Developing Learner %' },
        { data: Milestone.Sci2, label: 'Proficient Learner %' },
        { data: Milestone.Sci3, label: 'Advanced Learner %' },
      ],
    },
    {
      label: 'Social Studies',
      data: 'node.soc',
      children: [
        { data: Milestone.SocCount, label: 'Count' },
        { data: Milestone.SocMean, label: 'Mean' },
        { data: Milestone.SocRank, label: 'Rank' },
        { data: Milestone.Soc0, label: 'Beginning Learner %' },
        { data: Milestone.Soc1, label: 'Developing Learner %' },
        { data: Milestone.Soc2, label: 'Proficient Learner %' },
        { data: Milestone.Soc3, label: 'Advanced Learner %' },
      ],
    },
  ] as Partial<TreeNode>[];

  private subject = new ReplaySubject<TreeNode[]>(1);
  readonly Data$ = this.subject
    .asObservable()
    .pipe(
      map((items: TreeNode[]) =>
        items.map((item: TreeNode) => new TreeNode(item))
      )
    );
  // readonly Flat$ = this.subject.asObservable().pipe(
  //   map((data: TreeNode[]) => {
  //     const result: Header[] = [];
  //     data.forEach((item: TreeNode) => result.push(...this.flatten('', item)));
  //     return result;
  //   })
  // );

  // readonly Data = () =>
  //   this.data.map((item: Partial<TreeNode>) => new TreeNode(item));
  readonly Flat = () => {
    const result: Header[] = [];
    this.data.forEach((item: Partial<TreeNode>) =>
      result.push(...this.flatten('', item))
    );
    return result;
  };

  constructor() {
    this.subject.next(
      this.data.map((item: Partial<TreeNode>) => new TreeNode(item))
    );
  }

  private flatten(path: string, item: Partial<TreeNode>): Header[] {
    const result: Header[] = [];
    const children = item?.children ?? [];

    if (children.length > 0) {
      children.forEach((child: Partial<TreeNode>) =>
        result.push(...this.flatten(`${path}${item.label}`, child))
      );
    } else {
      result.push(
        new Header({ source: item.data, label: `${path} - ${item.label}` })
      );
    }

    return result;
  }
}
