import { createApiClient } from './create-api-client';

const API_URL = typeof window === 'undefined' 
  ? (process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api')
  : (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api');

export const apiClient = createApiClient(API_URL);

// ── Type Definitions ─────────────────────────────────────────────────

export interface Project {
  id: string;
  title: string;
  description?: string;
  prompt: string;
  status: ProjectStatus;
  progress: number;
  language: string;
  aspectRatio: string;
  videoStyle: string;
  cinematicReference?: string;
  targetDuration: number;
  creditsUsed: number;
  thumbnailUrl?: string;
  finalVideoUrl?: string;
  errorMessage?: string;
  scriptJson?: ScriptJson;
  scriptVersion: number;
  scenes?: Scene[];
  renderJobs?: RenderJob[];
  sourceType?: 'MANUAL' | 'X_TWEET' | 'YOUTUBE';
  sourceTweetData?: Record<string, unknown>;
  // SEO Power Engine
  seoTitle?: string;
  seoDescription?: string;
  seoKeywords?: string[];
  seoTitleAlts?: string[];
  seoScore?: number;
  socialContent?: {
    youtubeTitle?: string;
    youtubeDescription?: string;
    tiktokCaption?: string;
    instagramCaption?: string;
    twitterText?: string;
  };
  createdAt: string;
  updatedAt: string;
  completedAt?: string;
}

export type ProjectStatus =
  | 'DRAFT'
  | 'GENERATING_SCRIPT'
  | 'PENDING'
  | 'GENERATING_MEDIA'
  | 'RENDERING'
  | 'COMPLETED'
  | 'FAILED';

export interface Scene {
  id: string;
  order: number;
  title?: string;
  narrationText: string;
  visualPrompt: string;
  subtitleText?: string;
  duration: number;
  transitionType: string;
  mediaAssets?: MediaAsset[];
}

export interface MediaAsset {
  id: string;
  type: string;
  url?: string;
  fileName?: string;
  mimeType?: string;
  sizeBytes?: number;
  durationMs?: number;
  aiProvider?: string;
}

export interface RenderJob {
  id: string;
  status: string;
  currentStage?: string;
  progress?: number;
  attemptNumber: number;
  processingTimeMs?: number;
  errorMessage?: string;
  finalVideoUrl?: string;
  createdAt: string;
  startedAt?: string;
  completedAt?: string;
  logs?: RenderLog[];
}

export interface RenderLog {
  id: string;
  stage: string;
  level: string;
  message: string;
  durationMs?: number;
  createdAt: string;
}

export interface ScriptJson {
  metadata: {
    title: string;
    description: string;
    totalDurationSeconds: number;
    language: string;
    hashtags: string[];
  };
  seo: {
    title: string;
    description: string;
    keywords: string[];
    hashtags: string[];
    trendingHashtags?: string[];
    estimatedSearchVolume?: string;
    schemaMarkup: Record<string, unknown>;
  };
  seoTitleAlternatives?: string[];
  seoScore?: number;
  scenes: Array<{
    order: number;
    title?: string;
    narrationText: string;
    visualPrompt: string;
    subtitleText: string;
    durationSeconds: number;
    transitionType: string;
  }>;
  musicPrompt: string;
  voiceStyle: string;
  socialContent?: {
    youtubeTitle: string;
    youtubeDescription: string;
    tiktokCaption: string;
    instagramCaption: string;
    twitterText: string;
  };
}

export interface PaginatedResponse<T> {
  data: T[];
  meta: {
    total: number;
    page: number;
    limit: number;
    totalPages: number;
  };
}

export interface CreateProjectPayload {
  title: string;
  description?: string;
  prompt: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
  seoKeywords?: string[];
  referenceUrl?: string;
}

export interface UpdateProjectPayload {
  title?: string;
  description?: string;
  prompt?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
  seoKeywords?: string[];
}

export interface CreditBalance {
  balance: number;
  remaining: number;
  total: number;
  plan: string;
  monthlyUsed: number;
  monthlyLimit: number;
}

export interface Template {
  id: string;
  title: string;
  description?: string;
  thumbnailUrl?: string;
  previewVideoUrl?: string;
  category: string;
  tags: string[];
  language: string;
  usageCount: number;
  rating: number;
  isFeatured: boolean;
}

export interface DashboardStats {
  totalProjects: number;
  completedVideos: number;
  totalCreditsUsed: number;
  creditsRemaining: number;
  activeRenderJobs: number;
  recentProjects: Project[];
}

// Tweet Types
export interface TweetAuthor {
  id: string;
  name: string;
  username: string;
  avatarUrl: string;
  followersCount: number;
  verified: boolean;
}

export interface TweetMetrics {
  replies: number;
  retweets: number;
  likes: number;
  views: number;
  engagementRate: number;
}

export interface TweetMedia {
  type: 'photo' | 'video' | 'gif';
  url: string;
  thumbnailUrl?: string;
  width: number;
  height: number;
}

export interface ParsedTweet {
  id: string;
  url: string;
  text: string;
  createdAt: string;
  author: TweetAuthor;
  metrics: TweetMetrics;
  media: TweetMedia[];
  quotedTweet?: ParsedTweet;
  isThread: boolean;
  threadTweets?: ParsedTweet[];
}

export interface TweetPreview {
  tweet: ParsedTweet;
  suggestedTitle: string;
  suggestedPrompt: string;
  viralScore: number;
  contentType: 'tweet' | 'thread' | 'quote_tweet';
  estimatedDuration: number;
}

export interface CreateFromTweetPayload {
  tweetUrl: string;
  title?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
}

export interface CreateFromYoutubePayload {
  youtubeUrl: string;
  title?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
}

export interface CreateFromDocumentPayload {
  file: File;
  title?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
}

export interface CreateFromTextPayload {
  text: string;
  title?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
}

export interface ExtractDocumentTopicsPayload {
  file: File;
}

export interface ExtractDocumentTopicsResponse {
  text: string;
  topics: string[];
  originalFilename: string;
}

export interface CreateFromExtractedTextPayload {
  text: string;
  topic: string;
  originalFilename?: string;
  language?: string;
  aspectRatio?: string;
  videoStyle?: string;
  cinematicReference?: string;
  targetDuration?: number;
}

export interface Notification {
  id: string;
  userId: string;
  type: string;
  title: string;
  message?: string | null;
  metadata?: Record<string, unknown> | null;
  isRead: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface NotificationListResponse {
  data: Notification[];
  meta: {
    total: number;
    page: number;
    limit: number;
    totalPages: number;
    unreadCount: number;
  };
}

// ── API Functions ────────────────────────────────────────────────────

export const authApi = {
  login: (data: any) =>
    apiClient.post('/auth/login', data).then((r) => r.data),
  register: (data: any) =>
    apiClient.post('/auth/register', data).then((r) => r.data),
};

export const projectsApi = {
  list: (params?: { page?: number; limit?: number; status?: string }) =>
    apiClient.get<PaginatedResponse<Project>>('/projects', { params }).then((r) => r.data),

  get: (id: string) =>
    apiClient.get<Project>(`/projects/${id}`).then((r) => r.data),

  create: (data: CreateProjectPayload) =>
    apiClient.post<Project>('/projects', data).then((r) => r.data),

  update: (id: string, data: Partial<CreateProjectPayload>) =>
    apiClient.patch<Project>(`/projects/${id}`, data).then((r) => r.data),

  delete: (id: string) =>
    apiClient.delete(`/projects/${id}`).then((r) => r.data),

  generateScript: (id: string) =>
    apiClient.post<Project>(`/projects/${id}/generate-script`).then((r) => r.data),

  approveAndQueue: (id: string, data?: { ttsProvider?: string; visualEffect?: string }) =>
    apiClient.post<{ projectId: string; renderJobId: string; bullJobId: string }>(
      `/projects/${id}/approve`,
      data || {}
    ).then((r) => r.data),

  cancelRender: (id: string) =>
    apiClient.post<{ message: string; projectId: string; renderJobId: string; status: string }>(
      `/projects/${id}/cancel-render`,
    ).then((r) => r.data),

  generateSeoTitles: (id: string) =>
    apiClient.post<{ titles: string[]; seoScore: number; currentTitle: string }>(
      `/projects/${id}/generate-seo-titles`,
    ).then((r) => r.data),

  generateSocialContent: (id: string) =>
    apiClient.post<any>(`/projects/${id}/generate-social-content`).then((r) => r.data),

  selectSeoTitle: (id: string, title: string) =>
    apiClient.patch<Project>(
      `/projects/${id}/select-title`,
      { title },
    ).then((r) => r.data),

  getRenderQueue: () =>
    apiClient.get<any>('/projects/render-queue').then((r) => r.data),

  createFromTweet: (data: CreateFromTweetPayload) =>
    apiClient.post<Project>('/projects/from-tweet', data).then((r) => r.data),

  createFromYoutube: (data: CreateFromYoutubePayload) =>
    apiClient.post<Project>('/projects/from-youtube', data).then((r) => r.data),

  createFromDocument: (data: CreateFromDocumentPayload) => {
    const formData = new FormData();
    formData.append('file', data.file);
    if (data.title) formData.append('title', data.title);
    if (data.language) formData.append('language', data.language);
    if (data.aspectRatio) formData.append('aspectRatio', data.aspectRatio);
    if (data.videoStyle) formData.append('videoStyle', data.videoStyle);
    if (data.targetDuration) formData.append('targetDuration', data.targetDuration.toString());

    return apiClient.post<Project>('/projects/from-document', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    }).then((r) => r.data);
  },

  createFromText: (data: CreateFromTextPayload) =>
    apiClient.post<Project>('/projects/from-text', data).then((r) => r.data),

  extractDocumentTopics: (data: ExtractDocumentTopicsPayload) => {
    const formData = new FormData();
    formData.append('file', data.file);
    return apiClient.post<ExtractDocumentTopicsResponse>('/projects/extract-document-topics', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    }).then((r) => r.data);
  },

  createFromExtractedText: (data: CreateFromExtractedTextPayload) =>
    apiClient.post<Project>('/projects/document-from-topic', data).then((r) => r.data),

  updateScene: (projectId: string, sceneId: string, data: Partial<Scene>) =>
    apiClient.patch<Scene>(`/projects/${projectId}/scenes/${sceneId}`, data).then((r) => r.data),

  regenerateScene: (projectId: string, sceneId: string) =>
    apiClient.post<Scene>(`/projects/${projectId}/scenes/${sceneId}/regenerate`).then((r) => r.data),

  generateSceneImage: (projectId: string, sceneId: string, customPrompt?: string) =>
    apiClient.post<Scene>(`/projects/${projectId}/scenes/${sceneId}/generate-image`, { customPrompt }).then((r) => r.data),

  upscaleSceneImage: (projectId: string, sceneId: string) =>
    apiClient.post<Scene>(`/projects/${projectId}/scenes/${sceneId}/upscale-image`).then((r) => r.data),
};

export const toolsApi = {
  analyzeYoutubeVideo: (url: string) =>
    apiClient.post<any>('/youtube-tools/analyze', { url }).then((r) => r.data),
  getYoutubeAnalysisHistory: () =>
    apiClient.get<any[]>('/youtube-tools/history').then((r) => r.data),
  getYoutubeAnalysisById: (id: string) =>
    apiClient.get<any>(`/youtube-tools/analyze/${id}`).then((r) => r.data),

  // SEO
  analyzeYoutubeSEO: (url: string) =>
    apiClient.post<any>('/youtube-tools/seo/analyze', { url }).then((r) => r.data),
  getYoutubeSeoHistory: () =>
    apiClient.get<any[]>('/youtube-tools/seo/history').then((r) => r.data),
  getYoutubeSeoAnalysisById: (id: string) =>
    apiClient.get<any>(`/youtube-tools/seo/analyze/${id}`).then((r) => r.data),
  generateYoutubeSeoImage: (prompt: string) =>
    apiClient.post<{ url: string }>('/youtube-tools/seo/generate-image', { prompt }).then((r) => r.data),
};

// Backend path: /billing/credits/balance (billing controller prefix)
export const creditsApi = {
  getBalance: () =>
    apiClient.get<CreditBalance>('/billing/credits/balance').then((r) => r.data),

  getHistory: (params?: { page?: number; limit?: number }) =>
    apiClient.get('/billing/credits/history', { params }).then((r) => r.data),
};

export const billingApi = {
  createCheckout: (planName: string, billingCycle: 'monthly' | 'yearly') =>
    apiClient.post<{ sessionId: string; url: string }>('/billing/checkout', { planName, billingCycle }).then((r) => r.data),

  getSubscription: () =>
    apiClient.get('/billing/subscription').then((r) => r.data),

  getPlans: () =>
    apiClient.get('/billing/plans').then((r) => r.data),
};

export const usersApi = {
  getMe: () =>
    apiClient.get('/users/me').then((r) => r.data),

  updateProfile: (data: { firstName?: string; lastName?: string }) =>
    apiClient.patch('/users/me', data).then((r) => r.data),

  changePassword: (data: { currentPassword: string; newPassword: string }) =>
    apiClient.patch('/users/me/password', data).then((r) => r.data),
};

export const templatesApi = {
  list: (params?: { category?: string; language?: string; page?: number; limit?: number }) =>
    apiClient.get<PaginatedResponse<Template>>('/templates', { params }).then((r) => r.data),

  get: (id: string) =>
    apiClient.get<Template>(`/templates/${id}`).then((r) => r.data),

  clone: (id: string) =>
    apiClient.post<Project>(`/templates/${id}/clone`).then((r) => r.data),
};

export const dashboardApi = {
  getStats: () =>
    apiClient.get<DashboardStats>('/dashboard/stats').then((r) => r.data),
};

export const xTwitterApi = {
  preview: (tweetUrl: string) =>
    apiClient.post<TweetPreview>('/x-twitter/preview', { tweetUrl }).then((r) => r.data),

  fetch: (tweetUrl: string) =>
    apiClient.post<ParsedTweet>('/x-twitter/fetch', { tweetUrl }).then((r) => r.data),
};

export const notificationsApi = {
  list: (params?: { page?: number; limit?: number; unreadOnly?: boolean }) =>
    apiClient.get<NotificationListResponse>('/notifications', { params }).then((r) => r.data),

  getUnreadCount: () =>
    apiClient.get<{ count: number }>('/notifications/unread-count').then((r) => r.data),

  markAsRead: (id: string) =>
    apiClient.patch<Notification>(`/notifications/${id}/read`).then((r) => r.data),

  markAllAsRead: () =>
    apiClient.patch<{ count: number }>('/notifications/read-all').then((r) => r.data),

  delete: (id: string) =>
    apiClient.delete(`/notifications/${id}`).then((r) => r.data),
};

// ── Admin API Types ────────────────────────────────────────────────────────

export interface AdminUser {
  id: string;
  email: string;
  firstName?: string;
  lastName?: string;
  isActive: boolean;
  createdAt: string;
  roles?: Array<{ role: { id: string; name: string } }>;
}

export interface AdminProject {
  id: string;
  title: string;
  status: string;
  progress: number;
  creditsUsed: number;
  language: string;
  sourceType: string;
  createdAt: string;
  user: { id: string; email: string; firstName?: string; lastName?: string };
  _count: { scenes: number; renderJobs: number };
}

export interface AdminRenderJob {
  id: string;
  status: string;
  currentStage?: string;
  attemptNumber: number;
  processingTimeMs?: number;
  errorMessage?: string;
  workerHostname?: string;
  createdAt: string;
  startedAt?: string;
  completedAt?: string;
  project: {
    id: string;
    title: string;
    user: { id: string; email: string; firstName?: string; lastName?: string };
  };
}

export interface AdminPlan {
  id: string;
  name: string;
  displayName: string;
  description?: string;
  monthlyPrice: number;
  yearlyPrice?: number;
  currency: string;
  monthlyCredits: number;
  maxDuration: number;
  maxResolution: string;
  maxProjects: number;
  isActive: boolean;
  sortOrder: number;
  features?: Record<string, unknown>;
  _count: { subscriptions: number };
}

export interface AdminStats {
  users: { total: number; active: number; inactive: number };
  projects: { total: number; byStatus: Record<string, number> };
  renderJobs: { byStatus: Record<string, number>; active: number };
  credits: { totalGranted: number; totalUsed: number };
  plans: { total: number };
  templates: { total: number };
  storage?: unknown;
  recentUsers: AdminUser[];
}

// ── Admin API Functions ─────────────────────────────────────────────────────

export const adminApi = {
  getStats: () =>
    apiClient.get<AdminStats>('/admin/stats').then((r) => r.data),

  getUsers: (params?: { page?: number; limit?: number }) =>
    apiClient.get<PaginatedResponse<AdminUser>>('/admin/users', { params }).then((r) => r.data),

  getUserDetail: (id: string) =>
    apiClient.get(`/admin/users/${id}/detail`).then((r) => r.data),

  toggleUserActive: (id: string) =>
    apiClient.put(`/admin/users/${id}/toggle-active`).then((r) => r.data),

  banUser: (id: string) =>
    apiClient.put(`/admin/users/${id}/ban`).then((r) => r.data),

  activateUser: (id: string) =>
    apiClient.put(`/admin/users/${id}/activate`).then((r) => r.data),

  grantCredits: (userId: string, data: { amount: number; description: string }) =>
    apiClient.post(`/admin/users/${userId}/credits`, data).then((r) => r.data),

  assignRole: (userId: string, roleId: string) =>
    apiClient.post(`/admin/users/${userId}/roles/${roleId}`).then((r) => r.data),

  removeRole: (userId: string, roleId: string) =>
    apiClient.delete(`/admin/users/${userId}/roles/${roleId}`).then((r) => r.data),

  getProjects: (params?: { page?: number; limit?: number; status?: string; userId?: string }) =>
    apiClient.get<PaginatedResponse<AdminProject>>('/admin/projects', { params }).then((r) => r.data),

  deleteProject: (id: string) =>
    apiClient.delete(`/admin/projects/${id}`).then((r) => r.data),

  getRenderJobs: (params?: { page?: number; limit?: number; status?: string }) =>
    apiClient.get<PaginatedResponse<AdminRenderJob>>('/admin/render-jobs', { params }).then((r) => r.data),

  getPlans: () =>
    apiClient.get<AdminPlan[]>('/admin/plans').then((r) => r.data),

  updatePlan: (id: string, data: Partial<AdminPlan>) =>
    apiClient.put(`/admin/plans/${id}`, data).then((r) => r.data),

  getRoles: () =>
    apiClient.get('/admin/roles').then((r) => r.data),

  createRole: (data: { name: string; description?: string }) =>
    apiClient.post('/admin/roles', data).then((r) => r.data),
};
