import { auth } from "../auth";
import { entityRegistry, ensureInitialized } from "../entities/registry";
import {
  createApiResponse,
  createApiError,
  parsePaginationParams,
  createPaginationMeta,
  parseMetaParams,
  includeEntityMetadata,
  processEntityMetadata,
  handleEntityMetadataInResponse
} from "./helpers";
import { afterEntityCreate, afterEntityUpdate, afterEntityDelete } from "../entities/entity-hooks";
async function checkBasicAuth(request, entityName) {
  try {
    const session = await auth.api.getSession({ headers: request.headers });
    if (!session) {
      return {
        allowed: false,
        response: createApiError("Authentication required", 401)
      };
    }
    await ensureInitialized();
    const entity = entityRegistry.get(entityName);
    if (!entity) {
      return {
        allowed: false,
        response: createApiError("Entity not found", 404)
      };
    }
    return {
      allowed: true,
      user: {
        id: session.user.id,
        email: session.user.email,
        role: session.user.role || "user"
      },
      entity
    };
  } catch {
    return {
      allowed: false,
      response: createApiError("Authentication failed", 401)
    };
  }
}
function createEntityHandlers(entityName, handlers, options = {}) {
  console.warn(`createEntityHandlers is deprecated. Use createEntityListHandlers or createEntityDetailHandlers instead for ${entityName}`);
  return createEntityListHandlers(entityName, handlers, options);
}
function withEntityAuth(entityName, action, options = {}) {
  return function(handler) {
    return async function(request, ...args) {
      try {
        const authCheck = await checkBasicAuth(request, entityName);
        if (!authCheck.allowed) {
          return authCheck.response;
        }
        const context = {
          user: authCheck.user,
          entity: authCheck.entity,
          request
        };
        if (action === "read" && request.method === "GET") {
          context.pagination = parsePaginationParams(request);
        }
        if (options.customValidation) {
          const validationResult = await options.customValidation(context);
          if (!validationResult.valid) {
            return createApiError(
              validationResult.error || "Custom validation failed",
              400
            );
          }
        }
        return await handler(context, ...args);
      } catch (error) {
        console.error(`Error in ${entityName} ${action} handler:`, error);
        return createApiError(
          "Internal server error",
          500,
          process.env.NODE_ENV === "development" ? error : void 0
        );
      }
    };
  };
}
function createEntityListHandlers(entityName, handlers, options = {}) {
  async function GET(request) {
    const authCheck = await checkBasicAuth(request, entityName);
    if (!authCheck.allowed) {
      return authCheck.response;
    }
    const user = authCheck.user;
    const entity = authCheck.entity;
    const handlerContext = {
      user,
      entity,
      request,
      pagination: parsePaginationParams(request)
    };
    try {
      if (!handlers.list) {
        return createApiError("List operation not supported", 404);
      }
      const result = await handlers.list(handlerContext);
      const { data, total } = result;
      const metaParams = parseMetaParams(request);
      let dataWithMeta = data;
      if (options.allowMetadata && metaParams.includeMetadata) {
        dataWithMeta = await includeEntityMetadata(
          entityName,
          data,
          metaParams,
          user.id
        );
      }
      const pagination = handlerContext.pagination;
      const paginationMeta = pagination ? createPaginationMeta(pagination.page, pagination.limit, total) : {};
      return createApiResponse(dataWithMeta, paginationMeta);
    } catch (error) {
      console.error(`Error in ${entityName} GET handler:`, error);
      return createApiError(
        "Internal server error",
        500,
        process.env.NODE_ENV === "development" ? error : void 0
      );
    }
  }
  async function POST(request) {
    const authCheck = await checkBasicAuth(request, entityName);
    if (!authCheck.allowed) {
      return authCheck.response;
    }
    const user = authCheck.user;
    const entity = authCheck.entity;
    const handlerContext = {
      user,
      entity,
      request
    };
    try {
      if (!handlers.create) {
        return createApiError("Create operation not supported", 405);
      }
      let body;
      try {
        body = await request.json();
      } catch {
        return createApiError("Invalid JSON body", 400);
      }
      const { metas, ...entityData } = body;
      const createdItem = await handlers.create(handlerContext, entityData);
      try {
        await afterEntityCreate(entityName, createdItem, user.id);
      } catch (hookError) {
        console.error(`[entity-handler] Error in afterEntityCreate hook for ${entityName}:`, hookError);
      }
      const metadataWasProvided = metas && typeof metas === "object" && Object.keys(metas).length > 0;
      if (metadataWasProvided && options.allowMetadata) {
        await processEntityMetadata(entityName, createdItem.id, metas, user.id);
      }
      let responseData = createdItem;
      if (options.allowMetadata) {
        responseData = await handleEntityMetadataInResponse(
          entityName,
          createdItem,
          metadataWasProvided,
          user.id
        );
      }
      return createApiResponse(responseData, {}, 201);
    } catch (error) {
      console.error(`Error in ${entityName} POST handler:`, error);
      return createApiError(
        "Internal server error",
        500,
        process.env.NODE_ENV === "development" ? error : void 0
      );
    }
  }
  return {
    GET,
    POST
  };
}
function createEntityDetailHandlers(entityName, handlers, options = {}) {
  async function GET(request, routeContext) {
    const authCheck = await checkBasicAuth(request, entityName);
    if (!authCheck.allowed) {
      return authCheck.response;
    }
    const user = authCheck.user;
    const entity = authCheck.entity;
    const params = await routeContext.params;
    const { id } = params;
    const handlerContext = {
      user,
      entity,
      request
    };
    try {
      if (!handlers.read) {
        return createApiError("Read operation not supported", 404);
      }
      const item = await handlers.read(handlerContext, id);
      if (!item) {
        return createApiError("Item not found", 404);
      }
      const metaParams = parseMetaParams(request);
      let itemWithMeta = item;
      if (options.allowMetadata && metaParams.includeMetadata) {
        const items = await includeEntityMetadata(
          entityName,
          [item],
          metaParams,
          user.id
        );
        itemWithMeta = items[0] || item;
      }
      return createApiResponse(itemWithMeta);
    } catch (error) {
      console.error(`Error in ${entityName} GET handler:`, error);
      return createApiError(
        "Internal server error",
        500,
        process.env.NODE_ENV === "development" ? error : void 0
      );
    }
  }
  async function PATCH(request, routeContext) {
    const authCheck = await checkBasicAuth(request, entityName);
    if (!authCheck.allowed) {
      return authCheck.response;
    }
    const user = authCheck.user;
    const entity = authCheck.entity;
    const params = await routeContext.params;
    const { id } = params;
    const handlerContext = {
      user,
      entity,
      request
    };
    try {
      if (!handlers.update) {
        return createApiError("Update operation not supported", 405);
      }
      let body;
      try {
        body = await request.json();
      } catch {
        return createApiError("Invalid JSON body", 400);
      }
      const { metas, ...entityData } = body;
      const updatedItem = await handlers.update(handlerContext, id, entityData);
      if (!updatedItem) {
        return createApiError("Item not found", 404);
      }
      try {
        await afterEntityUpdate(entityName, id, updatedItem, entityData, user.id);
      } catch (hookError) {
        console.error(`[entity-handler] Error in afterEntityUpdate hook for ${entityName}:`, hookError);
      }
      const metadataWasProvided = metas && typeof metas === "object" && Object.keys(metas).length > 0;
      if (metadataWasProvided && options.allowMetadata) {
        await processEntityMetadata(entityName, id, metas, user.id);
      }
      let responseData = updatedItem;
      if (options.allowMetadata) {
        responseData = await handleEntityMetadataInResponse(
          entityName,
          updatedItem,
          metadataWasProvided,
          user.id
        );
      }
      return createApiResponse(responseData);
    } catch (error) {
      console.error(`Error in ${entityName} PATCH handler:`, error);
      return createApiError(
        "Internal server error",
        500,
        process.env.NODE_ENV === "development" ? error : void 0
      );
    }
  }
  async function DELETE(request, routeContext) {
    const authCheck = await checkBasicAuth(request, entityName);
    if (!authCheck.allowed) {
      return authCheck.response;
    }
    const user = authCheck.user;
    const entity = authCheck.entity;
    const params = await routeContext.params;
    const { id } = params;
    const handlerContext = {
      user,
      entity,
      request
    };
    try {
      if (!handlers.delete) {
        return createApiError("Delete operation not supported", 405);
      }
      const success = await handlers.delete(handlerContext, id);
      if (!success) {
        return createApiError("Item not found", 404);
      }
      try {
        await afterEntityDelete(entityName, id, user.id);
      } catch (hookError) {
        console.error(`[entity-handler] Error in afterEntityDelete hook for ${entityName}:`, hookError);
      }
      return createApiResponse({ success: true, id });
    } catch (error) {
      console.error(`Error in ${entityName} DELETE handler:`, error);
      return createApiError(
        "Internal server error",
        500,
        process.env.NODE_ENV === "development" ? error : void 0
      );
    }
  }
  return {
    GET,
    PATCH,
    DELETE
  };
}
function withEntityAction(entityName, action, options = {}) {
  return withEntityAuth(entityName, action, options);
}
function createQueryContext(context) {
  return {
    userId: context.user.id,
    userRole: context.user.role,
    userFlags: [],
    entityConfig: context.entity
  };
}
export {
  createEntityDetailHandlers,
  createEntityHandlers,
  createEntityListHandlers,
  createQueryContext,
  withEntityAction,
  withEntityAuth
};
