/**
 * 품목기준관리 API 클라이언트
 *
 * Laravel 백엔드와 통신하는 API 함수들
 * 동적 페이지 구성, 버전 관리, 멀티테넌시 지원
 */

import type {
  PageConfig,
  PageConfigRevision,
  PageType,
  DynamicFormData,
  FetchPageConfigParams,
  MasterDataApiResponse,
  VersionComparisonResult,
} from '@/types/master-data';

// ===== 환경 변수 =====

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';

// ===== 유틸리티 함수 =====

/**
 * 인증 토큰 가져오기
 */
function getAuthToken(): string | null {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('auth_token');
  }
  return null;
}

/**
 * Fetch 옵션 생성
 */
function createFetchOptions(options: RequestInit = {}): RequestInit {
  const token = getAuthToken();
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
  };

  // Merge existing headers if they are a plain object
  if (options.headers && typeof options.headers === 'object' && !Array.isArray(options.headers)) {
    Object.assign(headers, options.headers);
  }

  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  return {
    ...options,
    headers,
    credentials: 'include',
  };
}

/**
 * API 에러 처리
 */
async function handleApiResponse<T>(response: Response): Promise<T> {
  if (!response.ok) {
    const error = await response.json().catch(() => ({
      message: 'API 요청 실패',
    }));

    throw new Error(error.message || `HTTP ${response.status}: ${response.statusText}`);
  }

  const data = await response.json();
  return data;
}

// ===== 페이지 구성 CRUD =====

/**
 * 페이지 구성 목록 조회
 *
 * @example
 * const configs = await fetchPageConfigs({ pageType: 'item-master' });
 */
export async function fetchPageConfigs(
  params?: FetchPageConfigParams
): Promise<PageConfig[]> {
  const queryParams = new URLSearchParams();

  if (params) {
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        queryParams.append(key, String(value));
      }
    });
  }

  const url = `${API_URL}/api/master-data/pages${queryParams.toString() ? `?${queryParams}` : ''}`;

  const response = await fetch(url, createFetchOptions());
  const data = await handleApiResponse<MasterDataApiResponse<PageConfig[]>>(response);

  return data.data;
}

/**
 * 특정 페이지 타입의 최신 구성 조회
 *
 * @param pageType - 페이지 타입
 *
 * @example
 * const config = await fetchPageConfigByType('item-master');
 */
export async function fetchPageConfigByType(
  pageType: PageType
): Promise<PageConfig | null> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${pageType}`,
    createFetchOptions()
  );

  if (response.status === 404) {
    return null;
  }

  const data = await handleApiResponse<MasterDataApiResponse<PageConfig>>(response);
  return data.data;
}

/**
 * 페이지 구성 상세 조회 (특정 버전)
 *
 * @param id - 페이지 구성 ID
 * @param version - 버전 번호 (선택사항, 기본: 최신)
 *
 * @example
 * const config = await fetchPageConfigById('uuid', 2);
 */
export async function fetchPageConfigById(
  id: string,
  version?: number
): Promise<PageConfig> {
  const url = version
    ? `${API_URL}/api/master-data/pages/${id}?version=${version}`
    : `${API_URL}/api/master-data/pages/${id}`;

  const response = await fetch(url, createFetchOptions());
  const data = await handleApiResponse<MasterDataApiResponse<PageConfig>>(response);

  return data.data;
}

/**
 * 페이지 구성 생성
 *
 * @param configData - 페이지 구성 데이터
 *
 * @example
 * const newConfig = await createPageConfig({
 *   pageName: '품목기준정보',
 *   pageType: 'item-master',
 *   sections: [...],
 *   isActive: true,
 * });
 */
export async function createPageConfig(
  configData: Omit<PageConfig, 'id' | 'version' | 'createdAt' | 'updatedAt' | 'tenantId'>
): Promise<PageConfig> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages`,
    createFetchOptions({
      method: 'POST',
      body: JSON.stringify(configData),
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfig>>(response);
  return data.data;
}

/**
 * 페이지 구성 수정
 *
 * @param id - 페이지 구성 ID
 * @param updates - 수정할 필드들
 *
 * @example
 * const updatedConfig = await updatePageConfig('uuid', {
 *   sections: [...],
 * });
 */
export async function updatePageConfig(
  id: string,
  updates: Partial<PageConfig>
): Promise<PageConfig> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${id}`,
    createFetchOptions({
      method: 'PUT',
      body: JSON.stringify(updates),
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfig>>(response);
  return data.data;
}

/**
 * 페이지 구성 삭제
 *
 * @param id - 페이지 구성 ID
 */
export async function deletePageConfig(id: string): Promise<void> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${id}`,
    createFetchOptions({
      method: 'DELETE',
    })
  );

  await handleApiResponse<MasterDataApiResponse<null>>(response);
}

// ===== 버전 관리 =====

/**
 * 페이지 구성 버전 이력 조회
 *
 * @param pageConfigId - 페이지 구성 ID
 *
 * @example
 * const revisions = await fetchPageConfigRevisions('uuid');
 */
export async function fetchPageConfigRevisions(
  pageConfigId: string
): Promise<PageConfigRevision[]> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${pageConfigId}/revisions`,
    createFetchOptions()
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfigRevision[]>>(response);
  return data.data;
}

/**
 * 특정 버전 상세 조회
 *
 * @param pageConfigId - 페이지 구성 ID
 * @param version - 버전 번호
 */
export async function fetchPageConfigRevisionByVersion(
  pageConfigId: string,
  version: number
): Promise<PageConfigRevision> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${pageConfigId}/revisions/${version}`,
    createFetchOptions()
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfigRevision>>(response);
  return data.data;
}

/**
 * 버전 비교
 *
 * @param pageConfigId - 페이지 구성 ID
 * @param version1 - 비교할 버전 1
 * @param version2 - 비교할 버전 2
 *
 * @example
 * const comparison = await comparePageConfigVersions('uuid', 1, 2);
 */
export async function comparePageConfigVersions(
  pageConfigId: string,
  version1: number,
  version2: number
): Promise<VersionComparisonResult> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${pageConfigId}/compare?v1=${version1}&v2=${version2}`,
    createFetchOptions()
  );

  const data = await handleApiResponse<MasterDataApiResponse<VersionComparisonResult>>(response);
  return data.data;
}

/**
 * 버전 승인
 *
 * @param revisionId - 버전 ID
 *
 * @example
 * await approvePageConfigRevision('revision-uuid');
 */
export async function approvePageConfigRevision(
  revisionId: string
): Promise<PageConfigRevision> {
  const response = await fetch(
    `${API_URL}/api/master-data/revisions/${revisionId}/approve`,
    createFetchOptions({
      method: 'POST',
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfigRevision>>(response);
  return data.data;
}

/**
 * 특정 버전으로 롤백
 *
 * @param pageConfigId - 페이지 구성 ID
 * @param version - 롤백할 버전
 */
export async function rollbackPageConfig(
  pageConfigId: string,
  version: number
): Promise<PageConfig> {
  const response = await fetch(
    `${API_URL}/api/master-data/pages/${pageConfigId}/rollback`,
    createFetchOptions({
      method: 'POST',
      body: JSON.stringify({ version }),
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<PageConfig>>(response);
  return data.data;
}

// ===== 동적 폼 데이터 =====

/**
 * 동적 폼 데이터 조회
 *
 * @param pageType - 페이지 타입
 * @param id - 데이터 ID (선택사항)
 */
export async function fetchFormData(
  pageType: PageType,
  id?: string
): Promise<DynamicFormData | DynamicFormData[]> {
  const url = id
    ? `${API_URL}/api/master-data/form-data/${pageType}/${id}`
    : `${API_URL}/api/master-data/form-data/${pageType}`;

  const response = await fetch(url, createFetchOptions());
  const data = await handleApiResponse<MasterDataApiResponse<DynamicFormData | DynamicFormData[]>>(response);

  return data.data;
}

/**
 * 동적 폼 데이터 저장
 *
 * @param formData - 폼 데이터
 */
export async function saveFormData(
  formData: DynamicFormData
): Promise<DynamicFormData> {
  const response = await fetch(
    `${API_URL}/api/master-data/form-data`,
    createFetchOptions({
      method: 'POST',
      body: JSON.stringify(formData),
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<DynamicFormData>>(response);
  return data.data;
}

/**
 * 동적 폼 데이터 수정
 *
 * @param id - 데이터 ID
 * @param updates - 수정할 필드들
 */
export async function updateFormData(
  id: string,
  updates: Partial<DynamicFormData>
): Promise<DynamicFormData> {
  const response = await fetch(
    `${API_URL}/api/master-data/form-data/${id}`,
    createFetchOptions({
      method: 'PUT',
      body: JSON.stringify(updates),
    })
  );

  const data = await handleApiResponse<MasterDataApiResponse<DynamicFormData>>(response);
  return data.data;
}

/**
 * 동적 폼 데이터 삭제
 *
 * @param id - 데이터 ID
 */
export async function deleteFormData(id: string): Promise<void> {
  const response = await fetch(
    `${API_URL}/api/master-data/form-data/${id}`,
    createFetchOptions({
      method: 'DELETE',
    })
  );

  await handleApiResponse<MasterDataApiResponse<null>>(response);
}

// ===== 캐싱 =====

/**
 * 페이지 구성 캐시 무효화
 *
 * @param pageType - 페이지 타입 (선택사항, 전체 무효화 가능)
 */
export async function invalidatePageConfigCache(
  pageType?: PageType
): Promise<void> {
  const url = pageType
    ? `${API_URL}/api/master-data/cache/invalidate/${pageType}`
    : `${API_URL}/api/master-data/cache/invalidate`;

  const response = await fetch(
    url,
    createFetchOptions({
      method: 'POST',
    })
  );

  await handleApiResponse<MasterDataApiResponse<null>>(response);
}

/**
 * Next.js revalidation 트리거
 */
export async function revalidateMasterData(): Promise<void> {
  if (typeof window === 'undefined') {
    const { revalidatePath } = await import('next/cache');
    revalidatePath('/master-data');
  }
}
