import type { AuditEventDetail, AuditOperation, AuditOperationPage } from '../../audit/events/types';

import type { AuditEventDetailDTO, AuditEventId, DmsFolderAuditPageQuery } from '#/api/x/audit/events';

import { getDmsFolderAuditDetail, getDmsFolderAuditPage, getDmsFolderAuditTimeline } from '#/api/x/audit/events';
import { parseAuditEventFieldDiffs } from '#/components/FormExtraPanel/auditDiff';

import { groupTimelineOperations, normalizeOperation } from '../../audit/events/auditOperation';

const detailCache = new Map<string, AuditEventDetail>();

export const folderAuditOperationQuery = {
  async detail(eventId: AuditEventId): Promise<AuditEventDetail> {
    const cacheKey = String(eventId);
    const cached = detailCache.get(cacheKey);
    if (cached) return cached;

    const response = await getDmsFolderAuditDetail(eventId);
    const bundle = response.data;
    if (!bundle?.business) throw new Error('DMS_FOLDER_AUDIT_NOT_FOUND');

    const business = normalizeDetail(bundle.business);
    const signatures = Array.isArray(bundle.signatures) ? bundle.signatures.map((detail) => normalizeDetail(detail)) : [];
    detailCache.clear();
    detailCache.set(String(business.id), business);
    for (const signature of signatures) detailCache.set(String(signature.id), signature);
    return business;
  },

  async page(query: DmsFolderAuditPageQuery): Promise<AuditOperationPage> {
    const response = await getDmsFolderAuditPage(query);
    const page = response.data;
    return {
      list: Array.isArray(page?.list) ? page.list.map((event) => normalizeOperation(event)) : [],
      pagination: page?.pagination || {
        currentPage: query.currentPage,
        pageSize: query.pageSize,
        total: 0,
      },
    };
  },

  async timeline(folderId: string): Promise<AuditOperation[]> {
    const response = await getDmsFolderAuditTimeline(folderId);
    return groupTimelineOperations(Array.isArray(response.data) ? response.data : []);
  },
};

function normalizeDetail(detail: AuditEventDetailDTO): AuditEventDetail {
  const parsedDiffs = parseAuditEventFieldDiffs(detail.fieldDiffList, detail.fieldDiffs);
  return {
    ...detail,
    fieldDiffList: parsedDiffs.diffs,
    fieldDiffParseError: parsedDiffs.parseError,
  };
}
