import { signal, WritableSignal } from '@angular/core';
import { Observable, firstValueFrom } from 'rxjs';

export interface UseMutationResult<TData, TResult> {
  loading: WritableSignal<boolean>;
  error: WritableSignal<unknown | null>;
  data: WritableSignal<TResult | null>;
  execute: (factory: (payload: TData) => Observable<TResult>, payload: TData) => Promise<TResult>;
}

export function useMutation<TData, TResult>(): UseMutationResult<TData, TResult> {
  const loading = signal(false);
  const error = signal<unknown | null>(null);
  const data = signal<TResult | null>(null);

  async function execute(
    factory: (payload: TData) => Observable<TResult>,
    payload: TData
  ): Promise<TResult> {
    loading.set(true);
    error.set(null);

    try {
      const result = await firstValueFrom(factory(payload));
      data.set(result);

      return result;
    } catch (err) {
      error.set(err);
      throw err;
    } finally {
      loading.set(false);
    }
  }

  return {
    loading,
    error,
    data,
    execute
  };
}
