import { Component, Inject, Input, OnDestroy, OnInit, ViewChild, input } from '@angular/core';
import { ApiService } from '../../../services/api/user-management.api.service';
import { GuiGridModule, GuiColumn, GuiColumnMenu, GuiSorting, GuiRowDetail, GuiPaging, GuiPagingDisplay, GuiSearching, GuiCellEdit, GuiInfoPanel, GuiTitlePanel, GuiRowSelection, GuiSelectedRow, GuiGridComponent, GuiGridApi, GuiTheme } from '@generic-ui/ngx-grid';
import { Subscription } from 'rxjs/internal/Subscription';
import { ColorModeService, Theme } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

@Component({
  standalone: true,
  imports: [CommonModule, FormsModule, GuiGridModule ],
  selector: 'app-base-table',
  templateUrl: './base-table.component.html',
  styleUrl: './base-table.component.css'
})
export class BaseTableComponent<TModel, TApiService extends ApiService<TModel>> implements OnInit, OnDestroy {

  service: TApiService;

  columnMenu: GuiColumnMenu = {
    enabled: true,
    sort: true,
    columnsManager: false,
    filter: false
  };
  sorting: GuiSorting = {
    enabled: true,
    multiSorting: true
  };
  loading: boolean = false;
  autoResizeWidth: boolean = true;
  rowDetail: GuiRowDetail = {
    enabled: true,
    template: (item: TModel) => {
      return `
        <div></div>`;
    }
  };
  paging: GuiPaging = {
    enabled: true,
    page: 1,
    pageSize: 15,
    pageSizes: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50],
    pagerTop: true,
    pagerBottom: false,
    display: GuiPagingDisplay.ADVANCED
  };
  searching: GuiSearching = {
    enabled: true,
    placeholder: 'Suche'
  };
  maxHeight: any = 400;
  infoPanel: GuiInfoPanel = {
    enabled: true,
    infoDialog: false,
    columnsManager: true,
    schemaManager: true
  };
  titlePanel: GuiTitlePanel = {
    enabled: false,
    template: () => {
      return `
        <div class='title-panel-example' >List of contract workers</div>
        `;
    }
  };

  theme: GuiTheme = typeof window !== 'undefined' ? (localStorage.getItem('theme') === 'dark' ? GuiTheme.DARK : GuiTheme.FABRIC) : GuiTheme.DARK;

  private themeSubscription: Subscription = new Subscription();

  constructor(@Inject(ApiService<TModel>) service: TApiService, columns: Array<GuiColumn>, private cModeService: ColorModeService) {
    this.service = service;
    if (this.columns.length == 0)
      this.columns = columns;

    //assign row details
    if (this.rowDetailTemplate === null || this.rowDetailTemplate === undefined)
      this.rowDetail = {
        enabled: false,
      };
    else
      this.rowDetail = {
        enabled: true,
        template: (this.rowDetailTemplate)
      };
  }

  @Input() rowDetailTemplate: null | ((item: TModel, index: number) => string) = null;

  @Input() isCellEditable = false;

  @Input() cellEditing: GuiCellEdit = {

    enabled: this.isCellEditable,

    rowEdit: (value: any, item: any, index: number) => {
      return Boolean(index % 2);
    },

    cellEdit: (value: any, item: any, index: number) => {
      return Boolean(index % 5);
    }
  }

  @Input() rowSelection: boolean | GuiRowSelection = true;

  @Input() onSelectedRows: (rows: Array<GuiSelectedRow>) => void = (rows) => { };

  @Input() initData: () => void = this.fetchData;

  @Input() columns: Array<GuiColumn> = [];

  selected: boolean = false;
  safelyUnselectAll() {
    this.selected = true
    if (this.api?.getSelectedRows() != undefined)
      if ((this.api?.getSelectedRows().length ?? 0 > 0) && this.selected) {
        this.api?.unselectAll()
        this.selected = false
      }
  }

  @ViewChild('grid', { static: true }) mainGrid!: GuiGridComponent;

  private get api(): GuiGridApi {
    return this.mainGrid.api;
  }

  set source(data: any[]) {
    this.api.setSource(data)
  }

  get selectedRows(): Array<GuiSelectedRow> {
    return this.api.getSelectedRows();
  }

  ngOnInit(): void {

    const subscription = this.cModeService.themeChanges$.subscribe((theme: Theme) => {
      this.theme = theme === 'dark' ? GuiTheme.DARK : GuiTheme.FABRIC;
    });

    this.themeSubscription.add(subscription);
    this.initData()
  }

  ngOnDestroy(): void {
    this.themeSubscription.unsubscribe();
  }

  fetchData(): void {
    this.service.getAll().subscribe({
      next: (response) => {
        this.source = response;
        this.loading = false;
      },
      error: (error) => { }
    });
  }
}