import { buildBackendPayload } from "@/lib/diagnostic-status";

const STATUS_SUBMIT_ENDPOINT = "/api/diagnostic-status";

type SubmitDiagnosticStatusParams = {
  results: Record<string, any>;
  imei?: string;
  partnerName: string;
  redirectUrl?: string;
  requireRunContextInvalidation?: boolean;
};

type BackendDebugDetails = {
  request: {
    endpoint: string;
    partnerCode: string;
    imei: string;
    partnerName: string;
  };
  response: {
    status: number;
    statusText: string;
    body: string;
  } | null;
  error: string;
};

function buildRunContextUrl(partnerName: string, imei: string) {
  const params = new URLSearchParams({
    partner_name: partnerName,
    imei,
  });

  return `/api/run-context?${params.toString()}`;
}

function formatBackendDebugDetails({
  endpoint,
  partnerCode,
  payload,
  response = null,
  responseBody = null,
  error = null,
}: {
  endpoint: string;
  partnerCode: string;
  payload: any;
  response?: Response | null;
  responseBody?: unknown;
  error?: unknown;
}): BackendDebugDetails {
  const payloadData = payload?.data || {};
  const bodyText =
    typeof responseBody === "string"
      ? responseBody
      : responseBody
        ? JSON.stringify(responseBody)
        : "";

  return {
    request: {
      endpoint,
      partnerCode,
      imei: payloadData.imei || "",
      partnerName: payloadData.partner_name || "",
    },
    response: response
      ? {
          status: response.status,
          statusText: response.statusText,
          body: bodyText.length > 1200 ? `${bodyText.slice(0, 1200)}...` : bodyText,
        }
      : null,
    error:
      error instanceof Error
        ? error.message
        : error
          ? String(error)
          : "",
  };
}

export function buildDebugSummary(details?: BackendDebugDetails | null) {
  if (!details) return null;

  let responseBody: any = details.response?.body || "";

  try {
    responseBody = responseBody ? JSON.parse(responseBody) : "";
  } catch {
    // Keep plain text responses readable.
  }

  const upstream = responseBody?.data?.upstream;

  return {
    routeStatus: details.response?.status || "",
    routeMessage: responseBody?.message || details.error || "",
    backendStatus: upstream?.status || "",
    backendMessage:
      upstream?.body?.message ||
      upstream?.body?.error ||
      upstream?.statusText ||
      "",
    endpoint: responseBody?.data?.endpoint || details.request?.endpoint || "",
  };
}

export async function submitDiagnosticStatus({
  results,
  imei = "",
  partnerName,
  redirectUrl = "",
  requireRunContextInvalidation = false,
}: SubmitDiagnosticStatusParams) {
  let savedImei = "";
  let savedRedirectUrl = redirectUrl.trim();
  const hasGeneratedUrlContext = Boolean(
    requireRunContextInvalidation && partnerName && imei,
  );
  const contextUrl = hasGeneratedUrlContext
    ? buildRunContextUrl(partnerName, imei)
    : "";

  if (hasGeneratedUrlContext) {
    try {
      const contextResponse = await fetch(contextUrl);
      if (contextResponse.ok) {
        const contextJson = await contextResponse.json();
        savedImei = contextJson.data?.imei || "";
        savedRedirectUrl =
          contextJson.data?.redirect_url?.trim() || savedRedirectUrl;
      }
    } catch (error) {
      console.error("Unable to load saved run context:", error);
    }
  }

  const currentImei = imei || savedImei || "";
  const payload = buildBackendPayload(results, currentImei, partnerName);

  try {
    let backendResponse: Response | null = null;
    let backendResponseBody: unknown = null;
    console.log("Sending diagnostic test result to backend:", {
      endpoint: STATUS_SUBMIT_ENDPOINT,
      payload,
    });
    const response = await fetch(STATUS_SUBMIT_ENDPOINT, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(payload),
    });
    backendResponse = response;
    const responseText = await response.text();
    let responseBody: unknown = responseText;

    try {
      responseBody = JSON.parse(responseText);
    } catch {
      // Keep non-JSON backend responses readable in console output.
    }

    console.log("Received diagnostic backend response:", {
      ok: response.ok,
      status: response.status,
      statusText: response.statusText,
      body: responseBody,
    });
    backendResponseBody = responseBody;

    if (!response.ok) {
      return {
        status: {
          type: "error",
          message: "Could not send status. Please try again.",
          details: formatBackendDebugDetails({
            endpoint: STATUS_SUBMIT_ENDPOINT,
            partnerCode: "",
            payload,
            response: backendResponse,
            responseBody: backendResponseBody,
            error: `Backend returned ${response.status}`,
          }),
        },
      };
    }

    let contextInvalidated = false;

    if (hasGeneratedUrlContext) {
      try {
        const invalidateResponse = await fetch(contextUrl, {
          method: "DELETE",
        });

        contextInvalidated = invalidateResponse.ok;

        if (!contextInvalidated) {
          console.warn("Unable to invalidate run context after completion.");
        }
      } catch (error) {
        console.warn("Run context invalidation request failed:", error);
      }
    }

    if (hasGeneratedUrlContext && !contextInvalidated) {
      return {
        status: {
          type: "error",
          message: "Result saved, but the test URL could not be invalidated.",
        },
      };
    }

    return {
      status: {
        type: "success",
        message: "Result Saved Successfully",
      },
      redirectUrl: savedRedirectUrl,
    };
  } catch (error) {
    console.error("Backend status send failed:", error);

    return {
      status: {
        type: "error",
        message: "Could not send status. Please try again.",
        details: formatBackendDebugDetails({
          endpoint: STATUS_SUBMIT_ENDPOINT,
          partnerCode: "",
          payload,
          error,
        }),
      },
    };
  }
}
