import axios, { AxiosInstance, InternalAxiosRequestConfig } from "axios";

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3010/api/v1";

// Token storage keys
const ACCESS_TOKEN_KEY = "chatapp_access_token";
const REFRESH_TOKEN_KEY = "chatapp_refresh_token";
const WORKSPACE_ID_KEY = "chatapp_workspace_id";

export function getAccessToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(ACCESS_TOKEN_KEY);
}

export function getRefreshToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(REFRESH_TOKEN_KEY);
}

export function setTokens(access: string, refresh?: string) {
  localStorage.setItem(ACCESS_TOKEN_KEY, access);
  if (refresh) localStorage.setItem(REFRESH_TOKEN_KEY, refresh);
}

export function getWorkspaceId(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(WORKSPACE_ID_KEY);
}

export function setWorkspaceId(id: string) {
  localStorage.setItem(WORKSPACE_ID_KEY, id);
}

export function clearTokens() {
  localStorage.removeItem(ACCESS_TOKEN_KEY);
  localStorage.removeItem(REFRESH_TOKEN_KEY);
  localStorage.removeItem(WORKSPACE_ID_KEY);
}

// Axios instance
const api: AxiosInstance = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    "Content-Type": "application/json",
  },
});

// Request interceptor: add Authorization + X-Workspace-Id
api.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const token = getAccessToken();
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    const wsId = getWorkspaceId();
    if (wsId && config.headers) {
      config.headers["X-Workspace-Id"] = wsId;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// Response interceptor: handle 401 -> attempt refresh (with dedup to prevent race conditions)
let isRefreshing = false;
let refreshSubscribers: Array<(token: string | null) => void> = [];

function subscribeTokenRefresh(cb: (token: string | null) => void) {
  refreshSubscribers.push(cb);
}

function onTokenRefreshed(token: string | null) {
  refreshSubscribers.forEach((cb) => cb(token));
  refreshSubscribers = [];
}

api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    // Prevent infinite loop: only retry once
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;

      if (isRefreshing) {
        // Wait for the ongoing refresh to complete
        return new Promise((resolve, reject) => {
          subscribeTokenRefresh((token: string | null) => {
            if (token) {
              originalRequest.headers.Authorization = `Bearer ${token}`;
              resolve(api(originalRequest));
            } else {
              reject(error);
            }
          });
        });
      }

      isRefreshing = true;
      const refresh = getRefreshToken();
      if (refresh) {
        try {
          const res = await axios.post(`${API_BASE_URL}/auth/refresh`, {
            refresh_token: refresh,
          });
          const newAccess = res.data.access_token;
          const newRefresh = res.data.refresh_token;
          setTokens(newAccess, newRefresh);
          isRefreshing = false;
          onTokenRefreshed(newAccess);
          originalRequest.headers.Authorization = `Bearer ${newAccess}`;
          return api(originalRequest);
        } catch {
          isRefreshing = false;
          onTokenRefreshed(null);
          clearTokens();
          if (typeof window !== "undefined") {
            window.location.href = "/login";
          }
        }
      } else {
        isRefreshing = false;
        clearTokens();
        if (typeof window !== "undefined") {
          window.location.href = "/login";
        }
      }
    }
    return Promise.reject(error);
  }
);

// --- Types ---

export interface User {
  id: string;
  email: string;
  name?: string;
  display_name?: string;
  displayName?: string;
}

export interface Workspace {
  id: string;
  name: string;
}

export interface Channel {
  id: string;
  name: string;
  description?: string;
  is_private?: boolean;
  isPrivate?: boolean;
  type?: string;
  members_count?: number;
  memberCount?: number;
}

export interface Message {
  id: string;
  text: string;
  content?: string;
  userId?: string;
  user_id?: string;
  channelId?: string;
  channel_id?: string;
  user?: { id: string; name?: string; display_name?: string; displayName?: string; email?: string };
  createdAt?: string;
  created_at?: string;
  ts?: string;
  updatedAt?: string;
}

// --- API methods ---

export async function login(email: string, password: string) {
  const res = await axios.post(`${API_BASE_URL}/auth/login`, { email, password });
  const { access_token, refresh_token, user, workspaces } = res.data;
  setTokens(access_token, refresh_token);
  if (workspaces && workspaces.length > 0) {
    setWorkspaceId(workspaces[0].id);
  }
  return { user, workspaces };
}

export async function register(
  email: string,
  password: string,
  display_name?: string,
  workspace_name?: string
) {
  const res = await axios.post(`${API_BASE_URL}/auth/register`, {
    email,
    password,
    display_name: display_name || email.split('@')[0],
    workspace_name,
  });
  const { access_token, refresh_token, user, workspace } = res.data;
  setTokens(access_token, refresh_token);
  if (workspace) {
    setWorkspaceId(workspace.id);
  }
  return { user, workspace };
}

export async function getCurrentUser(): Promise<User> {
  const res = await api.get("/users/me");
  return res.data;
}

export async function getWorkspaces(): Promise<Workspace[]> {
  const res = await api.get("/workspaces");
  return res.data;
}

export async function getWorkspace(id: string): Promise<Workspace> {
  const res = await api.get(`/workspaces/${id}`);
  return res.data;
}

export async function getChannels(): Promise<Channel[]> {
  const res = await api.get("/channels");
  if (Array.isArray(res.data)) return res.data;
  if (res.data?.channels) return res.data.channels;
  return [];
}

export async function getChannelMessages(
  channelId: string,
  cursor?: string
): Promise<{ messages: Message[]; has_more: boolean; next_cursor?: string }> {
  const url = `/channels/${channelId}/messages`;
  const params = cursor ? { cursor, limit: 50 } : { limit: 50 };
  const res = await api.get(url, { params });
  if (Array.isArray(res.data)) {
    return { messages: res.data, has_more: false, next_cursor: undefined };
  }
  return {
    messages: res.data.messages || [],
    has_more: res.data.has_more || false,
    next_cursor: res.data.next_cursor,
  };
}

export async function sendMessage(channelId: string, text: string): Promise<Message> {
  const res = await api.post(`/messages/${channelId}`, { text });
  return res.data;
}

export async function createChannel(name: string, description?: string, is_private?: boolean): Promise<Channel> {
  const res = await api.post("/channels", { name, description, is_private });
  return res.data;
}

export async function search(query: string) {
  const res = await api.get("/search", { params: { q: query } });
  return res.data;
}

export async function uploadFile(file: File) {
  const formData = new FormData();
  formData.append("file", file);
  const res = await api.post("/files/upload", formData, {
    headers: { "Content-Type": "multipart/form-data" },
  });
  return res.data;
}

// --- Reactions ---

export interface Reaction {
  emoji: string;
  count: number;
  userIds?: string[];
}

export async function addReaction(messageId: string, emoji: string) {
  const res = await api.post(`/messages/${messageId}/reactions`, { emoji });
  return res.data;
}

export async function removeReaction(messageId: string, emoji: string) {
  const res = await api.delete(`/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`);
  return res.data;
}

// --- Threads ---

export async function getThread(rootId: string): Promise<Message[]> {
  const res = await api.get(`/messages/${rootId}/thread`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.messages || [];
}

export async function sendThreadReply(channelId: string, text: string, threadRootId: string): Promise<Message> {
  const res = await api.post(`/messages/${channelId}`, { text, thread_root_id: threadRootId });
  return res.data;
}

// --- Lists (Kanban board) ---

export interface ListItem {
  id: string;
  name: string;
  description?: string;
  status?: string;
  assigned_to?: string;
  assigned_user?: { id: string; name?: string; display_name?: string; email?: string };
  comments?: ListComment[];
  position?: number;
  created_at?: string;
  updated_at?: string;
}

export interface ListComment {
  id: string;
  text: string;
  user?: { id: string; name?: string; display_name?: string; email?: string };
  user_id?: string;
  created_at?: string;
}

export interface ListEntity {
  id: string;
  name: string;
  position?: number;
  items?: ListItem[];
  channel_id?: string;
  created_at?: string;
}

export async function getChannelLists(channelId: string): Promise<ListEntity[]> {
  const res = await api.get(`/channels/${channelId}/lists`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.lists || [];
}

export async function createList(channelId: string, name: string): Promise<ListEntity> {
  const res = await api.post(`/channels/${channelId}/lists`, { name });
  return res.data;
}

export async function getList(listId: string): Promise<ListEntity> {
  const res = await api.get(`/lists/${listId}`);
  return res.data;
}

export async function createListItem(
  listId: string,
  data: { name: string; description?: string; status?: string; assigned_to?: string }
): Promise<ListItem> {
  const res = await api.post(`/lists/${listId}/items`, data);
  return res.data;
}

export async function updateListItem(
  listId: string,
  itemId: string,
  data: Partial<{ name: string; description: string; status: string; assigned_to: string; position: number }>
): Promise<ListItem> {
  const res = await api.patch(`/lists/${listId}/items/${itemId}`, data);
  return res.data;
}

export async function deleteListItem(listId: string, itemId: string): Promise<void> {
  await api.delete(`/lists/${listId}/items/${itemId}`);
}

export async function addListComment(
  listId: string,
  itemId: string,
  text: string
): Promise<ListComment> {
  const res = await api.post(`/lists/${listId}/items/${itemId}/comments`, { text });
  return res.data;
}

// --- Canvas (Collaborative documents) ---

export interface Canvas {
  id: string;
  title: string;
  content?: string;
  channel_id?: string;
  created_by?: string;
  created_at?: string;
  updated_at?: string;
  collaborators?: CanvasCollaborator[];
}

export interface CanvasCollaborator {
  user_id: string;
  user?: { id: string; name?: string; display_name?: string; email?: string };
  role?: string;
}

export async function getChannelCanvases(channelId: string): Promise<Canvas[]> {
  const res = await api.get(`/channels/${channelId}/canvas`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.canvases || [];
}

export async function createCanvas(
  channelId: string,
  data: { title: string; content?: string }
): Promise<Canvas> {
  const res = await api.post(`/channels/${channelId}/canvas`, data);
  return res.data;
}

export async function getCanvas(canvasId: string): Promise<Canvas> {
  const res = await api.get(`/canvas/${canvasId}`);
  return res.data;
}

export async function updateCanvas(
  canvasId: string,
  data: Partial<{ title: string; content: string }>
): Promise<Canvas> {
  const res = await api.patch(`/canvas/${canvasId}`, data);
  return res.data;
}

export async function addCanvasCollaborator(
  canvasId: string,
  data: { user_id: string; role?: string }
): Promise<CanvasCollaborator> {
  const res = await api.post(`/canvas/${canvasId}/collaborators`, data);
  return res.data;
}

// --- Huddles (Audio/Video calls) ---

export interface Huddle {
  id: string;
  channel_id: string;
  status: string;
  started_by?: string;
  started_at?: string;
  ended_at?: string;
  participants?: HuddleParticipant[];
  notes?: string;
}

export interface HuddleParticipant {
  user_id: string;
  user?: { id: string; name?: string; display_name?: string; email?: string };
  muted?: boolean;
  video_on?: boolean;
  joined_at?: string;
}

export async function startHuddle(channelId: string): Promise<Huddle> {
  const res = await api.post(`/channels/${channelId}/huddles`, {});
  return res.data;
}

export async function joinHuddle(huddleId: string): Promise<Huddle> {
  const res = await api.post(`/huddles/${huddleId}/join`, {});
  return res.data;
}

export async function leaveHuddle(huddleId: string): Promise<void> {
  await api.post(`/huddles/${huddleId}/leave`, {});
}

export async function endHuddle(huddleId: string): Promise<void> {
  await api.post(`/huddles/${huddleId}/end`, {});
}

export async function getHuddle(huddleId: string): Promise<Huddle> {
  const res = await api.get(`/huddles/${huddleId}`);
  return res.data;
}

export async function updateHuddleNotes(huddleId: string, notes: string): Promise<Huddle> {
  const res = await api.post(`/huddles/${huddleId}/notes`, { notes });
  return res.data;
}

// --- Admin: Analytics ---

export interface AnalyticsData {
  total_messages: number;
  active_channels: number;
  total_members: number;
  storage_used_mb: number;
  messages_last_7_days: number[];
  messages_by_channel?: { channel: string; count: number }[];
}

export async function getAnalytics(): Promise<AnalyticsData> {
  const res = await api.get("/admin/analytics");
  return res.data;
}

// --- Admin: Audit Logs ---

export interface AuditLog {
  id: string;
  action: string;
  actor: { id: string; name?: string; email?: string };
  target?: string;
  details?: string;
  created_at: string;
}

export async function getAuditLogs(params?: {
  from?: string;
  to?: string;
  action?: string;
}): Promise<AuditLog[]> {
  const res = await api.get("/admin/audit-logs", { params });
  if (Array.isArray(res.data)) return res.data;
  return res.data.logs || [];
}

// --- Admin: Members ---

export interface Member {
  id: string;
  name?: string;
  email: string;
  display_name?: string;
  displayName?: string;
  role: string;
  status: string;
  last_active?: string;
  avatar_url?: string;
}

export async function getMembers(): Promise<Member[]> {
  const res = await api.get("/admin/members");
  if (Array.isArray(res.data)) return res.data;
  return res.data.members || [];
}

export async function updateMemberRole(memberId: string, role: string): Promise<void> {
  await api.patch(`/admin/members/${memberId}`, { role });
}

export async function suspendMember(memberId: string, suspend: boolean): Promise<void> {
  await api.patch(`/admin/members/${memberId}`, { status: suspend ? "suspended" : "active" });
}

// --- Admin: Emojis ---

export interface CustomEmoji {
  id: string;
  name: string;
  url: string;
  created_by?: string;
  created_at?: string;
}

export async function getCustomEmojis(): Promise<CustomEmoji[]> {
  const res = await api.get("/admin/emojis");
  if (Array.isArray(res.data)) return res.data;
  return res.data.emojis || [];
}

export async function uploadCustomEmoji(name: string, file: File): Promise<CustomEmoji> {
  const formData = new FormData();
  formData.append("name", name);
  formData.append("file", file);
  const res = await api.post("/admin/emojis", formData, {
    headers: { "Content-Type": "multipart/form-data" },
  });
  return res.data;
}

// --- User Profile ---

export async function updateProfile(data: {
  name?: string;
  display_name?: string;
  bio?: string;
  avatar_url?: string;
}): Promise<User> {
  const res = await api.patch("/users/me", data);
  return res.data;
}

export async function changePassword(currentPassword: string, newPassword: string): Promise<void> {
  await api.post("/users/me/password", {
    current_password: currentPassword,
    new_password: newPassword,
  });
}

export async function getActiveSessions(): Promise<Session[]> {
  const res = await api.get("/users/me/sessions");
  if (Array.isArray(res.data)) return res.data;
  return res.data.sessions || [];
}

export interface Session {
  id: string;
  device: string;
  ip: string;
  last_active: string;
  current?: boolean;
}

// --- Notification Preferences ---

export interface NotificationPreferences {
  dm_notifications: boolean;
  mention_notifications: boolean;
  keyword_notifications: boolean;
  keywords: string[];
  dnd_enabled: boolean;
  dnd_start: string;
  dnd_end: string;
}

export async function getNotificationPreferences(): Promise<NotificationPreferences> {
  const res = await api.get("/notifications/preferences");
  return res.data;
}

export async function updateNotificationPreferences(
  data: Partial<NotificationPreferences>
): Promise<NotificationPreferences> {
  const res = await api.patch("/notifications/preferences", data);
  return res.data;
}

// --- Saved Messages ---

export async function getSavedMessages(): Promise<Message[]> {
  const res = await api.get("/messages/saved");
  if (Array.isArray(res.data)) return res.data;
  return res.data.messages || [];
}

export async function saveMessage(messageId: string): Promise<void> {
  await api.post(`/messages/${messageId}/save`);
}

export async function unsaveMessage(messageId: string): Promise<void> {
  await api.delete(`/messages/${messageId}/save`);
}

// --- Pinned Messages ---

export async function getPinnedMessages(channelId: string): Promise<Message[]> {
  const res = await api.get(`/channels/${channelId}/pins`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.messages || res.data.pins || [];
}

export async function pinMessage(messageId: string): Promise<void> {
  await api.post(`/messages/${messageId}/pin`);
}

export async function unpinMessage(messageId: string): Promise<void> {
  await api.delete(`/messages/${messageId}/pin`);
}

// --- Scheduled Messages ---

export interface ScheduledMessage {
  id: string;
  text: string;
  channel_id: string;
  channel_name?: string;
  scheduled_at: string;
  status?: string;
}

export async function getScheduledMessages(): Promise<ScheduledMessage[]> {
  const res = await api.get("/messages/scheduled");
  if (Array.isArray(res.data)) return res.data;
  return res.data.messages || [];
}

export async function scheduleMessage(
  channelId: string,
  text: string,
  scheduledAt: string
): Promise<ScheduledMessage> {
  const res = await api.post("/messages/scheduled", {
    channel_id: channelId,
    text,
    scheduled_at: scheduledAt,
  });
  return res.data;
}

export async function deleteScheduledMessage(id: string): Promise<void> {
  await api.delete(`/messages/scheduled/${id}`);
}

// --- Custom Status ---

export async function setCustomStatus(
  emoji: string,
  text: string,
  expiresAt?: string
): Promise<void> {
  await api.post("/users/me/status", { emoji, text, expires_at: expiresAt });
}

// --- Channel Members ---

export interface ChannelMember {
  id: string;
  name?: string;
  email: string;
  display_name?: string;
  displayName?: string;
  role?: string;
  avatar_url?: string;
  status?: string;
}

export async function getChannelMembers(channelId: string): Promise<ChannelMember[]> {
  const res = await api.get(`/channels/${channelId}/members`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.members || [];
}

// --- DMs (Direct Messages) ---

export interface DMConversation {
  id: string;
  name?: string;
  is_group?: boolean;
  members?: { id: string; name?: string; display_name?: string; email?: string; avatar_url?: string }[];
  last_message?: {
    text: string;
    user?: string;
    created_at?: string;
  };
  unread_count?: number;
  created_at?: string;
  updated_at?: string;
}

export async function getDMs(): Promise<DMConversation[]> {
  const res = await api.get("/dms");
  if (Array.isArray(res.data)) return res.data;
  return res.data.dms || res.data.conversations || [];
}

export async function getDMMessages(
  dmId: string,
  cursor?: string
): Promise<{ messages: Message[]; has_more: boolean; next_cursor?: string }> {
  const url = `/dms/${dmId}/messages`;
  const params = cursor ? { cursor, limit: 50 } : { limit: 50 };
  const res = await api.get(url, { params });
  if (Array.isArray(res.data)) {
    return { messages: res.data, has_more: false, next_cursor: undefined };
  }
  return {
    messages: res.data.messages || [],
    has_more: res.data.has_more || false,
    next_cursor: res.data.next_cursor,
  };
}

export async function sendDMMessage(dmId: string, text: string): Promise<Message> {
  const res = await api.post(`/dms/${dmId}/messages`, { text });
  return res.data;
}

export async function createDM(userIds: string[]): Promise<DMConversation> {
  const res = await api.post("/dms", { user_ids: userIds });
  return res.data;
}

// --- Workflows ---

export interface Workflow {
  id: string;
  name: string;
  description?: string;
  enabled: boolean;
  trigger?: WorkflowTrigger;
  steps?: WorkflowStepConfig[];
  created_at?: string;
  updated_at?: string;
}

export interface WorkflowTrigger {
  type: string;
  channel_id?: string;
  keyword?: string;
}

export interface WorkflowStepConfig {
  id: string;
  type: string;
  config: Record<string, unknown>;
}

export async function getWorkflows(): Promise<Workflow[]> {
  const res = await api.get("/workflows");
  if (Array.isArray(res.data)) return res.data;
  return res.data.workflows || [];
}

export async function createWorkflow(data: {
  name: string;
  description?: string;
  trigger?: WorkflowTrigger;
  steps?: WorkflowStepConfig[];
}): Promise<Workflow> {
  const res = await api.post("/workflows", data);
  return res.data;
}

export async function updateWorkflow(
  workflowId: string,
  data: Partial<{ name: string; description: string; trigger: WorkflowTrigger; steps: WorkflowStepConfig[] }>
): Promise<Workflow> {
  const res = await api.patch(`/workflows/${workflowId}`, data);
  return res.data;
}

export async function deleteWorkflow(workflowId: string): Promise<void> {
  await api.delete(`/workflows/${workflowId}`);
}

export async function toggleWorkflow(workflowId: string, enabled: boolean): Promise<Workflow> {
  const res = await api.patch(`/workflows/${workflowId}`, { enabled });
  return res.data;
}

// --- Integrations ---

export interface Integration {
  id: string;
  app_id: string;
  name: string;
  description?: string;
  icon_url?: string;
  enabled: boolean;
  scopes?: string[];
  configured?: boolean;
  installed_at?: string;
}

export interface AvailableApp {
  id: string;
  name: string;
  description?: string;
  icon_url?: string;
  category?: string;
  developer?: string;
  install_count?: number;
  rating?: number;
}

export async function getIntegrations(): Promise<Integration[]> {
  const res = await api.get("/integrations");
  if (Array.isArray(res.data)) return res.data;
  return res.data.integrations || [];
}

export async function installIntegration(appId: string, scopes?: string[]): Promise<Integration> {
  const res = await api.post("/integrations", { app_id: appId, scopes });
  return res.data;
}

export async function uninstallIntegration(integrationId: string): Promise<void> {
  await api.delete(`/integrations/${integrationId}`);
}

export async function getAvailableApps(): Promise<AvailableApp[]> {
  const res = await api.get("/integrations/directory");
  if (Array.isArray(res.data)) return res.data;
  return res.data.apps || [];
}

// --- AI / Slackbot ---

export interface ChannelSummary {
  channel_id: string;
  summary: string;
  key_points: string[];
  action_items: string[];
  participants: string[];
  generated_at: string;
}

export interface DailyRecap {
  date: string;
  summary: string;
  channels: { channel_id: string; channel_name: string; message_count: number; highlights: string[] }[];
  mentions: number;
  threads: number;
}

export interface SlackbotResponse {
  answer: string;
  sources?: { type: string; id: string; text?: string }[];
}

export async function getChannelSummary(channelId: string): Promise<ChannelSummary> {
  const res = await api.get(`/ai/channel-summary/${channelId}`);
  return res.data;
}

export async function getDailyRecap(): Promise<DailyRecap> {
  const res = await api.get("/ai/daily-recap");
  return res.data;
}

export async function askSlackbot(question: string): Promise<SlackbotResponse> {
  const res = await api.post("/ai/slackbot", { question });
  return res.data;
}

export async function getAIThreadSummary(threadId: string): Promise<{ summary: string; key_points: string[] }> {
  const res = await api.get(`/ai/thread-summary/${threadId}`);
  return res.data;
}

// --- Bookmarks ---

export interface BookmarkItem {
  id: string;
  title: string;
  url?: string;
  emoji?: string;
  channel_id?: string;
  created_by?: string;
  created_at?: string;
}

export async function getBookmarks(channelId: string): Promise<BookmarkItem[]> {
  const res = await api.get(`/channels/${channelId}/bookmarks`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.bookmarks || [];
}

export async function addBookmark(
  channelId: string,
  data: { title: string; url?: string; emoji?: string }
): Promise<BookmarkItem> {
  const res = await api.post(`/channels/${channelId}/bookmarks`, data);
  return res.data;
}

export async function deleteBookmark(channelId: string, bookmarkId: string): Promise<void> {
  await api.delete(`/channels/${channelId}/bookmarks/${bookmarkId}`);
}

// --- Reminders ---

export interface Reminder {
  id: string;
  text: string;
  remind_at: string;
  channel_id?: string;
  completed: boolean;
  created_at?: string;
}

export async function getReminders(): Promise<Reminder[]> {
  const res = await api.get("/reminders");
  if (Array.isArray(res.data)) return res.data;
  return res.data.reminders || [];
}

export async function createReminder(data: {
  text: string;
  remind_at: string;
  channel_id?: string;
}): Promise<Reminder> {
  const res = await api.post("/reminders", data);
  return res.data;
}

export async function deleteReminder(id: string): Promise<void> {
  await api.delete(`/reminders/${id}`);
}

export async function completeReminder(id: string): Promise<void> {
  await api.post(`/reminders/${id}/complete`, {});
}

// --- Files ---

export interface FileItem {
  id: string;
  name: string;
  url?: string;
  type: string;
  size?: number;
  channel_id?: string;
  uploaded_by?: string;
  uploaded_by_user?: { id: string; name?: string; email?: string };
  created_at?: string;
}

export async function getFiles(channelId: string): Promise<FileItem[]> {
  const res = await api.get(`/channels/${channelId}/files`);
  if (Array.isArray(res.data)) return res.data;
  return res.data.files || [];
}

export async function deleteFile(fileId: string): Promise<void> {
  await api.delete(`/files/${fileId}`);
}

export async function getFileUrl(fileId: string): Promise<{ url: string }> {
  const res = await api.get(`/files/${fileId}/url`);
  return res.data;
}

// --- User Groups ---

export interface UserGroup {
  id: string;
  name: string;
  description?: string;
  handle?: string;
  members?: { id: string; name?: string; email?: string }[];
  member_count?: number;
  created_at?: string;
}

export async function getUserGroups(): Promise<UserGroup[]> {
  const res = await api.get("/user-groups");
  if (Array.isArray(res.data)) return res.data;
  return res.data.groups || [];
}

export async function createUserGroup(data: {
  name: string;
  description?: string;
  handle?: string;
  memberIds?: string[];
}): Promise<UserGroup> {
  const res = await api.post("/user-groups", data);
  return res.data;
}

export async function updateUserGroup(
  groupId: string,
  data: Partial<{ name: string; description: string; handle: string; memberIds: string[] }>
): Promise<UserGroup> {
  const res = await api.patch(`/user-groups/${groupId}`, data);
  return res.data;
}

export async function deleteUserGroup(groupId: string): Promise<void> {
  await api.delete(`/user-groups/${groupId}`);
}

// --- Connect / Shared Channels ---

export interface SharedChannel {
  id: string;
  name: string;
  channel_id: string;
  shared_with_domain: string;
  status: string;
  shared_at?: string;
  accepted_at?: string;
}

export async function getSharedChannels(): Promise<SharedChannel[]> {
  const res = await api.get("/connect/shared-channels");
  if (Array.isArray(res.data)) return res.data;
  return res.data.channels || [];
}

export async function shareChannel(channelId: string, targetDomain: string): Promise<SharedChannel> {
  const res = await api.post("/connect/shared-channels", {
    channel_id: channelId,
    target_domain: targetDomain,
  });
  return res.data;
}

export async function acceptSharedChannel(inviteId: string): Promise<SharedChannel> {
  const res = await api.post(`/connect/shared-channels/${inviteId}/accept`, {});
  return res.data;
}

// --- Templates ---

export interface Template {
  id: string;
  name: string;
  description?: string;
  category: string;
  icon?: string;
  channels?: { name: string; description?: string; is_private?: boolean }[];
  created_by?: string;
  created_at?: string;
}

export async function getTemplates(category?: string): Promise<Template[]> {
  const params = category ? { category } : undefined;
  const res = await api.get("/templates", { params });
  if (Array.isArray(res.data)) return res.data;
  return res.data.templates || [];
}

export async function createTemplate(data: {
  name: string;
  description?: string;
  category: string;
  channels?: { name: string; description?: string; is_private?: boolean }[];
}): Promise<Template> {
  const res = await api.post("/templates", data);
  return res.data;
}

export async function deleteTemplate(id: string): Promise<void> {
  await api.delete(`/templates/${id}`);
}

// --- Guest Accounts ---

export interface Guest {
  id: string;
  email: string;
  name?: string;
  display_name?: string;
  displayName?: string;
  type: "single" | "multi";
  channels?: { id: string; name: string }[];
  status?: string;
  invited_by?: string;
  invited_at?: string;
  last_active?: string;
  expires_at?: string;
}

export async function getGuests(): Promise<Guest[]> {
  const res = await api.get("/admin/guests");
  if (Array.isArray(res.data)) return res.data;
  return res.data.guests || [];
}

export async function inviteGuest(
  email: string,
  channels: string[],
  type: "single" | "multi"
): Promise<Guest> {
  const res = await api.post("/admin/guests", { email, channels, type });
  return res.data;
}

export async function updateGuest(
  id: string,
  data: Partial<{ name: string; display_name: string; channels: string[]; status: string; expires_at: string }>
): Promise<Guest> {
  const res = await api.patch(`/admin/guests/${id}`, data);
  return res.data;
}

export async function removeGuest(id: string): Promise<void> {
  await api.delete(`/admin/guests/${id}`);
}

// --- Data Export ---

export interface ExportResult {
  id: string;
  type: string;
  status: string;
  started_at?: string;
  completed_at?: string;
  download_url?: string;
  date_range?: { from: string; to: string };
}

export async function exportData(
  type: string,
  dateRange?: { from: string; to: string }
): Promise<ExportResult> {
  const res = await api.post("/admin/export", { type, date_range: dateRange });
  return res.data;
}

export async function getExportStatus(exportId: string): Promise<ExportResult> {
  const res = await api.get(`/admin/export/${exportId}`);
  return res.data;
}

// --- Data Retention ---

export interface RetentionPolicy {
  id: string;
  name: string;
  description?: string;
  scope: "messages" | "files" | "all";
  duration_days: number;
  channel_ids?: string[];
  action: "delete" | "archive";
  enabled: boolean;
  created_at?: string;
  updated_at?: string;
}

export async function getRetentionPolicies(): Promise<RetentionPolicy[]> {
  const res = await api.get("/admin/retention");
  if (Array.isArray(res.data)) return res.data;
  return res.data.policies || [];
}

export async function createRetentionPolicy(data: {
  name: string;
  description?: string;
  scope: "messages" | "files" | "all";
  duration_days: number;
  channel_ids?: string[];
  action: "delete" | "archive";
}): Promise<RetentionPolicy> {
  const res = await api.post("/admin/retention", data);
  return res.data;
}

export async function updateRetentionPolicy(
  id: string,
  data: Partial<{ name: string; description: string; scope: string; duration_days: number; channel_ids: string[]; action: string; enabled: boolean }>
): Promise<RetentionPolicy> {
  const res = await api.patch(`/admin/retention/${id}`, data);
  return res.data;
}

export async function deleteRetentionPolicy(id: string): Promise<void> {
  await api.delete(`/admin/retention/${id}`);
}

// --- Bot Users ---

export interface Bot {
  id: string;
  name: string;
  display_name?: string;
  email?: string;
  description?: string;
  icon_url?: string;
  scopes?: string[];
  enabled: boolean;
  channels?: { id: string; name: string }[];
  created_at?: string;
  updated_at?: string;
}

export async function getBots(): Promise<Bot[]> {
  const res = await api.get("/bots");
  if (Array.isArray(res.data)) return res.data;
  return res.data.bots || [];
}

export async function createBot(data: {
  name: string;
  display_name?: string;
  description?: string;
  scopes?: string[];
  channels?: string[];
}): Promise<Bot> {
  const res = await api.post("/bots", data);
  return res.data;
}

export async function updateBot(
  id: string,
  data: Partial<{ name: string; display_name: string; description: string; scopes: string[]; channels: string[]; enabled: boolean }>
): Promise<Bot> {
  const res = await api.patch(`/bots/${id}`, data);
  return res.data;
}

export async function deleteBot(id: string): Promise<void> {
  await api.delete(`/bots/${id}`);
}

// --- Workflow Executions ---

export interface WorkflowExecution {
  id: string;
  workflow_id: string;
  workflow_name?: string;
  status: "running" | "completed" | "failed" | "cancelled";
  trigger?: string;
  started_at: string;
  completed_at?: string;
  duration_ms?: number;
  steps?: { step_id: string; name: string; status: string; output?: string; error?: string }[];
  error?: string;
}

export async function getWorkflowExecutions(workflowId?: string): Promise<WorkflowExecution[]> {
  const params = workflowId ? { workflow_id: workflowId } : undefined;
  const res = await api.get("/workflows/executions", { params });
  if (Array.isArray(res.data)) return res.data;
  return res.data.executions || [];
}

export async function getWorkflowExecution(id: string): Promise<WorkflowExecution> {
  const res = await api.get(`/workflows/executions/${id}`);
  return res.data;
}

// --- AI Search ---

export interface AISearchResult {
  query: string;
  answer: string;
  sources?: { type: string; id: string; text?: string; channel_name?: string; created_at?: string }[];
  related_questions?: string[];
}

export async function aiSearch(query: string): Promise<AISearchResult> {
  const res = await api.post("/ai/search", { query });
  return res.data;
}

export interface AIConversation {
  id: string;
  query: string;
  answer: string;
  sources?: { type: string; id: string }[];
  created_at: string;
}

export async function getAIConversations(): Promise<AIConversation[]> {
  const res = await api.get("/ai/conversations");
  if (Array.isArray(res.data)) return res.data;
  return res.data.conversations || [];
}

// --- Security: 2FA ---

export interface TwoFASetup {
  qr_code_url: string;
  secret: string;
  backup_codes: string[];
}

export async function enable2FA(): Promise<TwoFASetup> {
  const res = await api.post("/security/2fa/enable");
  return res.data;
}

export async function verify2FA(token: string): Promise<{ verified: boolean }> {
  const res = await api.post("/security/2fa/verify", { token });
  return res.data;
}

export async function disable2FA(): Promise<void> {
  await api.post("/security/2fa/disable", {});
}

// --- Security: SSO / SAML ---

export interface SAMLConfig {
  enabled: boolean;
  entry_point: string;
  issuer: string;
  cert: string;
  domain: string;
  sign_in_url?: string;
  sign_out_url?: string;
}

export async function configureSAML(config: {
  entry_point: string;
  issuer: string;
  cert: string;
  domain: string;
}): Promise<SAMLConfig> {
  const res = await api.post("/security/saml", config);
  return res.data;
}

export async function getSAMLConfig(): Promise<SAMLConfig | null> {
  const res = await api.get("/security/saml");
  return res.data;
}

// --- Security: DLP ---

export interface DLPPolicy {
  id: string;
  name: string;
  description?: string;
  enabled: boolean;
  patterns: string[];
  action: "block" | "alert" | "redact";
  channels?: string[];
  created_at?: string;
}

export async function getDLPPolicies(): Promise<DLPPolicy[]> {
  const res = await api.get("/security/dlp");
  if (Array.isArray(res.data)) return res.data;
  return res.data.policies || [];
}

export async function createDLPolicy(data: {
  name: string;
  description?: string;
  patterns: string[];
  action: "block" | "alert" | "redact";
  channels?: string[];
}): Promise<DLPPolicy> {
  const res = await api.post("/security/dlp", data);
  return res.data;
}

// --- Security: Information Barriers ---

export interface InformationBarrier {
  id: string;
  name: string;
  description?: string;
  group_a: string[];
  group_b: string[];
  enabled: boolean;
  created_at?: string;
}

export async function getInformationBarriers(): Promise<InformationBarrier[]> {
  const res = await api.get("/security/barriers");
  if (Array.isArray(res.data)) return res.data;
  return res.data.barriers || [];
}

export async function createInformationBarrier(data: {
  name: string;
  description?: string;
  group_a: string[];
  group_b: string[];
}): Promise<InformationBarrier> {
  const res = await api.post("/security/barriers", data);
  return res.data;
}

export async function deleteInformationBarrier(id: string): Promise<void> {
  await api.delete(`/security/barriers/${id}`);
}

export default api;