import { PageOfDashboards } from 'jira.js/out/version2/models/pageOfDashboards.js';
import { AtlassianConfig, logger, getJiraV2Client, getAgileClient } from './atlassian-api-base.js';


// Get list of Jira dashboards (all)
export async function getDashboards(config: AtlassianConfig, startAt = 0, maxResults = 50): Promise<PageOfDashboards> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.dashboards.getAllDashboards({ startAt, maxResults });
}

// Get list of Jira dashboards owned by current user (my dashboards)
export async function getMyDashboards(config: AtlassianConfig, startAt = 0, maxResults = 50): Promise<PageOfDashboards> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.dashboards.getAllDashboards({ filter: "my", startAt, maxResults });
}

// Get Jira dashboard by ID
export async function getDashboardById(config: AtlassianConfig, dashboardId: string): Promise<any> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.dashboards.getDashboard({ id: dashboardId });
}

// Get gadgets (widgets) of a Jira dashboard
export async function getDashboardGadgets(config: AtlassianConfig, dashboardId: string): Promise<any> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.dashboards.getAllGadgets({ dashboardId: Number(dashboardId) });
}

// Get Jira issue by key or id
export async function getIssue(config: AtlassianConfig, issueIdOrKey: string): Promise<any> {
  try {
    const jiraClient = getJiraV2Client(config);
    return await jiraClient.issues.getIssue({
      issueIdOrKey,
      expand: 'renderedFields,names,schema,operations'
    });
  } catch (error: any) {
    logger.error(`Error getting issue ${issueIdOrKey}:`, error);
    throw error;
  }
}

// Search issues by JQL
export async function searchIssues(config: AtlassianConfig, jql: string, maxResults: number = 50): Promise<any> {
  try {
    const jiraClient = getJiraV2Client(config);
    return await jiraClient.issueSearch.searchForIssuesUsingJql({
      jql,
      maxResults,
      expand: "names,schema,operations"
    });
  } catch (error: any) {
    logger.error(`Error searching issues:`, error);
    throw error;
  }
}

// Get list of Jira filters
export async function getFilters(config: AtlassianConfig, startAt = 0, maxResults = 50): Promise<any> {
  const jiraClient = getJiraV2Client(config);
  // jira.js might map 'filter/search' to getMyFilters if no params, but likely has searchFilters or similar.
  // Checking jira.js source online, client.filters.search({...}) is common, but let's try assuming standard naming
  // Based on error logs or successful test, we might need to adjust.
  // Usually client.filters.getFilters refers to getting list.
  // Actually, 'getFilters' in API v3 returns a list of filters.
  // But wait, the original code used `/rest/api/3/filter/search`.
  // jira.js equivalent for filter search.
  // Let's try client.filters.search({ startAt, maxResults }) if available, or just getMyFilters?
  // No, getMyFilters is specific.
  // Actually, jira.js usually exposes 'search' under 'filters'.
  return (jiraClient.filters as any).search({ startAt, maxResults });
}

// Get Jira filter by ID
export async function getFilterById(config: AtlassianConfig, filterId: string): Promise<any> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.filters.getFilter({ id: Number(filterId) });
}

// Get filters owned by or shared with the current user
export async function getMyFilters(config: AtlassianConfig): Promise<any[]> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.filters.getMyFilters();
}

// Get list of Jira boards (Agile)
export async function getBoards(config: AtlassianConfig, startAt = 0, maxResults = 50): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.board.getAllBoards({ startAt, maxResults });
}

// Get Jira board by ID (Agile)
export async function getBoardById(config: AtlassianConfig, boardId: string): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.board.getBoard({ boardId: Number(boardId) });
}

// Get issues in a Jira board (Agile)
export async function getBoardIssues(config: AtlassianConfig, boardId: string, startAt = 0, maxResults = 50): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.board.getIssuesForBoard({
    boardId: Number(boardId),
    startAt,
    maxResults
  });
}

// Get list of sprints in a Jira board (Agile)
export async function getSprintsByBoard(config: AtlassianConfig, boardId: string, startAt = 0, maxResults = 50): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.board.getAllSprints({
    boardId: Number(boardId),
    startAt,
    maxResults
  });
}

// Get Jira sprint by ID (Agile)
export async function getSprintById(config: AtlassianConfig, sprintId: string): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.sprint.getSprint({ sprintId: Number(sprintId) });
}

// Get issues in a Jira sprint (Agile)
export async function getSprintIssues(config: AtlassianConfig, sprintId: string, startAt = 0, maxResults = 50): Promise<any> {
  const agileClient = getAgileClient(config);
  return agileClient.sprint.getIssuesForSprint({
    sprintId: Number(sprintId),
    startAt,
    maxResults
  });
}

export async function getProjects(config: AtlassianConfig): Promise<any[]> {
  const jiraClient = getJiraV2Client(config);
  // jira.js searchProjects uses /project/search which might not exist on all instances (returns 404).
  // We use sendRequest to call /rest/api/3/project directly which returns a list of all projects.
  return await (jiraClient as any).sendRequest({
    url: '/rest/api/2/project',
    method: 'GET'
  });
}

export async function getProject(config: AtlassianConfig, projectKey: string): Promise<any> {
  const jiraClient = getJiraV2Client(config);
  return jiraClient.projects.getProject({ projectIdOrKey: projectKey });
} 