import type {
  RequestResult,
  SkillCategory,
  SkillCategoryDraft,
  SkillFileContent,
  SkillFileNode,
  SkillGitScanResult,
  SkillImportBatchResult,
  SkillImportConfirmPayload,
  SkillImportPreview,
  SkillInfo,
  SkillMcpToolManifest,
  SkillToolBinding,
  SkillToolOptionPage,
  SkillToolType,
  SkillValidationResult,
} from './types';

import { api } from '#/api/request';

import { buildSkillCategoryPayload } from './skill-category';
import { buildSkillDraftPayload } from './skill-draft';

export function getSkillDetail(id: number | string) {
  return api.get<RequestResult<SkillInfo>>('/api/v1/skill/detail', {
    params: { id },
  });
}

export function getSkillToolOptions(params: {
  keyword?: string;
  pageNum?: number;
  pageSize?: number;
  toolType?: SkillToolType;
}) {
  return api.get<RequestResult<SkillToolOptionPage>>(
    '/api/v1/skill/toolOptions',
    { params },
  );
}

export function getSkillMcpTools(mcpId: number | string) {
  return api.get<RequestResult<SkillMcpToolManifest>>(
    '/api/v1/skill/mcpTools',
    { params: { mcpId } },
  );
}

export function updateSkillToolBindings(
  skillId: number | string,
  bindings: SkillToolBinding[],
) {
  return api.post<RequestResult<SkillToolBinding[]>>(
    '/api/v1/skill/toolBinding/update',
    {
      bindings: bindings.map((binding, sortNo) => ({
        hitlEnabled: Boolean(binding.hitlEnabled),
        mcpToolManifestHash:
          binding.toolType === 'MCP' ? binding.mcpToolManifestHash : undefined,
        sortNo,
        targetId: binding.targetId,
        toolType: binding.toolType,
      })),
      skillId,
    },
  );
}

export function saveSkill(skill: SkillInfo) {
  return api.post<RequestResult<SkillInfo>>(
    '/api/v1/skill/save',
    buildSkillDraftPayload(skill, false),
  );
}

export function updateSkill(skill: SkillInfo) {
  return api.post<RequestResult<SkillInfo>>(
    '/api/v1/skill/update',
    buildSkillDraftPayload(skill, true),
  );
}

export function copySkill(payload: {
  categoryId?: number | string;
  displayName: string;
  name: string;
  sourceId: number | string;
}) {
  return api.post<RequestResult<SkillInfo>>('/api/v1/skill/copy', payload);
}

export function validateSkillForPublish(id: number | string) {
  return api.post<RequestResult<SkillValidationResult>>(
    '/api/v1/skill/validatePublish',
    { id },
  );
}

export function getSkillCategories() {
  return api.get<RequestResult<SkillCategory[]>>(
    '/api/v1/skill/category/visibleList',
    { params: { sortKey: 'sortNo', sortType: 'asc' } },
  );
}

export function getSkillCategoryTree() {
  return api.get<RequestResult<SkillCategory[]>>(
    '/api/v1/skill/category/tree',
    { params: { sortKey: 'sortNo', sortType: 'asc' } },
  );
}

export function saveSkillCategory(category: SkillCategoryDraft) {
  return api.post<RequestResult<SkillCategory>>(
    '/api/v1/skill/category/save',
    buildSkillCategoryPayload(category, false),
  );
}

export function updateSkillCategory(category: SkillCategoryDraft) {
  return api.post<RequestResult<SkillCategory>>(
    '/api/v1/skill/category/update',
    buildSkillCategoryPayload(category, true),
  );
}

export function deleteSkillCategory(id: number | string) {
  return api.post<RequestResult<void>>('/api/v1/skill/category/remove', { id });
}

export function submitSkillPublishApproval(
  id: number | string,
  applicationReason: string,
) {
  return api.post<RequestResult<null | number | string>>(
    '/api/v1/skill/submitPublishApproval',
    { applicationReason, id },
  );
}

export function submitSkillOfflineApproval(id: number | string) {
  return api.post<RequestResult<null | number | string>>(
    '/api/v1/skill/submitOfflineApproval',
    { id },
  );
}

export function submitSkillDeleteApproval(id: number | string) {
  return api.post<RequestResult<null | number | string>>(
    '/api/v1/skill/submitDeleteApproval',
    { id },
  );
}

export function getSkillFileTree(skillId: number | string) {
  return api.get<RequestResult<SkillFileNode[]>>('/api/v1/skill/file/tree', {
    params: { skillId },
  });
}

export function getSkillFileContent(skillId: number | string, path: string) {
  return api.get<RequestResult<SkillFileContent>>(
    '/api/v1/skill/file/content',
    { params: { path, skillId } },
  );
}

export function saveSkillFile(
  skillId: number | string,
  path: string,
  content: string,
  expectedContentHash?: string,
) {
  return api.post<RequestResult<SkillFileContent>>('/api/v1/skill/file/save', {
    content,
    expectedContentHash,
    path,
    skillId,
  });
}

export function createSkillFile(
  skillId: number | string,
  path: string,
  content = '',
) {
  return api.post<RequestResult<SkillFileContent>>(
    '/api/v1/skill/file/create',
    {
      content,
      path,
      skillId,
    },
  );
}

export function renameSkillFile(
  skillId: number | string,
  path: string,
  newPath: string,
  expectedContentHash: string,
) {
  return api.post<RequestResult<SkillFileContent>>(
    '/api/v1/skill/file/rename',
    {
      expectedContentHash,
      newPath,
      path,
      skillId,
    },
  );
}

export function deleteSkillFile(
  skillId: number | string,
  path: string,
  expectedContentHash: string,
) {
  return api.post<RequestResult<void>>('/api/v1/skill/file/delete', {
    expectedContentHash,
    path,
    skillId,
  });
}

export function uploadSkillFile(
  skillId: number | string,
  path: string,
  file: File,
  expectedContentHash?: string,
) {
  const formData = new FormData();
  formData.append('skillId', String(skillId));
  formData.append('path', path);
  if (expectedContentHash)
    formData.append('expectedContentHash', expectedContentHash);
  formData.append('file', file);
  return api.postFile<RequestResult<SkillFileContent>>(
    '/api/v1/skill/file/upload',
    formData,
  );
}

export function downloadSkillFile(skillId: number | string, path: string) {
  return api.download<Blob>('/api/v1/skill/file/download', {
    params: { path, skillId },
  });
}

export function previewSkillFile(skillId: number | string, path: string) {
  return api.download<Blob>('/api/v1/skill/file/preview', {
    params: { path, skillId },
  });
}

export function importSkillPreviews(files: File[]) {
  const formData = new FormData();
  files.forEach((file) => formData.append('files', file));
  return api.postFile<RequestResult<SkillImportPreview[]>>(
    '/api/v1/skill/import/preview',
    formData,
  );
}

export function scanSkillGitRepository(repositoryUrl: string) {
  return api.post<RequestResult<SkillGitScanResult>>(
    '/api/v1/skill/import/repository/scan',
    { repositoryUrl },
  );
}

export function prepareSkillGitCandidates(
  scanToken: string,
  candidateIds: string[],
) {
  return api.post<RequestResult<SkillImportPreview[]>>(
    '/api/v1/skill/import/repository/prepare',
    { candidateIds, scanToken },
  );
}

export function importSkillConfirmBatch(payload: SkillImportConfirmPayload[]) {
  return api.post<RequestResult<SkillImportBatchResult[]>>(
    '/api/v1/skill/import/confirmBatch',
    payload,
  );
}

export function cancelSkillImport(importToken: string) {
  return api.post<RequestResult<void>>('/api/v1/skill/import/cancel', {
    importToken,
  });
}

export function exportSkills(ids: Array<number | string>) {
  return api.download<Blob>('/api/v1/skill/export', {
    data: { ids },
    method: 'POST',
  });
}
