import { SYSTEM_SERVICE_PREFIX } from '@/constants/service';
import { request } from '../request';
import { type ServiceRequestResult, mapServiceResult, normalizeStringId, safeJsonRequestConfig } from './shared';
import { type FeedbackStatResponse, normalizeFeedbackStat } from './feedback-normalize';

const FEEDBACK_PREFIX = `${SYSTEM_SERVICE_PREFIX}/feedback`;

type FeedbackResponse = Omit<Api.Feedback.FeedbackItem, 'id' | 'creator' | 'attachments' | 'contentPreview'> & {
  id: string | number;
  creator: string | number;
  /** 后端原始：附件的 JSON 数组字符串（前端约定存完整附件对象，兼容历史纯 URL 数组） */
  attachmentUrls?: string | null;
};

type FeedbackPageResponse = {
  total: number;
  list: FeedbackResponse[];
};

/** 从代理 URL 末段拆出文件名（兜底历史纯 URL 附件的展示名） */
function deriveAttachmentName(url: string): string {
  try {
    const path = decodeURI(url.split('?')[0]);
    const idx = path.lastIndexOf('/');
    return idx >= 0 ? path.slice(idx + 1) : path;
  } catch {
    return url;
  }
}

/**
 * 单个附件归一化为业务层 AttachmentItem（ID 铁律：fileId/configId 一律 String）。
 * - 对象形态（新版存储）：按字段对齐；
 * - 字符串形态（历史仅存 URL）：补出 url + 派生 name，fileId 缺省空串（不可下载/清理，仅展示）。
 */
function normalizeAttachment(raw: unknown): Api.Project.AttachmentItem | null {
  if (typeof raw === 'string') {
    return { fileId: '', url: raw, name: deriveAttachmentName(raw) };
  }
  if (raw && typeof raw === 'object') {
    const item = raw as Record<string, unknown>;
    const url = typeof item.url === 'string' ? item.url : '';
    return {
      fileId: item.fileId === null || item.fileId === undefined ? '' : String(item.fileId),
      url,
      name: typeof item.name === 'string' && item.name ? item.name : deriveAttachmentName(url),
      size: typeof item.size === 'number' ? item.size : undefined,
      contentType: typeof item.contentType === 'string' ? item.contentType : undefined,
      configId: item.configId === null || item.configId === undefined ? undefined : String(item.configId),
      path: typeof item.path === 'string' ? item.path : undefined
    };
  }
  return null;
}

/** 把后端 attachmentUrls(JSON 字符串) 安全解析成附件对象数组；空 / 异常兜底为 [] */
function parseAttachments(raw?: string | null): Api.Project.AttachmentItem[] {
  if (!raw) {
    return [];
  }
  try {
    const parsed = JSON.parse(raw);
    if (!Array.isArray(parsed)) {
      return [];
    }
    return parsed.map(normalizeAttachment).filter((item): item is Api.Project.AttachmentItem => item !== null);
  } catch {
    return [];
  }
}

/** 列表「内容」列去富文本标签，取纯文本预览（content 为 HTML，预算一次免每次渲染重扫） */
function stripHtml(html: string | null | undefined): string {
  if (!html) {
    return '';
  }
  return html
    .replace(/<[^>]+>/g, '')
    .replace(/&nbsp;/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

/** 后端记录 → 业务层口径（ID 铁律 String 兜底 + 附件 parse + 内容纯文本预览预算） */
function normalizeFeedback(data: FeedbackResponse): Api.Feedback.FeedbackItem {
  const { attachmentUrls, ...rest } = data;
  return {
    ...rest,
    id: normalizeStringId(data.id),
    creator: normalizeStringId(data.creator),
    attachments: parseAttachments(attachmentUrls),
    contentPreview: stripHtml(data.content)
  };
}

/** 附件对象数组 → attachmentUrls JSON 字符串（无附件传空串） */
function serializeAttachments(attachments: Api.Project.AttachmentItem[]): string {
  return attachments.length ? JSON.stringify(attachments) : '';
}

/** 分页（支持按提交人 creator 过滤；默认 createTime 倒序由后端保证） */
export async function fetchGetFeedbackPage(params: Api.Feedback.FeedbackSearchParams) {
  const result = await request<FeedbackPageResponse>({
    ...safeJsonRequestConfig,
    url: `${FEEDBACK_PREFIX}/page`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<FeedbackPageResponse>, data => ({
    total: data.total,
    list: data.list.map(normalizeFeedback)
  }));
}

/** 统计聚合（左侧分面面板；全量口径，无业务筛选入参） */
export async function fetchGetFeedbackStat() {
  const result = await request<FeedbackStatResponse>({
    ...safeJsonRequestConfig,
    url: `${FEEDBACK_PREFIX}/stat`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<FeedbackStatResponse>, normalizeFeedbackStat);
}

/** 详情 */
export async function fetchGetFeedback(id: string) {
  const result = await request<FeedbackResponse>({
    ...safeJsonRequestConfig,
    url: `${FEEDBACK_PREFIX}/get`,
    method: 'get',
    params: { id }
  });

  return mapServiceResult(result as ServiceRequestResult<FeedbackResponse>, normalizeFeedback);
}

/** 提交反馈（attachments 对象数组在此 stringify 成 attachmentUrls；无附件传空串；返回新建 id，ID 铁律 String 化） */
export async function fetchCreateFeedback(params: Api.Feedback.FeedbackSubmitParams) {
  const { attachments, ...rest } = params;
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${FEEDBACK_PREFIX}/create`,
    method: 'post',
    data: {
      ...rest,
      attachmentUrls: serializeAttachments(attachments)
    }
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 更新反馈（编辑态；attachments 对象数组在此 stringify 成 attachmentUrls；无附件传空串） */
export function fetchUpdateFeedback(params: Api.Feedback.FeedbackUpdateParams) {
  const { attachments, ...rest } = params;
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${FEEDBACK_PREFIX}/update`,
    method: 'put',
    data: {
      ...rest,
      attachmentUrls: serializeAttachments(attachments)
    }
  });
}

/** 修改处理状态（仅超管；状态可任意改，不校验流转） */
export function fetchUpdateFeedbackStatus(id: string, status: number) {
  return request<boolean>({
    url: `${FEEDBACK_PREFIX}/${id}/status`,
    method: 'put',
    data: { status }
  });
}

/** 删除反馈（软删除；后端按归属二次校验） */
export function fetchDeleteFeedback(id: string) {
  return request<boolean>({
    url: `${FEEDBACK_PREFIX}/delete`,
    method: 'delete',
    params: { id }
  });
}
