import { useState, useCallback } from 'react';
import { useApiRequest } from './useApiRequest';

export interface UseCrudDrawerOptions<T> {
  getId: (record: T) => string;
  onCreate: (values: Record<string, unknown>) => Promise<void>;
  onUpdate: (id: string, values: Record<string, unknown> & { version: number }) => Promise<void>;
  onSuccess?: () => void;
}

export interface UseCrudDrawerReturn<T> {
  open: boolean;
  editingRecord: T | null;
  initialValues: Record<string, unknown> | undefined;
  openCreate: (defaults?: Record<string, unknown>) => void;
  openEdit: (record: T, fieldMap?: (record: T) => Record<string, unknown>) => void;
  close: () => void;
  handleSubmit: (values: Record<string, unknown>) => Promise<void>;
  loading: boolean;
}

export function useCrudDrawer<T extends { version: number }>(
  options: UseCrudDrawerOptions<T>,
): UseCrudDrawerReturn<T> {
  const [open, setOpen] = useState(false);
  const [editingRecord, setEditingRecord] = useState<T | null>(null);
  const [initialValues, setInitialValues] = useState<Record<string, unknown> | undefined>(undefined);
  const { execute, loading } = useApiRequest();

  const openCreate = useCallback((defaults?: Record<string, unknown>) => {
    setEditingRecord(null);
    setInitialValues(defaults);
    setOpen(true);
  }, []);

  const openEdit = useCallback((record: T, fieldMap?: (record: T) => Record<string, unknown>) => {
    setEditingRecord(record);
    setInitialValues(fieldMap ? fieldMap(record) : (record as unknown as Record<string, unknown>));
    setOpen(true);
  }, []);

  const close = useCallback(() => {
    setOpen(false);
    setEditingRecord(null);
    setInitialValues(undefined);
  }, []);

  const handleSubmit = useCallback(
    async (values: Record<string, unknown>) => {
      if (editingRecord) {
        await execute(
          () => options.onUpdate(options.getId(editingRecord), { ...values, version: (editingRecord as unknown as { version: number }).version }),
          '更新成功',
        );
      } else {
        await execute(() => options.onCreate(values), '创建成功');
      }
      close();
      options.onSuccess?.();
    },
    [editingRecord, options, close, execute],
  );

  return {
    open,
    editingRecord,
    initialValues,
    openCreate,
    openEdit,
    close,
    handleSubmit,
    loading,
  };
}
