import { Maybe } from '@/core';
import {
  IListingResponse,
  IPaginatedResponse,
  IResponseMetadata,
} from '@/core/models/service.model';
import { Component, signal } from '@angular/core';
import { catchError, finalize, Observable } from 'rxjs';
import { IColumn } from '../components/pageDataList/page-data-list.component';

@Component({
  selector: 'abstract-list',
  template: '',
})
export abstract class AbstractList<ResponseModel, RequestParams = null> {
  columns = [] as IColumn[];
  loading = signal(false);
  items = signal<ResponseModel[]>([]);
  visibleForm = signal(false);
  requestPayload = signal<Maybe<RequestParams>>(null);
  selectedItemForEdit = signal<Maybe<ResponseModel>>(null);
  editMode = signal(false);
  withPagination = signal(false);
  responseMetaData = signal<Maybe<IResponseMetadata>>(null);

  ngOnInit() {
    this.setColumns();
    this.getData();
  }

  refresh() {
    this.getData();
  }

  getData() {
    this.loading.set(true);
    this.items.set([]);
    this.getDataRequest(this.requestPayload())
      ?.pipe(
        finalize(() => {
          this.loading.set(false);
        }),
        catchError((error) => {
          throw error;
        }),
      )
      .subscribe((res) => {
        if ('meta' in res) {
          this.responseMetaData.set(res.meta);
        }
        this.items.set(res.data ?? []);
      });
  }

  openAddForm() {
    this.selectedItemForEdit.set(null);
    this.editMode.set(false);
    this.visibleForm.set(true);
  }

  abstract getDataRequest(
    payload: Maybe<RequestParams>,
  ): Observable<IPaginatedResponse<ResponseModel> | IListingResponse<ResponseModel>> | void;

  abstract setColumns(): void;

  // constructor() {
  //   if (this.editable) {
  //     if (!this.ed) {
  //       throw new Error('onEdit output must be bound when editable is true');
  //     }
  //   }
  // }

  onEditClick(selectedItem: ResponseModel) {
    this.selectedItemForEdit.set(selectedItem);
    this.editMode.set(true);
    this.visibleForm.set(true);
  }
  onCloseEdit() {
    this.visibleForm.set(false);
  }

  changePage(page: number) {
    // this.
  }
}
