import api, { API_URL } from './api';
import { getToken } from '../utils/auth';

const normalizeArticle = (raw: any): Article => {
  if (!raw) return raw;
  const id = raw.id ?? raw.ID ?? raw.article_id ?? raw.articleId;
  const category = raw.category ?? raw.Category;
  const author = raw.author ?? raw.Author;
  return {
    ...(raw as Article),
    id,
    category,
    author,
  } as Article;
};

export interface Article {
  id: number;
  title: string;
  content: string;
  image_url?: string;
  author?: { id: number; first_name?: string; last_name?: string; email: string };
  category_id?: number;
  category?: { id: number; name: string; description?: string; slug?: string; created_at?: string; updated_at?: string };
  category_name?: string;
  published?: boolean;
  featured?: boolean;
  created_at?: string;
  slug?: string;
  seo_title?: string;
  seo_description?: string;
  og_image_url?: string;
  published_at?: string;
  updated_at?: string;
  estimated_read_minutes?: number;
  read_count?: number;
  view_count?: number;
  read_time?: number;
  gallery_album_id?: string;
  gallery_album_url?: string;
  gallery_photo_ids?: string[];
  youtube_video_id?: string;
  youtube_video_title?: string;
  youtube_video_url?: string;
  youtube_video_thumbnail?: string;
  attachments?: Array<{ name: string; url: string; mime_type?: string; size?: number }>;
}

// --- Article ⇄ Match link ---
export interface ArticleMatchLink {
  article_id: number;
  external_match_id?: string;
  title?: string;
}

export async function getArticleMatchLink(articleId: number | string): Promise<ArticleMatchLink> {
  const res = await api.get<ArticleMatchLink>(`/articles/${articleId}/match-link`);
  return res.data;
}

export async function putArticleMatchLink(articleId: number | string, payload: { external_match_id: string; title?: string }): Promise<ArticleMatchLink> {
  const res = await api.post<ArticleMatchLink>(`/articles/${articleId}/match-link`, payload);
  return res.data;
}

export async function deleteArticleMatchLink(articleId: number | string): Promise<{ ok: boolean }> {
  const res = await api.delete<{ ok: boolean }>(`/articles/${articleId}/match-link`);
  return res.data;
}

export async function getFeaturedArticles(params: {
  page?: number;
  page_size?: number;
} = {}) {
  const res = await api.get<any>('/articles/featured', { params });
  const d = res.data || {};
  const itemsRaw: any[] = Array.isArray(d.items)
    ? d.items
    : Array.isArray(d.data)
    ? d.data
    : [];
  const items: Article[] = itemsRaw.map((item) => normalizeArticle(item));
  const total = typeof d.total === 'number' ? d.total : items.length;
  const page = typeof d.page === 'number' ? d.page : (params as any).page || 1;
  const page_size = typeof d.page_size === 'number' ? d.page_size : (params as any).page_size || items.length;
  return { data: items, total, page, page_size } as Paginated<Article>;
}

export interface Paginated<T> {
  data: T[];
  page: number;
  page_size: number;
  total: number;
}

export async function getArticles(params: { 
  page?: number; 
  page_size?: number; 
  category_id?: number; 
  published?: boolean;
  featured?: boolean;
  q?: string;
  slug?: string;
} = {}) {
  // Backend returns shape: { items, total, page, page_size }
  // Normalize to { data, total, page, page_size } expected by the frontend.
  const res = await api.get<any>('/articles', { params });
  const d = res.data || {};
  const itemsRaw: any[] = Array.isArray(d.items)
    ? d.items
    : Array.isArray(d.data)
    ? d.data
    : [];
  const items: Article[] = itemsRaw.map((item) => normalizeArticle(item));
  const total = typeof d.total === 'number' ? d.total : (typeof d.count === 'number' ? d.count : items.length);
  const page = typeof d.page === 'number' ? d.page : (params as any).page || 1;
  const page_size = typeof d.page_size === 'number' ? d.page_size : (params as any).page_size || items.length;
  return { data: items, total, page, page_size } as Paginated<Article>;
}

export async function getArticle(id: number | string) {
  const res = await api.get<Article>(`/articles/${id}`);
  return normalizeArticle(res.data);
}

export interface CreateArticlePayload {
  title: string;
  content: string;
  category_id?: number;
  category_name?: string; // optional: backend will resolve/create category by name
  published?: boolean;
  image_url?: string;
  slug?: string;
  seo_title?: string;
  seo_description?: string;
  og_image_url?: string;
  featured?: boolean;
  gallery_album_id?: string;
  gallery_album_url?: string;
  gallery_photo_ids?: string[];
  youtube_video_id?: string;
  youtube_video_title?: string;
  youtube_video_url?: string;
  youtube_video_thumbnail?: string;
  attachments?: Array<{ name: string; url: string; mime_type?: string; size?: number }>;
}

export async function createArticle(payload: CreateArticlePayload) {
  const res = await api.post<Article>('/articles', payload);
  return normalizeArticle(res.data);
}

export type UpdateArticlePayload = Partial<CreateArticlePayload>;

export async function updateArticle(id: number | string, payload: UpdateArticlePayload) {
  const res = await api.put<Article>(`/articles/${id}`, payload);
  return normalizeArticle(res.data);
}

export async function deleteArticle(id: number | string) {
  const res = await api.delete<{ success: boolean }>(`/articles/${id}`);
  return res.data;
}

// Fetch by slug if the backend exposes /articles/slug/:slug.
// Falls back to querying the list endpoint with ?slug= if needed.
export async function getArticleBySlug(slug: string) {
  try {
    const res = await api.get<Article>(`/articles/slug/${encodeURIComponent(slug)}`);
    return res.data;
  } catch (e) {
    // Fallback: attempt list query through normalized helper and return first match
    const list = await getArticles({ slug });
    return list.data?.[0];
  }
}

export async function uploadFile(file: File) {
  const form = new FormData();
  form.append('file', file);
  // Important: Do NOT set Content-Type manually so Axios can attach the proper multipart boundary.
  // The api instance will automatically add Authorization via the interceptor when a token exists.
  const res = await api.post<{ url: string; name: string; type: string; size: number }>(
    '/upload',
    form
  );
  const data = res.data;
  let url = data.url || '';
  try {
    // Normalize URLs returned by backend: if the returned URL points to the frontend origin (dev server)
    // or to the API origin, convert it to a backend-relative path like '/uploads/2025/...'
    const parsed = new URL(url, window.location.origin);
    const appOrigin = window.location.origin;
    const apiOrigin = new URL(API_URL).origin;
    if (parsed.origin === appOrigin) {
      // Rewrite frontend-origin URLs to API origin, then strip origin to keep a relative path
      url = parsed.pathname + parsed.search + parsed.hash;
    } else if (parsed.origin === apiOrigin) {
      // Keep only the path so stored values are consistent (backend relative path)
      url = parsed.pathname + parsed.search + parsed.hash;
    }
  } catch (e) {
    // ignore parsing errors, keep original
  }
  return { ...data, url };
}

export async function trackArticleView(id: number | string) {
  try {
    await api.post(`/articles/${id}/track-view`);
  } catch (e) {
    console.debug('Failed to track article view:', e);
  }
}

