import type {
  RequestResult,
  SkillCapabilityBinding,
  SkillCapabilityCandidate,
  SkillCapabilityReplaceResult,
  SkillCapabilityTools,
  SkillCapabilityType,
  SkillCategory,
  SkillCategoryDraft,
  SkillExportFormat,
  SkillFileContent,
  SkillFileNode,
  SkillImportPreview,
  SkillInfo,
  SkillValidationResult,
} from './types';

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

import { buildCapabilityBindingsPayload } from './skill-capability';
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 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) {
  return api.post<RequestResult<null | number | string>>(
    '/api/v1/skill/submitPublishApproval',
    { 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 getSkillCapabilityBindings(skillId: number | string) {
  return api.get<RequestResult<SkillCapabilityBinding[]>>(
    '/api/v1/skill/capability/list',
    {
      params: { skillId },
    },
  );
}

export function getSkillCapabilityCandidates(
  type: SkillCapabilityType,
  keyword = '',
) {
  return api.get<RequestResult<SkillCapabilityCandidate[]>>(
    '/api/v1/skill/capability/candidates',
    { params: { keyword, type } },
  );
}

export function getSkillCapabilityTools(targetId: number | string) {
  return api.get<RequestResult<SkillCapabilityTools>>(
    '/api/v1/skill/capability/tools',
    {
      params: { targetId },
    },
  );
}

export function replaceSkillCapabilityBindings(
  skillId: number | string,
  bindings: SkillCapabilityBinding[],
  expectedCapabilityHash: string,
) {
  return api.post<RequestResult<SkillCapabilityReplaceResult>>(
    '/api/v1/skill/capability/replace',
    {
      bindings: buildCapabilityBindingsPayload(bindings),
      expectedCapabilityHash,
      skillId,
    },
  );
}

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

export function importSkillConfirm(payload: {
  capabilityMappings?: Array<{
    bindingKey: string;
    disabled?: boolean;
    targetId?: number | string;
  }>;
  categoryId?: number | string;
  conflictStrategy: 'OVERWRITE' | 'REJECT' | 'RENAME';
  importToken: string;
  renames?: Record<string, string>;
}) {
  return api.post<RequestResult<SkillInfo[]>>(
    '/api/v1/skill/import/confirm',
    payload,
  );
}

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

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