'use server';


import { executeServerAction } from '@/lib/api/execute-server-action';
import { buildApiUrl } from '@/lib/api/query-params';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { cookies } from 'next/headers';
import type { SalaryRecord, SalaryDetail, PaymentStatus } from './types';

// API 응답 타입
interface SalaryApiData {
  id: number;
  tenant_id: number;
  employee_id: number;
  year: number;
  month: number;
  base_salary: string;
  total_allowance: string;
  total_overtime: string;
  total_bonus: string;
  total_deduction: string;
  net_payment: string;
  allowance_details: Record<string, number> | null;
  deduction_details: Record<string, number> | null;
  payment_date: string | null;
  status: 'scheduled' | 'completed';
  employee?: {
    id: number;
    name: string;
    user_id?: string;
    email?: string;
  } | null;
  employee_profile?: {
    id: number;
    department_id: number | null;
    position_key: string | null;
    job_title_key: string | null;
    position_label: string | null;
    job_title_label: string | null;
    rank: string | null;
    department?: {
      id: number;
      name: string;
    } | null;
  } | null;
  created_at: string;
  updated_at: string;
}

interface SalaryPaginationData {
  data: SalaryApiData[];
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

interface StatisticsApiData {
  total_net_payment: number;
  total_base_salary: number;
  total_allowance: number;
  total_overtime: number;
  total_bonus: number;
  total_deduction: number;
  count: number;
  scheduled_count: number;
  completed_count: number;
}

// API → Frontend 변환 (목록용)
function transformApiToFrontend(apiData: SalaryApiData): SalaryRecord {
  const profile = apiData.employee_profile;
  return {
    id: String(apiData.id),
    employeeId: apiData.employee?.user_id || `EMP${String(apiData.employee_id).padStart(3, '0')}`,
    employeeName: apiData.employee?.name || '-',
    department: profile?.department?.name || '-',
    position: profile?.job_title_label || '-',
    rank: profile?.rank || '-',
    baseSalary: parseFloat(apiData.base_salary),
    allowance: parseFloat(apiData.total_allowance),
    overtime: parseFloat(apiData.total_overtime),
    bonus: parseFloat(apiData.total_bonus),
    deduction: parseFloat(apiData.total_deduction),
    netPayment: parseFloat(apiData.net_payment),
    paymentDate: apiData.payment_date || '',
    status: apiData.status as PaymentStatus,
    year: apiData.year,
    month: apiData.month,
    createdAt: apiData.created_at,
    updatedAt: apiData.updated_at,
  };
}

// API → Frontend 변환 (상세용)
function transformApiToDetail(apiData: SalaryApiData): SalaryDetail {
  const allowanceDetails = apiData.allowance_details || {};
  const deductionDetails = apiData.deduction_details || {};
  const profile = apiData.employee_profile;

  return {
    employeeId: apiData.employee?.user_id || `EMP${String(apiData.employee_id).padStart(3, '0')}`,
    employeeName: apiData.employee?.name || '-',
    department: profile?.department?.name || '-',
    position: profile?.job_title_label || '-',
    rank: profile?.rank || '-',
    baseSalary: parseFloat(apiData.base_salary),
    allowances: {
      positionAllowance: allowanceDetails.position_allowance || 0,
      overtimeAllowance: allowanceDetails.overtime_allowance || 0,
      mealAllowance: allowanceDetails.meal_allowance || 0,
      transportAllowance: allowanceDetails.transport_allowance || 0,
      otherAllowance: allowanceDetails.other_allowance || 0,
    },
    deductions: {
      nationalPension: deductionDetails.national_pension || 0,
      healthInsurance: deductionDetails.health_insurance || 0,
      longTermCare: deductionDetails.long_term_care || 0,
      employmentInsurance: deductionDetails.employment_insurance || 0,
      incomeTax: deductionDetails.income_tax || 0,
      localIncomeTax: deductionDetails.local_income_tax || 0,
      otherDeduction: deductionDetails.other_deduction || 0,
    },
    totalAllowance: parseFloat(apiData.total_allowance),
    totalDeduction: parseFloat(apiData.total_deduction),
    netPayment: parseFloat(apiData.net_payment),
    paymentDate: apiData.payment_date || '',
    status: apiData.status as PaymentStatus,
    year: apiData.year,
    month: apiData.month,
  };
}

// ===== 급여 목록 조회 =====
export async function getSalaries(params?: {
  search?: string; year?: number; month?: number; status?: string;
  employee_id?: number; start_date?: string; end_date?: string;
  page?: number; per_page?: number;
}): Promise<{
  success: boolean;
  data?: SalaryRecord[];
  pagination?: { total: number; currentPage: number; lastPage: number };
  error?: string
}> {
  const result = await executeServerAction<SalaryPaginationData>({
    url: buildApiUrl('/api/v1/salaries', {
      search: params?.search,
      year: params?.year,
      month: params?.month,
      status: params?.status && params.status !== 'all' ? params.status : undefined,
      employee_id: params?.employee_id,
      start_date: params?.start_date,
      end_date: params?.end_date,
      page: params?.page,
      per_page: params?.per_page,
    }),
    errorMessage: '급여 목록을 불러오는데 실패했습니다.',
  });

  if (!result.success || !result.data) return { success: false, error: result.error };

  return {
    success: true,
    data: result.data.data.map(transformApiToFrontend),
    pagination: {
      total: result.data.total,
      currentPage: result.data.current_page,
      lastPage: result.data.last_page,
    },
  };
}

// ===== 급여 상세 조회 =====
export async function getSalary(id: string): Promise<{
  success: boolean; data?: SalaryDetail; error?: string
}> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/salaries/${id}`),
    transform: (data: SalaryApiData) => transformApiToDetail(data),
    errorMessage: '급여 정보를 불러오는데 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 급여 상태 변경 =====
export async function updateSalaryStatus(
  id: string,
  status: PaymentStatus
): Promise<{ success: boolean; data?: SalaryRecord; error?: string }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/salaries/${id}/status`),
    method: 'PATCH',
    body: { status },
    transform: (data: SalaryApiData) => transformApiToFrontend(data),
    errorMessage: '상태 변경에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 급여 일괄 상태 변경 =====
export async function bulkUpdateSalaryStatus(
  ids: string[],
  status: PaymentStatus
): Promise<{ success: boolean; updatedCount?: number; error?: string }> {
  const result = await executeServerAction<{ updated_count: number }>({
    url: buildApiUrl('/api/v1/salaries/bulk-update-status'),
    method: 'POST',
    body: { ids: ids.map(id => parseInt(id, 10)), status },
    errorMessage: '일괄 상태 변경에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, error: result.error };
  return { success: true, updatedCount: result.data.updated_count };
}

// ===== 급여 수정 =====
export async function updateSalary(
  id: string,
  data: {
    base_salary?: number;
    allowance_details?: Record<string, number>;
    deduction_details?: Record<string, number>;
    status?: PaymentStatus;
    payment_date?: string;
  }
): Promise<{ success: boolean; data?: SalaryDetail; error?: string }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/salaries/${id}`),
    method: 'PUT',
    body: data,
    transform: (d: SalaryApiData) => transformApiToDetail(d),
    errorMessage: '급여 수정에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 급여 통계 조회 =====
export async function getSalaryStatistics(params?: {
  year?: number; month?: number; start_date?: string; end_date?: string;
}): Promise<{
  success: boolean;
  data?: {
    totalNetPayment: number; totalBaseSalary: number; totalAllowance: number;
    totalOvertime: number; totalBonus: number; totalDeduction: number;
    count: number; scheduledCount: number; completedCount: number;
  };
  error?: string
}> {
  const result = await executeServerAction<StatisticsApiData>({
    url: buildApiUrl('/api/v1/salaries/statistics', {
      year: params?.year,
      month: params?.month,
      start_date: params?.start_date,
      end_date: params?.end_date,
    }),
    errorMessage: '통계 정보를 불러오는데 실패했습니다.',
  });

  if (!result.success || !result.data) return { success: false, error: result.error };

  return {
    success: true,
    data: {
      totalNetPayment: result.data.total_net_payment,
      totalBaseSalary: result.data.total_base_salary,
      totalAllowance: result.data.total_allowance,
      totalOvertime: result.data.total_overtime,
      totalBonus: result.data.total_bonus,
      totalDeduction: result.data.total_deduction,
      count: result.data.count,
      scheduledCount: result.data.scheduled_count,
      completedCount: result.data.completed_count,
    },
  };
}

// ===== 급여 엑셀 내보내기 (native fetch - keep as-is) =====
export async function exportSalaryExcel(params?: {
  year?: number;
  month?: number;
  status?: string;
  employee_id?: number;
  start_date?: string;
  end_date?: string;
}): Promise<{
  success: boolean;
  data?: Blob;
  filename?: string;
  error?: string;
}> {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get('access_token')?.value;

    const headers: HeadersInit = {
      'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Authorization': token ? `Bearer ${token}` : '',
      'X-API-KEY': process.env.API_KEY || '',
    };

    const url = buildApiUrl('/api/v1/salaries/export', {
      year: params?.year,
      month: params?.month,
      status: params?.status && params.status !== 'all' ? params.status : undefined,
      employee_id: params?.employee_id,
      start_date: params?.start_date,
      end_date: params?.end_date,
    });

    const response = await fetch(url, {
      method: 'GET',
      headers,
    });

    if (!response.ok) {
      return { success: false, error: `API 오류: ${response.status}` };
    }

    const blob = await response.blob();
    const contentDisposition = response.headers.get('Content-Disposition');
    const filenameMatch = contentDisposition?.match(/filename="?(.+)"?/);
    const filename = filenameMatch?.[1] || `급여명세_${params?.year || 'all'}_${params?.month || 'all'}.xlsx`;

    return { success: true, data: blob, filename };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    return { success: false, error: '서버 오류가 발생했습니다.' };
  }
}
