import { ContentTypeEnum } from '@vben/request';

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

export type DmsFileCenterMode = 'CURRENT' | 'HISTORICAL';

export interface DmsApiResult<T> {
  code: number;
  data: T;
  msg?: string;
}

export interface DmsCursorPage<T> {
  hasMore: boolean;
  list: T[];
  nextCursor?: string;
}

export interface DmsFolderTreeItem {
  hasChildren: boolean;
  id: string;
  name: string;
  parentId?: string;
  sortCode?: number;
}

export interface DmsVersionExtendedProperties {
  prepared_by_name?: string;
  reviewers?: { name: string; user_id: string }[];
}

export interface DmsFileCenterItem {
  extendedProperties?: DmsVersionExtendedProperties;
  checksumSha256?: string;
  createdAt: string;
  documentId?: string;
  documentNo?: string;
  documentType?: string;
  invalidatedAt?: string;
  revokedAt?: string;
  statusReason?: string;
  effectiveFrom?: string;
  effectiveTo?: string;
  fileName?: string;
  id: string;
  lifecycleStatus?: 'EFFECTIVE' | 'EXPIRED' | 'INVALIDATED' | 'OBSOLETE' | 'REVOKED' | 'SUPERSEDED';
  mimeType?: string;
  name: string;
  parentId?: string;
  preparedBy?: string;
  preparedOn?: string;
  reviewCycleMonths?: number;
  lastReviewedOn?: string;
  nextReviewOn?: string;
  resourceType: 'DOCUMENT' | 'FILE_VERSION' | 'FOLDER';
  responsibleDeptId?: string;
  revision?: number;
  sizeBytes?: number;
  sortCode?: number;
  versionLabel?: string;
  versionNo?: number;
}

export interface DmsPermissionDecision {
  actionCode: 'CREATE' | 'DELETE' | 'READ' | 'UPDATE';
  allowed: boolean;
  reasonCode: string;
  resourceId: string;
  resourceType: 'DOCUMENT' | 'FILE_VERSION' | 'FOLDER';
}

export interface DmsFileUploadMetadata {
  documentName: string;
  documentNo: string;
  documentType: string;
  preparedBy: string;
  preparedOn: string;
  responsibleDeptId: string;
  versionLabel: string;
}

export interface DmsFileRevisionMetadata {
  preparedBy: string;
  preparedOn: string;
  revisionReason: string;
  versionLabel: string;
}

export type DmsAuditSignParameters = Record<string, string | string[]>;

export interface DmsFileOperationLogItem {
  id: number;
  occurredAt: string;
  operationCode: 'DOWNLOAD' | 'REVISION' | 'UPLOAD' | 'VIEW';
  operationContent: string;
}

export interface DmsFileOperationLogPage {
  currentPage: number;
  list: DmsFileOperationLogItem[];
  pageSize: number;
  total: number;
}

const prefix = '/api/dms';
const silentErrorOptions = { errorMessageMode: 'none' as const };

export function getRootFolders(params: { cursor?: string; pageSize?: number }) {
  return defHttp.get<DmsApiResult<DmsCursorPage<DmsFileCenterItem>>>({ url: `${prefix}/folders/root/children`, params }, silentErrorOptions);
}

export function getChildFolders(folderId: string, params: { cursor?: string; pageSize?: number }) {
  return defHttp.get<DmsApiResult<DmsCursorPage<DmsFileCenterItem>>>({ url: `${prefix}/folders/${folderId}/children`, params }, silentErrorOptions);
}

/** 获取 DMS 目录选择树的一层目录。 */
export function getDmsFolderTree(params: { cursor?: string; pageSize?: number; parentId?: string } = {}) {
  return defHttp.get<DmsApiResult<DmsCursorPage<DmsFolderTreeItem>>>({ url: `${prefix}/folders/tree`, params }, silentErrorOptions);
}

export function getFolderFiles(mode: DmsFileCenterMode, folderId: string, params: { cursor?: string; keyword?: string; pageSize?: number }) {
  const endpoint = mode === 'HISTORICAL' ? 'historical-versions' : 'documents';
  return defHttp.get<DmsApiResult<DmsCursorPage<DmsFileCenterItem>>>({ url: `${prefix}/folders/${folderId}/${endpoint}`, params }, silentErrorOptions);
}

export function getDocumentVersions(mode: DmsFileCenterMode, documentId: string, params: { cursor?: string; keyword?: string; pageSize?: number }) {
  return defHttp.get<DmsApiResult<DmsCursorPage<DmsFileCenterItem>>>(
    { url: `${prefix}/documents/${documentId}/versions`, params: { ...params, center: mode } },
    silentErrorOptions,
  );
}

export function getFileOperationLogs(fileVersionId: string, params: { currentPage?: number; keyword?: string; pageSize?: number }) {
  return defHttp.get<DmsApiResult<DmsFileOperationLogPage>>({ url: `${prefix}/file-versions/${fileVersionId}/operation-logs`, params }, silentErrorOptions);
}

export function evaluateFolderCreate(folderId: string) {
  return defHttp.post<DmsApiResult<DmsPermissionDecision>>(
    { url: `${prefix}/permission-decisions/evaluate`, data: { actionCode: 'CREATE', resourceId: folderId, resourceType: 'FOLDER' } },
    silentErrorOptions,
  );
}

export function evaluateDocumentUpdate(documentId: string) {
  return defHttp.post<DmsApiResult<DmsPermissionDecision>>(
    { url: `${prefix}/permission-decisions/evaluate`, data: { actionCode: 'UPDATE', resourceId: documentId, resourceType: 'DOCUMENT' } },
    silentErrorOptions,
  );
}

export function createFolder(data: { name: string; parentId: string; sourceId: string }) {
  return defHttp.post<DmsApiResult<DmsFileCenterItem>>({ url: `${prefix}/folders`, data }, silentErrorOptions);
}

export function uploadFile(folderId: string, sourceId: string, file: File, metadata: DmsFileUploadMetadata, auditSignParameters?: DmsAuditSignParameters) {
  const data = new FormData();
  data.append('folderId', folderId);
  data.append('sourceId', sourceId);
  data.append('documentNo', metadata.documentNo);
  data.append('documentName', metadata.documentName);
  data.append('documentType', metadata.documentType);
  data.append('responsibleDeptId', metadata.responsibleDeptId);
  data.append('versionLabel', metadata.versionLabel);
  data.append('preparedBy', metadata.preparedBy);
  data.append('preparedOn', metadata.preparedOn);
  appendAuditSigns(data, auditSignParameters);
  data.append('file', file);
  return defHttp.post<DmsApiResult<unknown>>(
    { url: '/api/file/Dms/Uploader', data, headers: { 'Content-Type': ContentTypeEnum.FORM_DATA } },
    silentErrorOptions,
  );
}

export function reviseFile(
  documentId: string,
  baseFileVersionId: string,
  sourceId: string,
  file: File,
  metadata: DmsFileRevisionMetadata,
  auditSignParameters?: DmsAuditSignParameters,
) {
  const data = new FormData();
  data.append('documentId', documentId);
  data.append('baseFileVersionId', baseFileVersionId);
  data.append('sourceId', sourceId);
  data.append('versionLabel', metadata.versionLabel);
  data.append('preparedBy', metadata.preparedBy);
  data.append('preparedOn', metadata.preparedOn);
  data.append('revisionReason', metadata.revisionReason);
  appendAuditSigns(data, auditSignParameters);
  data.append('file', file);
  return defHttp.post<DmsApiResult<unknown>>(
    { url: '/api/file/Dms/Revisions', data, headers: { 'Content-Type': ContentTypeEnum.FORM_DATA } },
    silentErrorOptions,
  );
}

function appendAuditSigns(data: FormData, parameters?: DmsAuditSignParameters) {
  if (!parameters) return;
  Object.entries(parameters).forEach(([name, rawValue]) => {
    if (!name.toLowerCase().endsWith('_sign')) return;
    const values = Array.isArray(rawValue) ? rawValue : [rawValue];
    values.forEach((value) => {
      const signId = value?.trim();
      if (signId) data.append(name, signId);
    });
  });
}
