'use server';


import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type { Process, ProcessFormData, ClassificationRule, IndividualItem } from '@/types/process';

// ============================================================================
// API 타입 정의
// ============================================================================

interface ApiProcess {
  id: number;
  tenant_id: number;
  process_code: string;
  process_name: string;
  description: string | null;
  process_type: string;
  department: string | null;
  work_log_template: string | null;
  required_workers: number;
  equipment_info: string | null;
  work_steps: string[] | null;
  note: string | null;
  is_active: boolean;
  created_at: string;
  updated_at: string;
  classification_rules?: ApiClassificationRule[];
  process_items?: ApiProcessItem[];
}

interface ApiClassificationRule {
  id: number;
  process_id: number;
  registration_type: string;
  rule_type: string;
  matching_type: string;
  condition_value: string;
  priority: number;
  description: string | null;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

interface ApiProcessItem {
  id: number;
  process_id: number;
  item_id: number;
  priority: number;
  is_active: boolean;
  item?: {
    id: number;
    code: string;
    name: string;
  };
}

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

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

// ============================================================================
// 데이터 변환 함수
// ============================================================================

function transformApiToFrontend(apiData: ApiProcess): Process {
  // Pattern 규칙 변환
  const patternRules = (apiData.classification_rules ?? []).map(transformRuleApiToFrontend);

  // 개별 품목 → individual 분류 규칙으로 변환
  const individualRules = transformProcessItemsToRules(apiData.process_items ?? []);

  return {
    id: String(apiData.id),
    processCode: apiData.process_code,
    processName: apiData.process_name,
    description: apiData.description ?? undefined,
    processType: apiData.process_type as Process['processType'],
    department: apiData.department ?? '',
    workLogTemplate: apiData.work_log_template ?? undefined,
    classificationRules: [...patternRules, ...individualRules],
    requiredWorkers: apiData.required_workers,
    equipmentInfo: apiData.equipment_info ?? undefined,
    workSteps: apiData.work_steps ?? [],
    note: apiData.note ?? undefined,
    status: apiData.is_active ? '사용중' : '미사용',
    createdAt: apiData.created_at,
    updatedAt: apiData.updated_at,
  };
}

/**
 * process_items 배열을 individual 분류 규칙으로 변환
 * 모든 개별 품목을 하나의 규칙으로 통합
 */
function transformProcessItemsToRules(processItems: ApiProcessItem[]): ClassificationRule[] {
  if (processItems.length === 0) return [];

  const activeItems = processItems.filter(pi => pi.is_active);
  if (activeItems.length === 0) return [];

  // 모든 품목 ID를 쉼표로 구분하여 하나의 규칙으로 통합
  const itemIds = activeItems
    .map(pi => String(pi.item_id))
    .join(',');

  // 품목 상세 정보 추출 (code, name 포함)
  const items: IndividualItem[] = activeItems
    .filter(pi => pi.item) // item 정보가 있는 것만
    .map(pi => ({
      id: String(pi.item!.id),
      code: pi.item!.code,
      name: pi.item!.name,
    }));

  return [{
    id: `individual-${Date.now()}`,
    registrationType: 'individual',
    ruleType: '품목코드',
    matchingType: 'equals',
    conditionValue: itemIds,
    priority: 0,
    description: `개별 품목 ${activeItems.length}개`,
    isActive: true,
    createdAt: new Date().toISOString(),
    items, // 품목 상세 정보 추가
  }];
}

function transformRuleApiToFrontend(apiRule: ApiClassificationRule): ClassificationRule {
  return {
    id: String(apiRule.id),
    registrationType: apiRule.registration_type as ClassificationRule['registrationType'],
    ruleType: apiRule.rule_type as ClassificationRule['ruleType'],
    matchingType: apiRule.matching_type as ClassificationRule['matchingType'],
    conditionValue: apiRule.condition_value,
    priority: apiRule.priority,
    description: apiRule.description ?? undefined,
    isActive: apiRule.is_active,
    createdAt: apiRule.created_at,
  };
}

function transformFrontendToApi(data: ProcessFormData): Record<string, unknown> {
  // 패턴 규칙만 분리 (individual 제외)
  const patternRules = data.classificationRules.filter(
    (rule) => rule.registrationType === 'pattern'
  );

  // 개별 품목 규칙에서 item_ids 추출
  const individualRules = data.classificationRules.filter(
    (rule) => rule.registrationType === 'individual'
  );

  // 개별 품목의 conditionValue에서 ID 배열 추출 (쉼표 구분)
  const itemIds: number[] = individualRules.flatMap((rule) =>
    rule.conditionValue
      .split(',')
      .map((id) => parseInt(id.trim(), 10))
      .filter((n) => !isNaN(n) && n > 0)
  );

  return {
    process_name: data.processName,
    process_type: data.processType,
    department: data.department || null,
    work_log_template: data.workLogTemplate || null,
    required_workers: data.requiredWorkers,
    equipment_info: data.equipmentInfo || null,
    work_steps: data.workSteps ? data.workSteps.split(',').map((s) => s.trim()).filter(Boolean) : [],
    note: data.note || null,
    is_active: data.isActive,
    // 패턴 규칙만 전송 (registration_type 제외)
    classification_rules: patternRules.map((rule) => ({
      rule_type: rule.ruleType,
      matching_type: rule.matchingType,
      condition_value: rule.conditionValue,
      priority: rule.priority,
      description: rule.description || null,
      is_active: rule.isActive,
    })),
    // 개별 품목 ID 배열 전송
    item_ids: itemIds,
  };
}

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

/**
 * 공정 목록 조회
 */
export async function getProcessList(params?: {
  page?: number;
  size?: number;
  q?: string;
  status?: string;
  process_type?: string;
}): Promise<{ success: boolean; data?: { items: Process[]; total: number; page: number; totalPages: number }; error?: string; __authError?: boolean }> {
  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?.q) searchParams.set('q', params.q);
    if (params?.status) searchParams.set('status', params.status);
    if (params?.process_type) searchParams.set('process_type', params.process_type);

    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes?${searchParams.toString()}`,
      { method: 'GET', cache: 'no-store' }
    );

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '목록 조회에 실패했습니다.' };
    }

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

    if (!response.ok || !result.success) {
      return { success: false, error: result.message || '목록 조회에 실패했습니다.' };
    }

    const transformed = result.data.data.map(transformApiToFrontend);

    return {
      success: true,
      data: {
        items: transformed,
        total: result.data.total,
        page: result.data.current_page,
        totalPages: result.data.last_page,
      },
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[getProcessList] Error:', error);
    return { success: false, error: '서버 오류가 발생했습니다.' };
  }
}

/**
 * 공정 상세 조회
 */
export async function getProcessById(id: string): Promise<{ success: boolean; data?: Process; error?: string; __authError?: boolean }> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes/${id}`, {
      method: 'GET',
      cache: 'no-store',
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '조회에 실패했습니다.' };
    }

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

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

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

/**
 * 공정 생성
 */
export async function createProcess(data: ProcessFormData): Promise<{ success: boolean; data?: Process; error?: string; __authError?: boolean }> {
  try {
    const apiData = transformFrontendToApi(data);

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

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '등록에 실패했습니다.' };
    }

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

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

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

/**
 * 공정 수정
 */
export async function updateProcess(id: string, data: ProcessFormData): Promise<{ success: boolean; data?: Process; error?: string; __authError?: boolean }> {
  try {
    const apiData = transformFrontendToApi(data);

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

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '수정에 실패했습니다.' };
    }

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

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

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

/**
 * 공정 삭제
 */
export async function deleteProcess(id: string): Promise<{ success: boolean; error?: string; __authError?: boolean }> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes/${id}`, {
      method: 'DELETE',
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '삭제에 실패했습니다.' };
    }

    const result: ApiResponse<null> = 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('[deleteProcess] Error:', error);
    return { success: false, error: '서버 오류가 발생했습니다.' };
  }
}

/**
 * 공정 일괄 삭제
 */
export async function deleteProcesses(ids: string[]): Promise<{ success: boolean; deletedCount?: number; error?: string; __authError?: boolean }> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes`, {
      method: 'DELETE',
      body: JSON.stringify({ ids: ids.map((id) => parseInt(id, 10)) }),
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '일괄 삭제에 실패했습니다.' };
    }

    const result: ApiResponse<{ deleted_count: number }> = await response.json();

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

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

/**
 * 공정 상태 토글
 */
export async function toggleProcessActive(id: string): Promise<{ success: boolean; data?: Process; error?: string; __authError?: boolean }> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes/${id}/toggle`, {
      method: 'PATCH',
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

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

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

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

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

/**
 * 공정 옵션 목록 (드롭다운용)
 */
export async function getProcessOptions(): Promise<{
  success: boolean;
  data?: Array<{ id: string; processCode: string; processName: string; processType: string; department: string }>;
  error?: string;
  __authError?: boolean;
}> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes/options`, {
      method: 'GET',
      cache: 'no-store',
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '옵션 조회에 실패했습니다.' };
    }

    const result: ApiResponse<Array<{ id: number; process_code: string; process_name: string; process_type: string; department: string }>> =
      await response.json();

    if (!response.ok || !result.success) {
      return { success: false, error: result.message || '옵션 조회에 실패했습니다.' };
    }

    return {
      success: true,
      data: result.data.map((item) => ({
        id: String(item.id),
        processCode: item.process_code,
        processName: item.process_name,
        processType: item.process_type,
        department: item.department ?? '',
      })),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[getProcessOptions] Error:', error);
    return { success: false, error: '서버 오류가 발생했습니다.' };
  }
}

/**
 * 공정 통계
 */
export async function getProcessStats(): Promise<{
  success: boolean;
  data?: { total: number; active: number; inactive: number; byType: Record<string, number> };
  error?: string;
  __authError?: boolean;
}> {
  try {
    const { response, error } = await serverFetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/processes/stats`, {
      method: 'GET',
      cache: 'no-store',
    });

    if (error) {
      return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED' };
    }

    if (!response) {
      return { success: false, error: '통계 조회에 실패했습니다.' };
    }

    const result: ApiResponse<{ total: number; active: number; inactive: number; by_type: Record<string, number> }> = await response.json();

    if (!response.ok || !result.success) {
      return { success: false, error: result.message || '통계 조회에 실패했습니다.' };
    }

    return {
      success: true,
      data: {
        total: result.data.total,
        active: result.data.active,
        inactive: result.data.inactive,
        byType: result.data.by_type,
      },
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[getProcessStats] Error:', error);
    return { success: false, error: '서버 오류가 발생했습니다.' };
  }
}

// ============================================================================
// 부서 옵션 타입 및 함수
// ============================================================================

export interface DepartmentOption {
  id: string;
  value: string;
  label: string;
}

/**
 * 부서 목록 조회
 */
export async function getDepartmentOptions(): Promise<DepartmentOption[]> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/departments`,
      {
        method: 'GET',
        cache: 'no-store',
      }
    );

    if (error || !response?.ok) {
      // 기본 부서 옵션 반환
      return [
        { id: 'default-1', value: '생산부', label: '생산부' },
        { id: 'default-2', value: '품질관리부', label: '품질관리부' },
        { id: 'default-3', value: '물류부', label: '물류부' },
        { id: 'default-4', value: '영업부', label: '영업부' },
      ];
    }

    const result = await response.json();
    if (result.success && result.data?.data) {
      // 중복 부서명 제거 (같은 이름이 여러 개일 경우 첫 번째만 사용)
      const seenNames = new Set<string>();
      return result.data.data
        .filter((dept: { id: number; name: string }) => {
          if (seenNames.has(dept.name)) {
            return false;
          }
          seenNames.add(dept.name);
          return true;
        })
        .map((dept: { id: number; name: string }) => ({
          id: String(dept.id),
          value: dept.name,
          label: dept.name,
        }));
    }

    return [];
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[getDepartmentOptions] Error:', error);
    return [];
  }
}

// ============================================================================
// 품목 옵션 타입 및 함수
// ============================================================================

export interface ItemOption {
  value: string;
  label: string;
  code: string;
  id: string;
  fullName: string;
  type: string;
}

interface GetItemListParams {
  q?: string;
  itemType?: string;
  size?: number;
}

/**
 * 품목 목록 조회 (분류 규칙용)
 */
export async function getItemList(params?: GetItemListParams): Promise<ItemOption[]> {
  try {
    const searchParams = new URLSearchParams();
    searchParams.set('size', String(params?.size || 1000));
    if (params?.q) searchParams.set('q', params.q);
    if (params?.itemType) searchParams.set('item_type', params.itemType);

    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/items?${searchParams.toString()}`,
      {
        method: 'GET',
        cache: 'no-store',
      }
    );

    if (error || !response?.ok) {
      return [];
    }

    const result = await response.json();
    if (result.success && result.data?.data) {
      return result.data.data.map((item: { id: number; name: string; code?: string; item_type?: string }) => ({
        value: String(item.id),
        label: item.name,
        code: item.code || '',
        id: String(item.id),
        fullName: item.name,
        type: item.item_type || '',
      }));
    }

    return [];
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[getItemList] Error:', error);
    return [];
  }
}
