"use server";

import { pollTaskUntilSettled } from "@/actions/task/poll";
import { apiBaseUrl, getAuthHeaders } from "@/lib";
import { handleApiError } from "@/lib/server-actions-helper";
import type {
  IntegrationProps,
  JiraDispatchRequest,
  JiraDispatchResponse,
} from "@/types/integrations";

export const getJiraIssueTypes = async (
  integrationId: string,
  projectKey: string,
): Promise<
  { success: true; issueTypes: string[] } | { success: false; error: string }
> => {
  const headers = await getAuthHeaders({ contentType: false });
  const url = new URL(
    `${apiBaseUrl}/integrations/${integrationId}/jira/issue_types`,
  );
  url.searchParams.append("project_key", projectKey);

  try {
    const response = await fetch(url.toString(), { method: "GET", headers });

    if (response.ok) {
      const data: {
        data: { type: string; attributes: { issue_types: string[] } };
      } = await response.json();
      return {
        success: true,
        issueTypes: data.data?.attributes?.issue_types ?? [],
      };
    }

    const errorData: unknown = await response.json().catch(() => ({}));
    const errorMessage =
      (errorData as { errors?: { detail?: string }[] }).errors?.[0]?.detail ||
      `Unable to fetch issue types: ${response.statusText}`;
    return { success: false, error: errorMessage };
  } catch (error) {
    const errorResult = handleApiError(error);
    return { success: false, error: errorResult.error || "An error occurred" };
  }
};

export const getJiraIntegrations = async (): Promise<
  | { success: true; data: IntegrationProps[] }
  | { success: false; error: string }
> => {
  const headers = await getAuthHeaders({ contentType: false });
  const url = new URL(`${apiBaseUrl}/integrations`);

  // Filter for Jira integrations only
  url.searchParams.append("filter[integration_type]", "jira");

  try {
    const response = await fetch(url.toString(), { method: "GET", headers });

    if (response.ok) {
      const data: { data: IntegrationProps[] } = await response.json();
      // Filter for enabled integrations on the client side
      const enabledIntegrations = (data.data || []).filter(
        (integration: IntegrationProps) =>
          integration.attributes.enabled === true,
      );
      return { success: true, data: enabledIntegrations };
    }

    const errorData: unknown = await response.json().catch(() => ({}));
    const errorMessage =
      (errorData as { errors?: { detail?: string }[] }).errors?.[0]?.detail ||
      `Unable to fetch Jira integrations: ${response.statusText}`;
    return { success: false, error: errorMessage };
  } catch (error) {
    const errorResult = handleApiError(error);
    return { success: false, error: errorResult.error || "An error occurred" };
  }
};

export const sendFindingToJira = async (
  integrationId: string,
  findingId: string,
  projectKey: string,
  issueType: string,
): Promise<
  | { success: true; taskId: string; message: string }
  | { success: false; error: string }
> => {
  const headers = await getAuthHeaders({ contentType: true });
  const url = new URL(
    `${apiBaseUrl}/integrations/${integrationId}/jira/dispatches`,
  );

  // Single finding: use direct filter without array notation
  url.searchParams.append("filter[finding_id]", findingId);

  const payload: JiraDispatchRequest = {
    data: {
      type: "integrations-jira-dispatches",
      attributes: {
        project_key: projectKey,
        issue_type: issueType,
      },
    },
  };

  try {
    const response = await fetch(url.toString(), {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
    });

    if (response.ok) {
      const data: JiraDispatchResponse = await response.json();
      const taskId = data?.data?.id;

      if (taskId) {
        return {
          success: true,
          taskId,
          message: "Jira issue creation started. Processing...",
        };
      } else {
        return {
          success: false,
          error: "Failed to start Jira dispatch. No task ID received.",
        };
      }
    }

    const errorData: unknown = await response.json().catch(() => ({}));
    const errorMessage =
      (errorData as { errors?: { detail?: string }[] }).errors?.[0]?.detail ||
      `Unable to send finding to Jira: ${response.statusText}`;
    return { success: false, error: errorMessage };
  } catch (error) {
    const errorResult = handleApiError(error);
    return { success: false, error: errorResult.error || "An error occurred" };
  }
};

export const pollJiraDispatchTask = async (
  taskId: string,
): Promise<
  { success: true; message: string } | { success: false; error: string }
> => {
  const res = await pollTaskUntilSettled(taskId, {
    maxAttempts: 30,
    delayMs: 2000,
  });
  if (!res.ok) {
    return { success: false, error: res.error };
  }
  const { state, result } = res;
  type JiraTaskResult = JiraDispatchResponse["data"]["attributes"]["result"];
  const jiraResult = result as JiraTaskResult | undefined;

  if (state === "completed") {
    const createdCount = jiraResult?.created_count ?? 0;
    const failedCount = jiraResult?.failed_count ?? 0;
    if (!jiraResult?.error && failedCount === 0 && createdCount > 0) {
      return { success: true, message: "Finding successfully sent to Jira!" };
    }
    return {
      success: false,
      error:
        jiraResult?.error ||
        (failedCount > 1
          ? `Failed to create ${failedCount} Jira issues.`
          : "Failed to create Jira issue."),
    };
  }

  if (state === "failed") {
    return { success: false, error: jiraResult?.error || "Task failed." };
  }

  return { success: false, error: `Unknown task state: ${state}` };
};
