/*
 * M17 CMS 실배선 API 계약(SCR-35·36·37). 공용 클라이언트(../../api/client)만 사용 — client/endpoints/types 무수정.
 * 정본: 백엔드 컨트롤러
 *   - GET  /api/cms/contents                          → PageResponse<CmsContent>
 *   - POST /api/cms/contents                          → CmsContent(신규 초안)
 *   - PATCH /api/cms/contents/{id}/status?value=      → CmsContent(전이·역전이 400)
 *   - GET/PUT /api/cms/contents/{id}/translations     → CmsTranslation[]
 *   - GET/PUT /api/exhibitors/{exhibitorId}/microsite → Microsite
 *   - GET  /api/public/microsites/{exhibitorId}       → Microsite(공개·무인증)
 */
import { api } from '../../api/client';
import type { PageResponse } from '../../api/types';

export type FlowStatus = 'draft' | 'review' | 'approved' | 'published';
export type TransStatus = 'none' | 'ai' | 'reviewed';
export type Lang = 'ko' | 'en' | 'zh' | 'ja';

export interface CmsContent {
  id: string;
  eventId: string | null;
  contentType: string | null;
  title: string;
  body: string | null;
  status: FlowStatus;
  lang: string | null;
  scheduledAt: string | null;
  signage: boolean;
  mailing: boolean;
  authorName: string | null;
  publishedAt: string | null;
  createdAt: string | null;
  updatedAt: string | null;
}

export interface CmsTranslation {
  contentId: string;
  lang: Lang;
  title: string | null;
  body: string | null;
  transStatus: TransStatus;
  updatedAt: string | null;
}

/**
 * AI 자동 번역(초벌) 결과 봉투. degraded=true 면 AI 일시 불가(저장 안 됨) — 프론트는 "준비 중"으로 부드럽게 처리.
 * degraded=false 면 translation 에 AI 초벌(trans_status='ai') 이 채워진다.
 */
export interface CmsAiTranslateResult {
  translation: CmsTranslation | null;
  degraded: boolean;
  provider: string;
  message: string | null;
}

export interface CmsContentVersion {
  id: string;
  contentId: string;
  versionNo: number;
  title: string | null;
  body: string | null;
  status: FlowStatus;
  authorName: string | null;
  note: string | null;
  createdAt: string | null;
}

export interface CmsMedia {
  id: string;
  eventId: string | null;
  fileName: string;
  url: string;
  contentType: string | null;
  sizeBytes: number | null;
  altText: string | null;
  uploaderName: string | null;
  createdAt: string | null;
}

export interface ContentUpdateRequest {
  title: string;
  body?: string | null;
  scheduledAt?: string | null;
  signage?: boolean | null;
  mailing?: boolean | null;
}

export interface MicrositeSection {
  id: string;
  type: string;
  visible: boolean;
  order?: number;
  payload?: Record<string, unknown>;
}

export interface Microsite {
  exhibitorId: string;
  eventId: string | null;
  slug: string | null;
  exhibitorName: string | null;
  theme: string;
  sections: MicrositeSection[];
  seoTitle: string | null;
  seoMeta: string | null;
  langs: string | null;
  status: 'draft' | 'published';
  publishedAt: string | null;
  updatedAt: string | null;
}

export interface ContentCreateRequest {
  eventId?: string | null;
  contentType?: string;
  title: string;
  body?: string;
  lang?: string;
}

export interface TranslationSaveRequest {
  lang: Lang;
  title?: string | null;
  body?: string | null;
  transStatus?: TransStatus;
}

export interface MicrositeSaveRequest {
  eventId?: string | null;
  slug?: string | null;
  exhibitorName?: string | null;
  theme?: string;
  sections?: MicrositeSection[];
  seoTitle?: string | null;
  seoMeta?: string | null;
  langs?: string | null;
  status?: 'draft' | 'published';
}

export const cmsApi = {
  listContents: (p: { status?: string; type?: string; keyword?: string; page?: number; size?: number } = {}) => {
    const qs = new URLSearchParams();
    if (p.status) qs.set('status', p.status);
    if (p.type) qs.set('type', p.type);
    if (p.keyword) qs.set('keyword', p.keyword);
    qs.set('page', String(p.page ?? 0));
    qs.set('size', String(p.size ?? 50));
    return api.get<PageResponse<CmsContent>>(`/api/cms/contents?${qs.toString()}`);
  },
  createContent: (body: ContentCreateRequest) => api.post<CmsContent>('/api/cms/contents', body),
  getContent: (id: string) => api.get<CmsContent>(`/api/cms/contents/${encodeURIComponent(id)}`),
  updateContent: (id: string, body: ContentUpdateRequest) =>
    api.put<CmsContent>(`/api/cms/contents/${encodeURIComponent(id)}`, body),
  transition: (id: string, value: FlowStatus) =>
    api.patch<CmsContent>(`/api/cms/contents/${encodeURIComponent(id)}/status?value=${value}`),
  getVersions: (id: string) =>
    api.get<CmsContentVersion[]>(`/api/cms/contents/${encodeURIComponent(id)}/versions`),
  rollback: (id: string, versionNo: number) =>
    api.post<CmsContent>(`/api/cms/contents/${encodeURIComponent(id)}/rollback?versionNo=${versionNo}`),
  getTranslations: (id: string) =>
    api.get<CmsTranslation[]>(`/api/cms/contents/${encodeURIComponent(id)}/translations`),
  saveTranslation: (id: string, body: TranslationSaveRequest) =>
    api.put<CmsTranslation[]>(`/api/cms/contents/${encodeURIComponent(id)}/translations`, body),
  /**
   * AI 자동 번역(초벌) — AiTextRouter(Claude 기본·Ollama 폴백) 실배선.
   * 성공 시 result.translation 채움(trans_status='ai'). AI 미가용 시 result.degraded=true(HTTP 200, 저장 안 됨).
   */
  aiTranslate: (id: string, lang: Lang) =>
    api.post<CmsAiTranslateResult>(
      `/api/cms/contents/${encodeURIComponent(id)}/translations/ai?lang=${lang}`,
    ),
  // ── 미디어 라이브러리 ──
  listMedia: (limit = 60) => api.get<CmsMedia[]>(`/api/cms/media?limit=${limit}`),
  uploadMedia: (file: File, altText?: string) => {
    const form = new FormData();
    form.append('file', file);
    if (altText) form.append('altText', altText);
    return api.postForm<CmsMedia>('/api/cms/media', form);
  },
  // ── 공개 조회(무인증·게시 상태만) ──
  publicByType: (type: string, limit = 50) =>
    api.get<CmsContent[]>(`/api/public/cms/${encodeURIComponent(type)}?limit=${limit}`, {
      anonymous: true,
    }),
  getMicrosite: (exhibitorId: string) =>
    api.get<Microsite>(`/api/exhibitors/${encodeURIComponent(exhibitorId)}/microsite`),
  saveMicrosite: (exhibitorId: string, body: MicrositeSaveRequest) =>
    api.put<Microsite>(`/api/exhibitors/${encodeURIComponent(exhibitorId)}/microsite`, body),
  getPublicMicrosite: (exhibitorId: string) =>
    api.get<Microsite>(`/api/public/microsites/${encodeURIComponent(exhibitorId)}`, { anonymous: true }),
};
