'use server';

/**
 * 제품검사 관리 Server Actions
 *
 * API Endpoints:
 * - GET /api/v1/quality/documents - 목록 조회
 * - GET /api/v1/quality/documents/stats - 통계 조회
 * - GET /api/v1/quality/documents/calendar - 캘린더 스케줄 조회
 * - GET /api/v1/quality/documents/{id} - 상세 조회
 * - POST /api/v1/quality/documents - 등록
 * - PUT /api/v1/quality/documents/{id} - 수정
 * - DELETE /api/v1/quality/documents/{id} - 삭제
 * - PATCH /api/v1/quality/documents/{id}/complete - 검사 완료 처리
 * - GET /api/v1/quality/documents/available-orders - 수주 선택 목록 조회
 */

import { executeServerAction } from '@/lib/api/execute-server-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type {
  ProductInspection,
  ProductInspectionData,
  InspectionStats,
  InspectionStatus,
  InspectionCalendarItem,
  OrderSelectItem,
  InspectionFormData,
} from './types';
import {
  mockInspections,
  mockStats,
  mockCalendarItems,
  mockOrderSelectItems,
} from './mockData';

// 개발환경 Mock 데이터 fallback 플래그
const USE_MOCK_FALLBACK = false;

// ===== API 응답 타입 =====

interface ProductInspectionApi {
  id: number;
  quality_doc_number: string;
  site_name: string;
  client: string;
  client_id?: number | null;
  location_count: number;
  required_info: string;
  inspection_period: string;
  inspector: string;
  status: 'reception' | 'in_progress' | 'completed';
  author: string;
  reception_date: string;
  manager: string;
  manager_contact: string;
  construction_site: {
    site_name: string;
    land_location: string;
    lot_number: string;
  };
  material_distributor: {
    company_name: string;
    company_address: string;
    representative_name: string;
    phone: string;
  };
  constructor_info: {
    company_name: string;
    company_address: string;
    name: string;
    phone: string;
  };
  supervisor: {
    office_name: string;
    office_address: string;
    name: string;
    phone: string;
  };
  schedule_info: {
    visit_request_date: string;
    start_date: string;
    end_date: string;
    inspector: string;
    site_postal_code: string;
    site_address: string;
    site_address_detail: string;
  };
  order_items: Array<{
    id: string;
    order_id?: number;
    order_number: string;
    site_name: string;
    client_id?: number | null;
    client_name?: string;
    item_id?: number | null;
    item_name?: string;
    delivery_date: string;
    floor: string;
    symbol: string;
    order_width: number;
    order_height: number;
    construction_width: number;
    construction_height: number;
    change_reason: string;
    document_id?: number | null;
    inspection_data?: Record<string, unknown>;
  }>;
  request_document_id: number | null;
  created_at: string;
  updated_at: string;
}

interface PaginatedResponse {
  items: ProductInspectionApi[];
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

interface InspectionStatsApi {
  reception_count: number;
  in_progress_count: number;
  completed_count: number;
}

interface CalendarItemApi {
  id: number;
  start_date: string;
  end_date: string;
  inspector: string;
  site_name: string;
  status: 'reception' | 'in_progress' | 'completed';
}

interface OrderSelectItemApi {
  id: number;
  order_number: string;
  site_name: string;
  client_id: number | null;
  client_name: string;
  item_id: number | null;
  item_name: string;
  delivery_date: string;
  location_count: number;
  locations: Array<{
    node_id: number;
    floor: string;
    symbol: string;
    order_width: number;
    order_height: number;
  }>;
}

// ===== 페이지네이션 =====

interface PaginationMeta {
  currentPage: number;
  lastPage: number;
  perPage: number;
  total: number;
}

// ===== 상태 변환 =====

function mapApiStatus(status: ProductInspectionApi['status']): InspectionStatus {
  switch (status) {
    case 'reception':
      return '접수';
    case 'in_progress':
      return '진행중';
    case 'completed':
      return '완료';
    default:
      return '접수';
  }
}

function mapFrontendStatus(status: InspectionStatus): string {
  switch (status) {
    case '접수':
      return 'reception';
    case '진행중':
      return 'in_progress';
    case '완료':
      return 'completed';
    default:
      return 'reception';
  }
}

// ===== API → Frontend 변환 =====

function transformApiToFrontend(api: ProductInspectionApi): ProductInspection {
  return {
    id: String(api.id),
    qualityDocNumber: api.quality_doc_number,
    siteName: api.site_name,
    client: api.client,
    clientId: api.client_id ?? undefined,
    locationCount: api.location_count,
    requiredInfo: api.required_info,
    inspectionPeriod: api.inspection_period,
    inspector: api.inspector,
    status: mapApiStatus(api.status),
    author: api.author,
    receptionDate: api.reception_date,
    manager: api.manager,
    managerContact: api.manager_contact,
    constructionSite: {
      siteName: api.construction_site?.site_name || '',
      landLocation: api.construction_site?.land_location || '',
      lotNumber: api.construction_site?.lot_number || '',
    },
    materialDistributor: {
      companyName: api.material_distributor?.company_name || '',
      companyAddress: api.material_distributor?.company_address || '',
      representativeName: api.material_distributor?.representative_name || '',
      phone: api.material_distributor?.phone || '',
    },
    constructorInfo: {
      companyName: api.constructor_info?.company_name || '',
      companyAddress: api.constructor_info?.company_address || '',
      name: api.constructor_info?.name || '',
      phone: api.constructor_info?.phone || '',
    },
    supervisor: {
      officeName: api.supervisor?.office_name || '',
      officeAddress: api.supervisor?.office_address || '',
      name: api.supervisor?.name || '',
      phone: api.supervisor?.phone || '',
    },
    scheduleInfo: {
      visitRequestDate: api.schedule_info?.visit_request_date || '',
      startDate: api.schedule_info?.start_date || '',
      endDate: api.schedule_info?.end_date || '',
      inspector: api.schedule_info?.inspector || '',
      sitePostalCode: api.schedule_info?.site_postal_code || '',
      siteAddress: api.schedule_info?.site_address || '',
      siteAddressDetail: api.schedule_info?.site_address_detail || '',
    },
    orderItems: (api.order_items || []).map((item) => ({
      id: item.id,
      orderId: item.order_id,
      orderNumber: item.order_number,
      siteName: item.site_name || '',
      clientId: item.client_id ?? null,
      clientName: item.client_name ?? '',
      itemId: item.item_id ?? null,
      itemName: item.item_name ?? '',
      deliveryDate: item.delivery_date || '',
      floor: item.floor,
      symbol: item.symbol,
      orderWidth: item.order_width,
      orderHeight: item.order_height,
      constructionWidth: item.construction_width,
      constructionHeight: item.construction_height,
      changeReason: item.change_reason,
      documentId: item.document_id ?? null,
      inspectionData: item.inspection_data ? item.inspection_data as unknown as ProductInspectionData : undefined,
    })),
    requestDocumentId: api.request_document_id ?? null,
  };
}

// ===== Frontend → API 변환 =====

function transformFormToApi(data: InspectionFormData): Record<string, unknown> {
  return {
    site_name: data.siteName,
    client_id: data.clientId ?? null,
    inspector_id: data.inspectorId ?? null,
    received_date: data.receptionDate ?? null,
    options: {
      manager: {
        name: data.manager || '',
        phone: data.managerContact || '',
      },
      inspection: {
        request_date: data.scheduleInfo?.visitRequestDate || '',
        start_date: data.scheduleInfo?.startDate || '',
        end_date: data.scheduleInfo?.endDate || '',
      },
      site_address: {
        postal_code: data.scheduleInfo?.sitePostalCode || '',
        address: data.scheduleInfo?.siteAddress || '',
        detail: data.scheduleInfo?.siteAddressDetail || '',
      },
      construction_site: {
        name: data.constructionSite?.siteName || '',
        land_location: data.constructionSite?.landLocation || '',
        lot_number: data.constructionSite?.lotNumber || '',
      },
      material_distributor: {
        company: data.materialDistributor?.companyName || '',
        address: data.materialDistributor?.companyAddress || '',
        ceo: data.materialDistributor?.representativeName || '',
        phone: data.materialDistributor?.phone || '',
      },
      contractor: {
        company: data.constructorInfo?.companyName || '',
        address: data.constructorInfo?.companyAddress || '',
        name: data.constructorInfo?.name || '',
        phone: data.constructorInfo?.phone || '',
      },
      supervisor: {
        office: data.supervisor?.officeName || '',
        address: data.supervisor?.officeAddress || '',
        name: data.supervisor?.name || '',
        phone: data.supervisor?.phone || '',
      },
    },
    // 수주 연결
    order_ids: data.orderItems?.map((item) => item.orderId ?? Number(item.id)) ?? [],
  };
}

// ===== 제품검사 목록 조회 =====

export async function getInspections(params?: {
  page?: number;
  size?: number;
  q?: string;
  status?: InspectionStatus | '전체';
  dateFrom?: string;
  dateTo?: string;
}): Promise<{
  success: boolean;
  data: ProductInspection[];
  pagination: PaginationMeta;
  error?: string;
  __authError?: boolean;
}> {
  const defaultPagination = { currentPage: 1, lastPage: 1, perPage: 20, total: 0 };

  const result = await executeServerAction<PaginatedResponse>({
    url: buildApiUrl('/api/v1/quality/documents', {
      page: params?.page,
      per_page: params?.size,
      q: params?.q,
      status: params?.status && params.status !== '전체' ? mapFrontendStatus(params.status) : undefined,
      date_from: params?.dateFrom,
      date_to: params?.dateTo,
    }),
    errorMessage: '제품검사 목록 조회에 실패했습니다.',
  });

  if (!result.success) {
    if (USE_MOCK_FALLBACK) {
      let filtered = [...mockInspections];
      if (params?.status && params.status !== '전체') {
        filtered = filtered.filter(i => i.status === params.status);
      }
      if (params?.q) {
        const q = params.q.toLowerCase();
        filtered = filtered.filter(i =>
          i.siteName.toLowerCase().includes(q) ||
          i.client.toLowerCase().includes(q) ||
          i.qualityDocNumber.toLowerCase().includes(q) ||
          i.inspector.toLowerCase().includes(q)
        );
      }
      const page = params?.page || 1;
      const size = params?.size || 20;
      const start = (page - 1) * size;
      return {
        success: true,
        data: filtered.slice(start, start + size),
        pagination: { currentPage: page, lastPage: Math.ceil(filtered.length / size), perPage: size, total: filtered.length },
      };
    }
    return { success: false, data: [], pagination: defaultPagination, error: result.error, __authError: result.__authError };
  }

  const d = result.data || { items: [], current_page: 1, last_page: 1, per_page: 20, total: 0 };
  return {
    success: true,
    data: d.items.map(transformApiToFrontend),
    pagination: {
      currentPage: d.current_page,
      lastPage: d.last_page,
      perPage: d.per_page,
      total: d.total,
    },
  };
}

// ===== 통계 조회 =====

export async function getInspectionStats(params?: {
  dateFrom?: string;
  dateTo?: string;
}): Promise<{
  success: boolean;
  data?: InspectionStats;
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction<InspectionStatsApi>({
    url: buildApiUrl('/api/v1/quality/documents/stats', {
      date_from: params?.dateFrom,
      date_to: params?.dateTo,
    }),
    errorMessage: '제품검사 통계 조회에 실패했습니다.',
  });

  if (!result.success) {
    if (USE_MOCK_FALLBACK) return { success: true, data: mockStats };
    return { success: false, error: result.error, __authError: result.__authError };
  }

  const s = result.data;
  return {
    success: true,
    data: s ? {
      receptionCount: s.reception_count,
      inProgressCount: s.in_progress_count,
      completedCount: s.completed_count,
    } : undefined,
  };
}

// ===== 캘린더 스케줄 조회 =====

export async function getInspectionCalendar(params?: {
  year?: number;
  month?: number;
  inspector?: string;
  status?: InspectionStatus | '전체';
}): Promise<{
  success: boolean;
  data: InspectionCalendarItem[];
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction<CalendarItemApi[]>({
    url: buildApiUrl('/api/v1/quality/documents/calendar', {
      year: params?.year,
      month: params?.month,
      inspector: params?.inspector,
      status: params?.status && params.status !== '전체' ? mapFrontendStatus(params.status) : undefined,
    }),
    errorMessage: '캘린더 스케줄 조회에 실패했습니다.',
  });

  if (!result.success) {
    if (USE_MOCK_FALLBACK) return { success: true, data: mockCalendarItems };
    return { success: false, data: [], error: result.error, __authError: result.__authError };
  }

  const items = result.data || [];
  return {
    success: true,
    data: items.map((item) => ({
      id: String(item.id),
      startDate: item.start_date,
      endDate: item.end_date,
      inspector: item.inspector,
      siteName: item.site_name,
      status: mapApiStatus(item.status as ProductInspectionApi['status']),
    })),
  };
}

// ===== 상세 조회 =====

export async function getInspectionById(id: string): Promise<{
  success: boolean;
  data?: ProductInspection;
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction<ProductInspectionApi>({
    url: buildApiUrl(`/api/v1/quality/documents/${id}`),
    errorMessage: '제품검사 상세 조회에 실패했습니다.',
  });

  if (!result.success) {
    if (USE_MOCK_FALLBACK) {
      const mockItem = mockInspections.find(i => i.id === id);
      if (mockItem) return { success: true, data: mockItem };
      return { success: false, error: '해당 데이터를 찾을 수 없습니다.' };
    }
    return { success: false, error: result.error, __authError: result.__authError };
  }

  return result.data
    ? { success: true, data: transformApiToFrontend(result.data) }
    : { success: false, error: '상세 조회 실패' };
}

// ===== 등록 =====

export async function createInspection(data: InspectionFormData): Promise<{
  success: boolean;
  data?: ProductInspection;
  error?: string;
  __authError?: boolean;
}> {
  const apiData = transformFormToApi(data);
  const result = await executeServerAction<ProductInspectionApi>({
    url: buildApiUrl('/api/v1/quality/documents'),
    method: 'POST',
    body: apiData,
    errorMessage: '제품검사 등록에 실패했습니다.',
  });

  if (!result.success) return { success: false, error: result.error, __authError: result.__authError };
  return result.data
    ? { success: true, data: transformApiToFrontend(result.data) }
    : { success: true };
}

// ===== 수정 =====

export async function updateInspection(
  id: string,
  data: Partial<InspectionFormData>
): Promise<{
  success: boolean;
  data?: ProductInspection;
  error?: string;
  __authError?: boolean;
}> {
  const apiData: Record<string, unknown> = {};

  if (data.siteName !== undefined) apiData.site_name = data.siteName;
  if (data.clientId !== undefined) apiData.client_id = data.clientId;
  if (data.inspectorId !== undefined) apiData.inspector_id = data.inspectorId;
  if (data.receptionDate !== undefined) apiData.received_date = data.receptionDate;

  // options 필드들은 백엔드에서 array_replace_recursive로 병합됨
  const options: Record<string, unknown> = {};

  if (data.manager !== undefined || data.managerContact !== undefined) {
    options.manager = {
      name: data.manager || '',
      phone: data.managerContact || '',
    };
  }
  if (data.scheduleInfo) {
    options.inspection = {
      request_date: data.scheduleInfo.visitRequestDate || '',
      start_date: data.scheduleInfo.startDate || '',
      end_date: data.scheduleInfo.endDate || '',
    };
    options.site_address = {
      postal_code: data.scheduleInfo.sitePostalCode || '',
      address: data.scheduleInfo.siteAddress || '',
      detail: data.scheduleInfo.siteAddressDetail || '',
    };
  }
  if (data.constructionSite) {
    options.construction_site = {
      name: data.constructionSite.siteName || '',
      land_location: data.constructionSite.landLocation || '',
      lot_number: data.constructionSite.lotNumber || '',
    };
  }
  if (data.materialDistributor) {
    options.material_distributor = {
      company: data.materialDistributor.companyName || '',
      address: data.materialDistributor.companyAddress || '',
      ceo: data.materialDistributor.representativeName || '',
      phone: data.materialDistributor.phone || '',
    };
  }
  if (data.constructorInfo) {
    options.contractor = {
      company: data.constructorInfo.companyName || '',
      address: data.constructorInfo.companyAddress || '',
      name: data.constructorInfo.name || '',
      phone: data.constructorInfo.phone || '',
    };
  }
  if (data.supervisor) {
    options.supervisor = {
      office: data.supervisor.officeName || '',
      address: data.supervisor.officeAddress || '',
      name: data.supervisor.name || '',
      phone: data.supervisor.phone || '',
    };
  }

  if (Object.keys(options).length > 0) {
    apiData.options = options;
  }

  // 수주 연결 동기화 (orderItems에서 orderId 추출)
  if (data.orderItems !== undefined) {
    apiData.order_ids = data.orderItems.map((item) => {
      // orderId가 있으면 사용, 없으면 id를 숫자로 변환
      return item.orderId ?? Number(item.id);
    });

    // 개소별 데이터 (시공규격, 변경사유, 검사데이터)
    // 새로 추가된 항목(id가 "orderId-nodeId" 형태)은 order_ids 동기화로 생성되므로 제외
    apiData.locations = data.orderItems
      .filter((item) => !String(item.id).includes('-') && !isNaN(Number(item.id)))
      .map((item) => ({
        id: Number(item.id),
        post_width: item.constructionWidth || null,
        post_height: item.constructionHeight || null,
        change_reason: item.changeReason || null,
        inspection_data: item.inspectionData || null,
      }));
  }

  const result = await executeServerAction<ProductInspectionApi>({
    url: buildApiUrl(`/api/v1/quality/documents/${id}`),
    method: 'PUT',
    body: apiData,
    errorMessage: '제품검사 수정에 실패했습니다.',
  });

  if (!result.success) return { success: false, error: result.error, __authError: result.__authError };
  return result.data
    ? { success: true, data: transformApiToFrontend(result.data) }
    : { success: true };
}

// ===== 개소별 검사 저장 =====

export async function saveLocationInspection(
  docId: string,
  locationId: string,
  inspectionData: ProductInspectionData,
  constructionInfo?: {
    width: number | null;
    height: number | null;
    changeReason: string;
  },
): Promise<{
  success: boolean;
  error?: string;
  __authError?: boolean;
}> {
  const body: Record<string, unknown> = {
    inspection_data: inspectionData,
    inspection_status: 'completed',
  };
  if (constructionInfo) {
    body.construction_width = constructionInfo.width;
    body.construction_height = constructionInfo.height;
    body.change_reason = constructionInfo.changeReason;
  }

  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/quality/documents/${docId}/locations/${locationId}/inspect`),
    method: 'POST',
    body,
    errorMessage: '검사 데이터 저장에 실패했습니다.',
  });

  return { success: result.success, error: result.error, __authError: result.__authError };
}

// ===== 삭제 =====

export async function deleteInspection(id: string): Promise<{
  success: boolean;
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/quality/documents/${id}`),
    method: 'DELETE',
    errorMessage: '제품검사 삭제에 실패했습니다.',
  });

  return { success: result.success, error: result.error, __authError: result.__authError };
}

// ===== 검사 완료 처리 =====

export async function completeInspection(
  id: string,
): Promise<{
  success: boolean;
  data?: ProductInspection;
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction<ProductInspectionApi>({
    url: buildApiUrl(`/api/v1/quality/documents/${id}/complete`),
    method: 'PATCH',
    errorMessage: '검사 완료 처리에 실패했습니다.',
  });

  if (!result.success) return { success: false, error: result.error, __authError: result.__authError };
  return result.data
    ? { success: true, data: transformApiToFrontend(result.data) }
    : { success: true };
}

// ===== 수주 선택 목록 조회 =====

export async function getOrderSelectList(params?: {
  q?: string;
  clientId?: number | null;
  itemId?: number | null;
}): Promise<{
  success: boolean;
  data: OrderSelectItem[];
  error?: string;
  __authError?: boolean;
}> {
  const result = await executeServerAction<OrderSelectItemApi[]>({
    url: buildApiUrl('/api/v1/quality/documents/available-orders', {
      q: params?.q,
      client_id: params?.clientId ?? undefined,
      item_id: params?.itemId ?? undefined,
    }),
    errorMessage: '수주 선택 목록 조회에 실패했습니다.',
  });

  if (!result.success) {
    if (USE_MOCK_FALLBACK) {
      let filtered = [...mockOrderSelectItems];
      if (params?.q) {
        const q = params.q.toLowerCase();
        filtered = filtered.filter(i =>
          i.orderNumber.toLowerCase().includes(q) || i.siteName.toLowerCase().includes(q)
        );
      }
      if (params?.clientId) {
        filtered = filtered.filter(i => i.clientId === params.clientId);
      }
      if (params?.itemId) {
        filtered = filtered.filter(i => i.itemId === params.itemId);
      }
      return { success: true, data: filtered };
    }
    return { success: false, data: [], error: result.error, __authError: result.__authError };
  }

  const items = result.data || [];
  return {
    success: true,
    data: items.map((item) => ({
      id: String(item.id),
      orderNumber: item.order_number,
      siteName: item.site_name,
      clientId: item.client_id ?? null,
      clientName: item.client_name ?? '',
      itemId: item.item_id ?? null,
      itemName: item.item_name ?? '',
      deliveryDate: item.delivery_date,
      locationCount: item.location_count,
      locations: (item.locations || []).map((loc) => ({
        nodeId: loc.node_id,
        floor: loc.floor,
        symbol: loc.symbol,
        orderWidth: loc.order_width,
        orderHeight: loc.order_height,
      })),
    })),
  };
}
