import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
import { TabItem } from '../../components/common/tab-card/tab-card.component';
import { GuiRowSelection, GuiRowSelectionMode, GuiRowSelectionType, GuiSelectedRow } from '@generic-ui/ngx-grid';
import { UserTableComponent } from '../../components/tables/user-table/user-table.component';
import { ModuleTableComponent } from '../../components/tables/module-table/module-table.component';
import { GroupTableComponent } from '../../components/tables/group-table/group-table.component';
import { User } from '../../models/user-management.api.models';
import { MatTabsModule, MatTabGroup } from '@angular/material/tabs';
import { BasePageComponent } from '../base-page/base-page.component';

@Component({
  standalone: true,
  imports: [MatTabsModule, MatTabGroup, UserTableComponent, ModuleTableComponent, GroupTableComponent],
  selector: 'app-user-assignment',
  templateUrl: './user-assignment.component.html',
  styleUrl: './user-assignment.component.scss'
})
export class UserAssignmentComponent extends BasePageComponent implements OnInit, AfterViewInit {

  initWithoutData = () => { }

  userInLabel: string = "Benutzer in"

  tabItems: TabItem[] = [
    {
      routerLink: '/module-user',
      title: 'Modules'
    },
    {
      routerLink: '/group-user',
      title: 'Groups'
    }
  ]

  @Input() activeTabTitle: string | null = null;
  @Input() activeIndex: number = 0;
  @ViewChild("unassignedUsers") unassignedUsers!: UserTableComponent;
  @ViewChild("assignedUsers") assignedUsers!: UserTableComponent;
  @ViewChild("modules") modules!: ModuleTableComponent;
  @ViewChild("groups") groups!: GroupTableComponent;

  userRowSelection: GuiRowSelection = {
    enabled: true,
    type: GuiRowSelectionType.CHECKBOX,
    mode: GuiRowSelectionMode.MULTIPLE
  }

  private anySelected: boolean = false;

  ngOnInit(): void { }

  ngAfterViewInit(): void {

    this.buttonVisibilityService.setVisibleOnly(this.refreshService, this.transferService)

    this.refreshService.removeAll()
    this.refreshService.add(() => {
      this.modules.fetchData();
      this.groups.fetchData();
      if (this.anySelected)
        this.updateUserTables();
    });

    this.transferService.add(() => {
      if (this.isAssignment) {
        this.assign();
        this.refreshService.executeAll();
      }
      else if (this.isUnassignment) {
        this.unassign();
        this.refreshService.executeAll();
      }
    });
  }

  target: Target = Target.Module;
  targetId = 0;

  assign() {
    var users: User[] = this.unassignedUsers.selectedRows.map(row => row.source)

    console.log(users)

    this.unselectUserTables()
    switch (this.target) {
      case Target.Module:
        this.unassignedUsers.createModuleOfUsers(this.targetId, users)
          .then(() => this.updateUserTables())
        break;
      case Target.Group:
        this.unassignedUsers.createGroupOfUsers(this.targetId, users)
          .then(() => this.updateUserTables())
        break;
    }
  }

  unassign() {
    var users: User[] = this.assignedUsers.selectedRows.map(row => row.source)
    
    this.unselectUserTables()
    switch (this.target) {
      case Target.Module:
        this.unassignedUsers.deleteModuleOfUsers(this.targetId, users)
          .then(() => this.updateUserTables())
        break;
      case Target.Group:
        this.unassignedUsers.deleteGroupOfUsers(this.targetId, users)
          .then(() => this.updateUserTables())
        break;
    }
  }

  unselectUserTables() {
    this.assignedUsers.safelyUnselectAll()
    this.unassignedUsers.safelyUnselectAll()
  }

  updateUserTables() {
    this.anySelected = true;
    this.unselectUserTables()
    switch (this.target) {
      case Target.Module:
        this.assignedUsers.fetchDataByModuleId(this.targetId);
        this.unassignedUsers.fetchDataByModuleId(this.targetId, false);
        break;
      case Target.Group:
        this.assignedUsers.fetchDataByGroupId(this.targetId);
        this.unassignedUsers.fetchDataByGroupId(this.targetId, false);
        break;
    }
  }

  modulesOnSelectedRows = (rows: GuiSelectedRow[]) => {
    if (rows.length > 0) {
      this.modules.safelyUnselectAll();
      this.userInLabel = `Benutzer in Module ${rows[0].source?.name}`
      this.target = Target.Module;
      this.targetId = rows[0].source.id;
      this.updateUserTables();
    }
  }

  groupsOnSelectedRows = (rows: GuiSelectedRow[]) => {
    if (rows.length > 0) {
      this.groups.safelyUnselectAll();
      this.userInLabel = `Benutzer in Gruppe ${rows[0].source?.name}`
      this.target = Target.Group;
      this.targetId = rows[0].source.id;
      this.updateUserTables();
    }
  }

  //unselection case
  private sUnassgnCount: number = 0;
  private sAssgnCount: number = 0;

  private get isAssignment(): boolean {
    return this.sUnassgnCount > 0;
  }

  private get isUnassignment(): boolean {
    return this.sAssgnCount > 0;
  }

  unassignedUsersOnSelectedRows = (rows: GuiSelectedRow[]) => {
    if (rows.length > this.sUnassgnCount && this.unassignedUsers.selectedRows.length > 0) {
      this.assignedUsers.safelyUnselectAll()
    }

    this.sUnassgnCount = rows.length;
  }

  assignedUsersOnSelectedRows = (rows: GuiSelectedRow[]) => {
    if (rows.length > this.sAssgnCount && this.assignedUsers.selectedRows.length > 0) {
      this.unassignedUsers.safelyUnselectAll()
    }

    this.sAssgnCount = rows.length;
  }
}

enum Target {
  Module,
  Group
}