/**
 * 참조함 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/approvals/reference - 참조함 목록 조회
 * - POST /api/v1/approvals/{id}/read - 열람 처리
 * - POST /api/v1/approvals/{id}/unread - 미열람 처리
 */

'use server';


import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type { ReferenceRecord, ApprovalType, DocumentStatus } from './types';

// ============================================
// API 응답 타입 정의
// ============================================

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message: string;
}

interface PaginatedResponse<T> {
  current_page: number;
  data: T[];
  total: number;
  per_page: number;
  last_page: number;
}

// API 응답의 참조 문서 타입
interface ReferenceApiData {
  id: number;
  document_number: string;
  title: string;
  status: string;
  form?: {
    id: number;
    name: string;
    code: string;
    category: string;
  };
  drafter?: {
    id: number;
    name: string;
    position?: string;
    department?: { name: string };
  };
  steps?: ReferenceStepApiData[];
  created_at: string;
  updated_at: string;
}

interface ReferenceStepApiData {
  id: number;
  step_order: number;
  step_type: string;
  approver_id: number;
  approver?: {
    id: number;
    name: string;
    position?: string;
    department?: { name: string };
  };
  is_read: boolean;
  read_at?: string;
}

// ============================================
// 헬퍼 함수
// ============================================

/**
 * API 상태 → 프론트엔드 상태 변환
 */
function mapApiStatus(apiStatus: string): DocumentStatus {
  const statusMap: Record<string, DocumentStatus> = {
    'draft': 'pending',
    'pending': 'pending',
    'in_progress': 'pending',
    'approved': 'approved',
    'rejected': 'rejected',
  };
  return statusMap[apiStatus] || 'pending';
}

/**
 * 양식 카테고리 → 결재 유형 변환
 */
function mapApprovalType(formCategory?: string): ApprovalType {
  const typeMap: Record<string, ApprovalType> = {
    'expense_report': 'expense_report',
    'proposal': 'proposal',
    'expense_estimate': 'expense_estimate',
  };
  return typeMap[formCategory || ''] || 'proposal';
}

/**
 * API 데이터 → 프론트엔드 데이터 변환
 */
function transformApiToFrontend(data: ReferenceApiData): ReferenceRecord {
  // 참조 단계에서 열람 상태 추출
  const referenceStep = data.steps?.find(s => s.step_type === 'reference');
  const isRead = referenceStep?.is_read ?? false;
  const readAt = referenceStep?.read_at;

  return {
    id: String(data.id),
    documentNo: data.document_number,
    approvalType: mapApprovalType(data.form?.category),
    title: data.title,
    draftDate: data.created_at.replace('T', ' ').substring(0, 16),
    drafter: data.drafter?.name || '',
    drafterDepartment: data.drafter?.department?.name || '',
    drafterPosition: data.drafter?.position || '',
    documentStatus: mapApiStatus(data.status),
    readStatus: isRead ? 'read' : 'unread',
    readAt: readAt ? readAt.replace('T', ' ').substring(0, 16) : undefined,
    createdAt: data.created_at,
    updatedAt: data.updated_at,
  };
}

// ============================================
// API 함수
// ============================================

/**
 * 참조함 목록 조회
 */
export async function getReferences(params?: {
  page?: number;
  per_page?: number;
  search?: string;
  is_read?: boolean;
  approval_type?: string;
  sort_by?: string;
  sort_dir?: 'asc' | 'desc';
}): Promise<{ data: ReferenceRecord[]; total: number; lastPage: number }> {
  try {
    const searchParams = new URLSearchParams();

    if (params?.page) searchParams.set('page', String(params.page));
    if (params?.per_page) searchParams.set('per_page', String(params.per_page));
    if (params?.search) searchParams.set('search', params.search);
    if (params?.is_read !== undefined) {
      searchParams.set('is_read', params.is_read ? '1' : '0');
    }
    if (params?.approval_type && params.approval_type !== 'all') {
      searchParams.set('approval_type', params.approval_type);
    }
    if (params?.sort_by) searchParams.set('sort_by', params.sort_by);
    if (params?.sort_dir) searchParams.set('sort_dir', params.sort_dir);

    const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/approvals/reference?${searchParams.toString()}`;

    const { response, error } = await serverFetch(url, {
      method: 'GET',
    });

    // serverFetch handles 401 with redirect, so we just check for other errors
    if (error || !response) {
      console.error('[ReferenceBoxActions] GET reference error:', error?.message);
      return { data: [], total: 0, lastPage: 1 };
    }

    if (!response.ok) {
      console.error('[ReferenceBoxActions] GET reference error:', response.status);
      return { data: [], total: 0, lastPage: 1 };
    }

    const result: ApiResponse<PaginatedResponse<ReferenceApiData>> = await response.json();

    if (!result.success || !result.data?.data) {
      console.warn('[ReferenceBoxActions] No data in response');
      return { data: [], total: 0, lastPage: 1 };
    }

    return {
      data: result.data.data.map(transformApiToFrontend),
      total: result.data.total,
      lastPage: result.data.last_page,
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ReferenceBoxActions] getReferences error:', error);
    return { data: [], total: 0, lastPage: 1 };
  }
}

/**
 * 참조함 통계 (목록 데이터 기반)
 */
export async function getReferenceSummary(): Promise<{ all: number; read: number; unread: number } | null> {
  try {
    // 전체 데이터를 조회해서 통계 계산
    const allResult = await getReferences({ per_page: 1 });
    const readResult = await getReferences({ per_page: 1, is_read: true });
    const unreadResult = await getReferences({ per_page: 1, is_read: false });

    return {
      all: allResult.total,
      read: readResult.total,
      unread: unreadResult.total,
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ReferenceBoxActions] getReferenceSummary error:', error);
    return null;
  }
}

/**
 * 열람 처리
 */
export async function markAsRead(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/approvals/${id}/read`;

    const { response, error } = await serverFetch(url, {
      method: 'POST',
      body: JSON.stringify({}),
    });

    // serverFetch handles 401 with redirect
    if (error || !response) {
      return {
        success: false,
        error: error?.message || '열람 처리에 실패했습니다.',
      };
    }

    const result = await response.json();

    if (!response.ok || !result.success) {
      return {
        success: false,
        error: result.message || '열람 처리에 실패했습니다.',
      };
    }

    return { success: true };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ReferenceBoxActions] markAsRead error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

/**
 * 미열람 처리
 */
export async function markAsUnread(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/approvals/${id}/unread`;

    const { response, error } = await serverFetch(url, {
      method: 'POST',
      body: JSON.stringify({}),
    });

    // serverFetch handles 401 with redirect
    if (error || !response) {
      return {
        success: false,
        error: error?.message || '미열람 처리에 실패했습니다.',
      };
    }

    const result = await response.json();

    if (!response.ok || !result.success) {
      return {
        success: false,
        error: result.message || '미열람 처리에 실패했습니다.',
      };
    }

    return { success: true };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ReferenceBoxActions] markAsUnread error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

/**
 * 일괄 열람 처리
 */
export async function markAsReadBulk(ids: string[]): Promise<{ success: boolean; failedIds?: string[]; error?: string }> {
  const failedIds: string[] = [];

  for (const id of ids) {
    const result = await markAsRead(id);
    if (!result.success) {
      failedIds.push(id);
    }
  }

  if (failedIds.length > 0) {
    return {
      success: false,
      failedIds,
      error: `${failedIds.length}건의 열람 처리에 실패했습니다.`,
    };
  }

  return { success: true };
}

/**
 * 일괄 미열람 처리
 */
export async function markAsUnreadBulk(ids: string[]): Promise<{ success: boolean; failedIds?: string[]; error?: string }> {
  const failedIds: string[] = [];

  for (const id of ids) {
    const result = await markAsUnread(id);
    if (!result.success) {
      failedIds.push(id);
    }
  }

  if (failedIds.length > 0) {
    return {
      success: false,
      failedIds,
      error: `${failedIds.length}건의 미열람 처리에 실패했습니다.`,
    };
  }

  return { success: true };
}