
import { Component, computed, inject, input, output, TemplateRef, ViewChild } from "@angular/core";
import { CheckboxColumnComponent, ColumnBase, ColumnComponent, FieldDataType, FilterService, KENDO_GRID } from "@progress/kendo-angular-grid";
import { FastGridDateFilterCell } from "./fast-grid-date-filter-cell.component";
import { MessageService } from "../services/message.service";
import { DateType } from "./fast-datepicker.component";
import { handleError } from "../utils/util";
import { FastNumericTextBoxComponent } from "./fast-numerictextbox.component";
import { ReactiveFormsModule } from "@angular/forms";
import { FastGridNumericFilterCell } from "./fast-grid-numeric-filter-cell.component";
import { NgTemplateOutlet } from "@angular/common";

export type GridColType = 'text' | 'checkbox' | 'num-c#' | 'num-c0' | 'num-c2' | 'num-c2-edit' | 'num-c5' | 'num-c5-edit' | 'num-d#' | 'num-d0' | 'num-d0-edit' | 'num-d2' | 'num-d2-edit' | 'num-d5' | 'num-p#' | 'num-p#*100' | DateType;

export interface TypeFormat {
  type: GridColType;
  format?: string;
}

@Component({
  selector: 'fast-grid-col',
  imports: [KENDO_GRID, FastGridDateFilterCell, FastGridNumericFilterCell, FastNumericTextBoxComponent, ReactiveFormsModule, NgTemplateOutlet],
  template: `
  @if(type() === 'checkbox') {
     <kendo-grid-checkbox-column #kendoCheckboxCol [title]="computedTitle()" [width]="width()" (click)="clickMethod.emit($event)" [class]="class() + ' p-0!'" [headerClass]="headerClass() + ' checkbox-header'" [hidden]="hidden()">
         @if(this.headerTemplate() !== null) {
          <ng-template #headerTemplateRef kendoGridHeaderTemplate let-column="column" let-dataItem="dataItem" let-rowIndex="rowIndex">
            <ng-container *ngTemplateOutlet="headerTemplate(); context: { $implicit: column, column, dataItem, rowIndex }" ></ng-container>
          </ng-template>
        }

        @if(this.cellTemplate() !== null) {
          <ng-template #cellTemplateRef kendoGridCellTemplate let-column="column" let-dataItem="dataItem" let-rowIndex="rowIndex">
            <ng-container *ngTemplateOutlet="cellTemplate(); context: { $implicit: column, column, dataItem, rowIndex }"></ng-container>
          </ng-template>
        }
     </kendo-grid-checkbox-column>
  }
  @else {
      <kendo-grid-column #kendoCol [editor]="editor()" [field]="field()" [title]="computedTitle()" [width]="width()" [filter]="computedFilterType()" [format]="computedFormat()" (click)="clickMethod.emit($event)" [filterable]="filterable()" [class]="class()" [headerClass]="headerClass()" [hidden]="hidden()">
        @if(this.headerTemplate() !== null) {
          <ng-template #headerTemplateRef kendoGridHeaderTemplate let-column="column" let-dataItem="dataItem" let-rowIndex="rowIndex">
            <ng-container *ngTemplateOutlet="headerTemplate(); context: { $implicit: column, column, dataItem, rowIndex }" ></ng-container>
          </ng-template>
        }

        @if(this.cellTemplate() !== null) {
          <ng-template #cellTemplateRef kendoGridCellTemplate let-column="column" let-dataItem="dataItem" let-rowIndex="rowIndex">
            <ng-container *ngTemplateOutlet="cellTemplate(); context: { $implicit: column, column, dataItem, rowIndex }"></ng-container>
          </ng-template>
        }

        @if (type().includes('date-')) {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-date-filter-cell [field]="field()" [type]="computedDateType()" />
          </ng-template>
        }
        @else if(type() === 'num-d0-edit') {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-numeric-filter-cell   [field]="field()" [type]="type()" [format]="computedFormat()" />
          </ng-template>
          <ng-template kendoGridEditTemplate let-formGroup="formGroup">
            <fast-numerictextbox [formControl]="formGroup?.controls[editFormControlName()]" [spinners]="false" [step]="0" [decimals]="0" />
          </ng-template>
        }
        @else if(type() === 'num-d2-edit') {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-numeric-filter-cell [columnFilter]="filter" [field]="field()" [type]="type()" [format]="computedFormat()" />
          </ng-template>
          <ng-template kendoGridEditTemplate let-formGroup="formGroup">
            <fast-numerictextbox [formControl]="formGroup?.controls[editFormControlName()]" [spinners]="false" [step]="0" [decimals]="2" />
          </ng-template>
        }
        @else if(type() === 'num-c2-edit') {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-numeric-filter-cell [columnFilter]="filter" [field]="field()" [type]="type()" [format]="computedFormat()" />
          </ng-template>
          <ng-template kendoGridEditTemplate let-formGroup="formGroup">
            <fast-numerictextbox [formControl]="formGroup?.controls[editFormControlName()]" [spinners]="false" [step]="0" [decimals]="2" />
          </ng-template>
        }
        @else if(type() === 'num-c5-edit') {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-numeric-filter-cell [columnFilter]="filter" [field]="field()" [type]="type()" [format]="computedFormat()" />
          </ng-template>
          <ng-template kendoGridEditTemplate let-formGroup="formGroup">
            <fast-numerictextbox [formControl]="formGroup?.controls[editFormControlName()]" [spinners]="false" [step]="0" [decimals]="5" />
          </ng-template>
        }
        @else if(type().includes('num-')) {
          <ng-template kendoGridFilterCellTemplate let-filter="filter" let-column="column">
            <fast-grid-numeric-filter-cell [columnFilter]="filter" [field]="field()" [type]="type()" [format]="computedFormat()" />
          </ng-template>
        }
      </kendo-grid-column>
    }
  `,
})
export class FastGridColComponent {
  @ViewChild('kendoCol') kendoCol: ColumnComponent;
  @ViewChild('kendoCheckboxCol') kendoCheckboxCol: CheckboxColumnComponent;
  @ViewChild('headerTemplateRef') headerTemplateRef: TemplateRef<unknown>;
  @ViewChild('cellTemplateRef') cellTemplateRef: TemplateRef<unknown>;
  @ViewChild(FastGridDateFilterCell) dateFilterCell: FastGridDateFilterCell;
  @ViewChild(FastGridNumericFilterCell) numericFilterCell: FastGridNumericFilterCell;
  messageService = inject(MessageService);

  field = input.required<string>();
  title = input<string>();
  width = input<number>();
  type = input.required<GridColType>();
  editor = input<"boolean" | "text" | "numeric" | "date">();
  editFormControlName = input<string>(null);
  clickMethod = output<unknown>();
  headerTemplate = input<TemplateRef<unknown> | null>(null);
  cellTemplate = input<TemplateRef<unknown> | null>(null);
  filterable = input<boolean>(true);
  class = input<unknown>(null);
  headerClass = input<unknown>(null);
  hidden = input<boolean>(false);

  formats: Record<GridColType, TypeFormat> = {
    'text': { type: 'text' },
    'checkbox': { type: 'checkbox' },
    'num-c#': { type: 'num-c#', format: '$#,##.#####;($#,##.#####)' },
    'num-c0': { type: 'num-c0', format: '$#,##;($#,##)' },
    'num-c2': { type: 'num-c2', format: '$#,##.00;($#,##.00)' },
    'num-c2-edit': { type: 'num-c2-edit', format: '$#,##.00;($#,##.00)' },
    'num-c5': { type: 'num-c5', format: '$#,##.00000;($#,##.00000)' },
    'num-c5-edit': { type: 'num-c5-edit', format: '$#,##.00000;($#,##.00000)' },
    'num-d#': { type: 'num-d#', format: '#,##.#####;-#,##.#####' },
    'num-d0': { type: 'num-d0', format: '#,##;-#,##' },
    'num-d0-edit': { type: 'num-d0-edit', format: '#,##;-#,##' },
    'num-d2': { type: 'num-d2', format: '#,##.00;-#,##.00' },
    'num-d2-edit': { type: 'num-d2-edit', format: '#,##.00;-#,##.00' },
    'num-d5': { type: 'num-d5', format: '#,##.00000;-#,##.00000' },
    'num-p#': { type: 'num-p#', format: '#,.#####\\%;(#,.#####)\\%' },
    'num-p#*100': { type: 'num-p#*100', format: '#,.#####%;(#,.#####)%' },
    'date-short': { type: 'date-short', format: 'M/d/yyyy' },
    'date-month': { type: 'date-month', format: 'MMM yyyy' },
    'date-time': { type: 'date-time', format: 'M/d/yyyy h:mm a' },
  }

  computedDateType = computed(() => {
    const dateType = this.type() as DateType;
    if (dateType)
      return dateType
    else
      this.throwTypeError();
  });

  computedTitle = computed(() => {
    return this.title() ?? this.field();
  });

  computedFilterType = computed((): FieldDataType => {
    if (this.type() === 'text')
      return 'text';
    else if (this.type().includes('date-'))
      return 'date';
    else if (this.type().includes('num-'))
      return 'numeric'
    else if (this.type() === 'checkbox')
      return 'boolean';
    else
      this.throwTypeError();
  });

  computedFormat = computed(() => {
    if (this.type() === 'checkbox')
      return undefined;
    if (this.type() in this.formats)
      return this.formats[this.type()].format;
    else
      this.throwTypeError();
  });

  throwTypeError() {
    handleError(`Type {${this.type()}} not implemented in fast-grid-col`, this.messageService);
  }

  public getKendoCol(): ColumnBase {
    return this.kendoCol ?? this.kendoCheckboxCol;
  }

  public setDateFilterService(filterService: FilterService) {
    this.dateFilterCell?.setFilterService(filterService);
  }

  public setNumFilterService(filterService: FilterService) {
    this.numericFilterCell.setFilterService(filterService);
  }
}
