/**
 * 악성채권 추심관리 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/bad-debts - 목록 조회
 * - GET /api/v1/bad-debts/{id} - 상세 조회
 * - POST /api/v1/bad-debts - 등록
 * - PUT /api/v1/bad-debts/{id} - 수정
 * - DELETE /api/v1/bad-debts/{id} - 삭제
 * - PATCH /api/v1/bad-debts/{id}/toggle - 활성화 토글
 * - GET /api/v1/bad-debts/summary - 통계 조회
 */

'use server';


import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { revalidatePath } from 'next/cache';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type { BadDebtRecord, BadDebtItem, CollectionStatus } 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 BadDebtItemApiData {
  id: number;
  debt_amount: number;
  status: 'collecting' | 'legal_action' | 'recovered' | 'bad_debt';
  overdue_days: number;
  is_active: boolean;
  occurred_at: string | null;
  assigned_user?: {
    id: number;
    name: string;
  } | null;
}

// API 악성채권 데이터 타입 (거래처 기준)
interface BadDebtApiData {
  id: number;
  client_id: number;
  client_code: string;
  client_name: string;
  business_no: string | null;
  contact_person: string | null;
  phone: string | null;
  mobile: string | null;
  email: string | null;
  address: string | null;
  client_type: string | null;
  // 집계 데이터
  total_debt_amount: number;
  max_overdue_days: number;
  bad_debt_count: number;
  // 대표 상태
  status: 'collecting' | 'legal_action' | 'recovered' | 'bad_debt';
  is_active: boolean;
  // 담당자
  assigned_user?: {
    id: number;
    name: string;
  } | null;
  // 개별 악성채권 목록
  bad_debts: BadDebtItemApiData[];
}

// 통계 API 응답 타입
interface BadDebtSummaryApiData {
  total_amount: number;
  collecting_amount: number;
  legal_action_amount: number;
  recovered_amount: number;
  bad_debt_amount: number;
  total_count: number;
  collecting_count: number;
  legal_action_count: number;
  recovered_count: number;
  bad_debt_count: number;
}

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

/**
 * API 상태 → 프론트엔드 상태 변환
 * API: legal_action, bad_debt (snake_case)
 * Frontend: legalAction, badDebt (camelCase)
 */
function mapApiStatusToFrontend(apiStatus: string): CollectionStatus {
  switch (apiStatus) {
    case 'collecting': return 'collecting';
    case 'legal_action': return 'legalAction';
    case 'recovered': return 'recovered';
    case 'bad_debt': return 'badDebt';
    default: return 'collecting';
  }
}

/**
 * 프론트엔드 상태 → API 상태 변환
 */
function mapFrontendStatusToApi(status: CollectionStatus): string {
  switch (status) {
    case 'collecting': return 'collecting';
    case 'legalAction': return 'legal_action';
    case 'recovered': return 'recovered';
    case 'badDebt': return 'bad_debt';
    default: return 'collecting';
  }
}

/**
 * API client_type → 프론트엔드 vendorType 변환
 */
function mapClientTypeToVendorType(clientType?: string | null): 'sales' | 'purchase' | 'both' {
  switch (clientType) {
    case 'customer':
    case 'sales':
      return 'sales';
    case 'supplier':
    case 'purchase':
      return 'purchase';
    default:
      return 'both';
  }
}

/**
 * API 데이터 → 프론트엔드 타입 변환 (거래처 기준)
 */
function transformApiToFrontend(apiData: BadDebtApiData): BadDebtRecord {
  const manager = apiData.assigned_user;
  const firstBadDebt = apiData.bad_debts?.[0];

  return {
    id: String(apiData.id), // Client ID
    vendorId: String(apiData.client_id),
    vendorCode: apiData.client_code || '',
    vendorName: apiData.client_name || '거래처 없음',
    businessNumber: apiData.business_no || '',
    representativeName: '',
    vendorType: mapClientTypeToVendorType(apiData.client_type),
    businessType: '',
    businessCategory: '',
    zipCode: '',
    address1: apiData.address || '',
    address2: '',
    phone: apiData.phone || '',
    mobile: apiData.mobile || '',
    fax: '',
    email: apiData.email || '',
    contactName: apiData.contact_person || '',
    contactPhone: '',
    systemManager: '',
    // 집계 데이터
    debtAmount: apiData.total_debt_amount || 0,
    badDebtCount: apiData.bad_debt_count || 0,
    status: mapApiStatusToFrontend(apiData.status),
    overdueDays: apiData.max_overdue_days || 0,
    overdueToggle: apiData.is_active,
    occurrenceDate: firstBadDebt?.occurred_at || '',
    endDate: null,
    assignedManagerId: manager ? String(manager.id) : null,
    assignedManager: manager ? {
      id: String(manager.id),
      departmentName: '',
      name: manager.name,
      position: '',
      phone: '',
    } : null,
    settingToggle: apiData.is_active,
    // 개별 악성채권 목록
    badDebts: (apiData.bad_debts || []).map(bd => ({
      id: String(bd.id),
      debtAmount: bd.debt_amount || 0,
      status: mapApiStatusToFrontend(bd.status),
      overdueDays: bd.overdue_days || 0,
      isActive: bd.is_active,
      occurredAt: bd.occurred_at,
      assignedManager: bd.assigned_user ? {
        id: String(bd.assigned_user.id),
        name: bd.assigned_user.name,
      } : null,
    })),
    files: [],
    memos: [],
    createdAt: '',
    updatedAt: '',
  };
}

/**
 * 프론트엔드 데이터 → API 요청 형식 변환
 */
function transformFrontendToApi(data: Partial<BadDebtRecord>): Record<string, unknown> {
  return {
    client_id: data.vendorId ? parseInt(data.vendorId) : null,
    debt_amount: data.debtAmount || 0,
    status: data.status ? mapFrontendStatusToApi(data.status) : 'collecting',
    overdue_days: data.overdueDays || 0,
    occurred_at: data.occurrenceDate || null,
    closed_at: data.endDate || null,
    assigned_manager_id: data.assignedManagerId ? parseInt(data.assignedManagerId) : null,
    is_active: data.settingToggle ?? true,
    note: null,
  };
}

// ============================================
// API 호출 함수
// ============================================

/**
 * 악성채권 목록 조회
 */
export async function getBadDebts(params?: {
  page?: number;
  size?: number;
  status?: string;
  client_id?: string;
}): Promise<BadDebtRecord[]> {
  try {
    const searchParams = new URLSearchParams();

    if (params?.page) searchParams.set('page', String(params.page));
    if (params?.size) searchParams.set('size', String(params.size));
    if (params?.status && params.status !== 'all') {
      searchParams.set('status', mapFrontendStatusToApi(params.status as CollectionStatus));
    }
    if (params?.client_id && params.client_id !== 'all') {
      searchParams.set('client_id', params.client_id);
    }

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

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

    if (error) {
      console.error('[BadDebtActions] GET list error:', error.message);
      return [];
    }

    if (!response?.ok) {
      console.error('[BadDebtActions] GET list error:', response?.status);
      return [];
    }

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

    if (!result.success || !result.data?.data) {
      console.warn('[BadDebtActions] No data in response');
      return [];
    }

    return result.data.data.map(transformApiToFrontend);
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[BadDebtActions] getBadDebts error:', error);
    return [];
  }
}

/**
 * 악성채권 상세 조회
 */
export async function getBadDebtById(id: string): Promise<BadDebtRecord | null> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${id}`,
      { method: 'GET' }
    );

    if (error) {
      console.error('[BadDebtActions] GET detail error:', error.message);
      return null;
    }

    if (!response?.ok) {
      console.error('[BadDebtActions] GET detail error:', response?.status);
      return null;
    }

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

    if (!result.success || !result.data) {
      return null;
    }

    return transformApiToFrontend(result.data);
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[BadDebtActions] getBadDebtById error:', error);
    return null;
  }
}

/**
 * 악성채권 통계 조회
 */
export async function getBadDebtSummary(): Promise<BadDebtSummaryApiData | null> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/summary`,
      { method: 'GET' }
    );

    if (error) {
      console.error('[BadDebtActions] GET summary error:', error.message);
      return null;
    }

    if (!response?.ok) {
      console.error('[BadDebtActions] GET summary error:', response?.status);
      return null;
    }

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

    if (!result.success || !result.data) {
      return null;
    }

    return result.data;
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[BadDebtActions] getBadDebtSummary error:', error);
    return null;
  }
}

/**
 * 악성채권 등록
 */
export async function createBadDebt(
  data: Partial<BadDebtRecord>
): Promise<{ success: boolean; data?: BadDebtRecord; error?: string }> {
  try {
    const apiData = transformFrontendToApi(data);

    console.log('[BadDebtActions] POST request:', apiData);

    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts`,
      {
        method: 'POST',
        body: JSON.stringify(apiData),
      }
    );

    if (error) {
      return { success: false, error: error.message };
    }

    const result = await response?.json();

    if (!response?.ok || !result.success) {
      return {
        success: false,
        error: result?.message || '악성채권 등록에 실패했습니다.',
      };
    }

    revalidatePath('/accounting/bad-debt-collection');

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

/**
 * 악성채권 수정
 */
export async function updateBadDebt(
  id: string,
  data: Partial<BadDebtRecord>
): Promise<{ success: boolean; data?: BadDebtRecord; error?: string }> {
  try {
    const apiData = transformFrontendToApi(data);

    console.log('[BadDebtActions] PUT request:', apiData);

    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${id}`,
      {
        method: 'PUT',
        body: JSON.stringify(apiData),
      }
    );

    if (error) {
      return { success: false, error: error.message };
    }

    const result = await response?.json();

    if (!response?.ok || !result.success) {
      return {
        success: false,
        error: result?.message || '악성채권 수정에 실패했습니다.',
      };
    }

    revalidatePath('/accounting/bad-debt-collection');

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

/**
 * 악성채권 삭제
 */
export async function deleteBadDebt(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${id}`,
      { method: 'DELETE' }
    );

    if (error) {
      return { success: false, error: error.message };
    }

    const result = await response?.json();

    if (!response?.ok || !result.success) {
      return {
        success: false,
        error: result?.message || '악성채권 삭제에 실패했습니다.',
      };
    }

    revalidatePath('/accounting/bad-debt-collection');

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

/**
 * 악성채권 활성화 토글
 */
export async function toggleBadDebt(id: string): Promise<{ success: boolean; data?: BadDebtRecord; error?: string }> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${id}/toggle`,
      { method: 'PATCH' }
    );

    if (error) {
      return { success: false, error: error.message };
    }

    const result = await response?.json();

    if (!response?.ok || !result.success) {
      return {
        success: false,
        error: result?.message || '상태 변경에 실패했습니다.',
      };
    }

    revalidatePath('/accounting/bad-debt-collection');

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

/**
 * 악성채권 메모 추가
 */
export async function addBadDebtMemo(
  badDebtId: string,
  content: string
): Promise<{ success: boolean; data?: { id: string; content: string; createdAt: string; createdBy: string }; error?: string }> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${badDebtId}/memos`,
      {
        method: 'POST',
        body: JSON.stringify({ content }),
      }
    );

    if (error) {
      return { success: false, error: error.message };
    }

    const result = await response?.json();

    if (!response?.ok || !result.success) {
      return {
        success: false,
        error: result?.message || '메모 추가에 실패했습니다.',
      };
    }

    const memo = result.data;
    return {
      success: true,
      data: {
        id: String(memo.id),
        content: memo.content,
        createdAt: memo.created_at,
        createdBy: memo.created_by_user?.name || '사용자',
      },
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[BadDebtActions] addBadDebtMemo error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

/**
 * 악성채권 메모 삭제
 */
export async function deleteBadDebtMemo(
  badDebtId: string,
  memoId: string
): Promise<{ success: boolean; error?: string }> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bad-debts/${badDebtId}/memos/${memoId}`,
      { method: 'DELETE' }
    );

    if (error) {
      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('[BadDebtActions] deleteBadDebtMemo error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}