import {
  MockEndpointAsset,
  RefObj,
  BaseAsset,
  MockEndpointSpec,
} from "../../../model/assets-model.js";
import { KindEnums } from "@apic/api-model/common/StudioEnums.js";
import { AssetCacheModel } from "../../../model/asset-cache-model.js";
import {
  checkForNullOrUndefined,
  isNullOrUndefined,
} from "../../common/data-helper.js";
import { showWarning } from "./../../common/message-helper.js";
import { MockEndpoint_Methods } from "@apic/api-model/mock/MockEndpoint.js";


const getRefsFromMockEndpointAsset = (asset: BaseAsset): AssetCacheModel[] => {
  const mockEndpointAsset = asset as unknown as MockEndpointAsset;
  const spec: MockEndpointSpec = mockEndpointAsset.spec;
  const result: AssetCacheModel[] = [];

  try {
    checkForNullOrUndefined(
      mockEndpointAsset,
      "MockEndpoint asset is null or undefined"
    );
    if (spec.paths) {
      const uniqueRefs = new Set<string>();

      for (const path in spec.paths) {
        const pathObject = spec.paths[path] as MockEndpoint_Methods;

        const httpMethods: (keyof MockEndpoint_Methods)[] = [
          "get",
          "post",
          "put",
          "patch",
          "delete",
          "head",
          "options",
          "trace",
        ];

        // Iterate over the valid HTTP methods
        for (const method of httpMethods) {
          const methodObject = pathObject[method];

          if (methodObject) {
            // Check defaultResponse
            if (methodObject.defaultResponse) {
              for (const statusCode in methodObject.defaultResponse) {
                const responseObj = methodObject.defaultResponse[statusCode];
                if (responseObj.response?.$ref) {
                  const refValue = responseObj.response.$ref;
                  // Only add if this $ref hasn't been seen before
                  if (!uniqueRefs.has(refValue)) {

                    uniqueRefs.add(refValue);

                    result.push({
                      kind: KindEnums.MockResponse,
                      isNewlyAdded: true,
                      ref: responseObj.response.$ref,
                    });
                  }
                }
              }
            }

            // Check conditionalResponse
            if (methodObject.conditionalResponse) {
              methodObject.conditionalResponse.forEach((condition, index) => {
                if (condition.response?.$ref) {
                  const refValue = condition.response.$ref;
                  // Only add if this $ref hasn't been seen before
                  if (!uniqueRefs.has(refValue)) {
                    uniqueRefs.add(refValue);
                    result.push({
                      kind: KindEnums.MockResponse,
                      isNewlyAdded: true,
                      ref: condition.response.$ref,
                    });
                  }
                }
              });
            }
          }
        }
      }
    }
    return result;
  } catch (error: unknown) {
    showWarning((error as Error).message);
    return [];
  }
};

export { getRefsFromMockEndpointAsset };
