﻿import { fetchJson } from '@/shared/api/fetch-json';
import type {
  BugDetails,
  BugListMeta,
  BugListResponse,
  BugResponse,
  BugStats,
  CommentResponse,
  CreateBugPayload,
  MediaResponse,
  BugQueryParams,
  UpdateBugPayload,
} from './types';
import { isUnauthorizedError } from '@/lib/server-action-errors';

const buildQueryString = (params: BugQueryParams = {}) => {
  const searchParams = new URLSearchParams();

  if (params.search) {
    searchParams.set('search', params.search);
  }
  if (params.status) {
    searchParams.set('status', params.status);
  }
  if (params.priority) {
    searchParams.set('priority', params.priority);
  }
  if (params.platform) {
    searchParams.set('platform', params.platform);
  }
  if (params.osVersion) {
    searchParams.set('osVersion', params.osVersion);
  }
  if (params.deviceType) {
    searchParams.set('deviceType', params.deviceType);
  }
  if (params.assigneeId) {
    searchParams.set('assigneeId', params.assigneeId);
  }
  if (params.reporterId) {
    searchParams.set('reporterId', params.reporterId);
  }
  if (params.versionId) {
    searchParams.set('versionId', params.versionId);
  }
  if (params.projectId) {
    searchParams.set('projectId', params.projectId);
  }
  if (typeof params.page === 'number') {
    searchParams.set('page', String(params.page));
  }
  if (typeof params.limit === 'number') {
    searchParams.set('limit', String(params.limit));
  }
  if (params.sortBy) {
    searchParams.set('sortBy', params.sortBy);
  }
  if (params.sortOrder) {
    searchParams.set('sortOrder', params.sortOrder);
  }

  const query = searchParams.toString();
  return query ? `?${query}` : '';
};

interface RequestOptions {
  signal?: AbortSignal;
}

export async function fetchBugsList(params?: BugQueryParams, options: RequestOptions = {}): Promise<BugListResponse> {
  try {
    const { listBugs } = await import('./actions');
    
    const bugListOptions = {
      search: params?.search ?? null,
      status: params?.status ?? null,
      priority: params?.priority ?? null,
      platform: params?.platform ?? null,
      osVersion: params?.osVersion ?? null,
      deviceType: params?.deviceType ?? null,
      assigneeId: params?.assigneeId ?? null,
      reporterId: params?.reporterId ?? null,
      versionId: params?.versionId ?? null,
      projectId: params?.projectId ?? null,
      page: params?.page ?? 1,
      limit: params?.limit ?? 10,
      sortBy: (params?.sortBy ?? 'createdAt') as 'createdAt' | 'updatedAt',
      sortOrder: (params?.sortOrder ?? 'desc') as 'asc' | 'desc',
    };

    return await listBugs(bugListOptions);
  } catch (error) {
    // Обрабатываем ошибку 401 - редиректим на /login
    if (isUnauthorizedError(error)) {
      if (typeof window !== 'undefined') {
        const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
        window.location.href = `${basePath}/login`;
      }
      // Возвращаем пустой ответ, чтобы не ломать UI
      return {
        bugs: [],
        meta: {
          total: 0,
          page: 1,
          limit: 10,
          totalPages: 0,
        },
        stats: {
          total: 0,
          open: 0,
          inReview: 0,
          closed: 0,
        },
      };
    }
    throw error;
  }
}

export async function fetchBugDetails(bugId: string, options: RequestOptions = {}) {
  const { bug } = await fetchJson<BugResponse>(`/api/bugs/${bugId}`, {
    signal: options.signal,
  });
  // После JSON сериализации через API, Date становится string, enum остаются string
  // Это соответствует типу BugDetails
  return bug;
}

export async function createBug(payload: CreateBugPayload, projectId?: string | null, versionId?: string | null) {
  const params = new URLSearchParams();
  if (projectId)
    params.set('projectId', projectId);
  if (versionId)
    params.set('versionId', versionId);
  
  const queryString = params.toString();
  const url = queryString ? `/api/bugs?${queryString}` : '/api/bugs';
  
  const { bug } = await fetchJson<BugResponse>(url, {
    method: 'POST',
    body: JSON.stringify(payload),
  });

  return bug;
}

export async function updateBug(bugId: string, payload: UpdateBugPayload) {
  try {
    const { updateBug: updateBugAction } = await import('./actions');
    const result = await updateBugAction(bugId, payload);
    return result.bug;
  } catch (error) {
    // Обрабатываем ошибку 401 - редиректим на /login
    if (isUnauthorizedError(error)) {
      if (typeof window !== 'undefined') {
        const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
        window.location.href = `${basePath}/login`;
      }
      throw error;
    }
    throw error;
  }
}

export async function addBugComment(bugId: string, content: string, files?: File[]) {
  const formData = new FormData();
  formData.append('content', content);
  
  if (files && files.length > 0) {
    for (const file of files) {
      formData.append('files', file);
    }
  }

  const { comment } = await fetchJson<CommentResponse>(
    `/api/bugs/${bugId}/comments`,
    {
      method: 'POST',
      body: formData,
    }
  );

  return comment;
}

export async function updateBugComment(bugId: string, commentId: string, content: string) {
  const { comment } = await fetchJson<CommentResponse>(
    `/api/bugs/${bugId}/comments/${commentId}`,
    {
      method: 'PATCH',
      body: JSON.stringify({ content }),
    }
  );

  return comment;
}

export async function uploadBugMedia(bugId: string, file: File) {
  const formData = new FormData();
  formData.append('file', file);

  const { media } = await fetchJson<MediaResponse>(
    `/api/bugs/${bugId}/media`,
    {
      method: 'POST',
      body: formData,
    }
  );

  return media;
}

export async function deleteBugMedia(bugId: string, mediaId: string) {
  await fetchJson<void>(`/api/bugs/${bugId}/media/${mediaId}`, {
    method: 'DELETE',
  });
}

export async function markBugViewed(bugId: string) {
  return fetchJson<{ success: boolean; unreadCount: number }>(`/api/bugs/${bugId}/mark-viewed`, {
    method: 'POST',
  });
}

export async function createBugStatusHistory(bugId: string, oldStatus: string, newStatus: string) {
  const { historyEntry } = await fetchJson<{ historyEntry: any }>(
    `/api/bugs/${bugId}/status-history`,
    {
      method: 'POST',
      body: JSON.stringify({ oldStatus, newStatus }),
    }
  );

  return historyEntry;
}
