/**
 * 품목유형별 Zod 검증 스키마
 *
 * FG(제품), PT(부품), SM/RM(원자재/부자재), CS(소모품) 스키마 정의
 */

import { z } from 'zod';
import {
  itemNameSchema,
  itemTypeSchema,
  dateSchema,
  bomLineSchema,
  bendingDetailSchema,
} from './common';

// ===== 품목 마스터 기본 스키마 =====

/**
 * 품목 마스터 공통 필드
 */
export const itemMasterBaseSchema = z.object({
  // 공통 필수 필드
  itemCode: z.string().optional(), // 자동생성되므로 선택 사항
  itemName: itemNameSchema,
  itemType: itemTypeSchema,
  unit: z.string().max(20).optional(), // 선택 사항으로 변경

  // 공통 선택 필드
  specification: z.string().max(500).optional(),
  isActive: z.boolean().default(true),

  // 분류
  category1: z.string().max(100).optional(),
  category2: z.string().max(100).optional(),
  category3: z.string().max(100).optional(),

  // 가격 정보 - 모두 선택 사항
  purchasePrice: z.number().optional(),
  salesPrice: z.number().optional(),
  marginRate: z.number().min(0).max(100).optional(),
  processingCost: z.number().optional(),
  laborCost: z.number().optional(),
  installCost: z.number().optional(),

  // BOM
  bom: z.array(bomLineSchema).optional(),
  bomCategories: z.array(z.string()).optional(),

  // 메타데이터
  safetyStock: z.number().int().nonnegative().optional(),
  leadTime: z.number().int().nonnegative().optional(),
  isVariableSize: z.boolean().optional(),

  // 버전 관리
  currentRevision: z.number().int().nonnegative().default(0),
  isFinal: z.boolean().default(false),
  finalizedDate: dateSchema,
  finalizedBy: z.string().optional(),

  // 시스템 필드
  createdAt: z.string().optional(),
  updatedAt: z.string().optional(),
});

// ===== 제품(FG) 스키마 =====

/**
 * 제품 전용 필드
 */
const productFieldsSchema = z.object({
  productName: z.preprocess(
    (val) => val === undefined || val === null ? "" : val,
    z.string().min(1, '상품명을 입력해주세요').max(200, '상품명은 200자 이내로 입력해주세요')
  ),
  productCategory: z.enum(['SCREEN', 'STEEL']).optional(),
  lotAbbreviation: z.string().max(10).optional(),
  note: z.string().max(1000).optional(),

  // 인정 정보
  certificationNumber: z.string().max(100).optional(),
  certificationStartDate: dateSchema,
  certificationEndDate: dateSchema,
  specificationFile: z.string().optional(),
  specificationFileName: z.string().optional(),
  certificationFile: z.string().optional(),
  certificationFileName: z.string().optional(),
});

/**
 * 제품(FG) 전체 스키마 (refinement 없이)
 * 제품에는 가격 정보가 없으므로 제거
 */
export const productSchemaBase = itemMasterBaseSchema
  .omit({
    purchasePrice: true,
    salesPrice: true,
    processingCost: true,
    laborCost: true,
    installCost: true,
  })
  .merge(productFieldsSchema);

/**
 * 제품(FG) 전체 스키마 (refinement 포함)
 */
export const productSchema = productSchemaBase.refine(
  (data) => {
    // 인정 정보 검증: 시작일과 종료일이 모두 있거나 모두 없어야 함
    if (data.certificationStartDate && data.certificationEndDate) {
      return new Date(data.certificationStartDate) <= new Date(data.certificationEndDate);
    }
    return true;
  },
  {
    message: '인정 유효기간 종료일은 시작일보다 이후여야 합니다',
    path: ['certificationEndDate'],
  }
);

// ===== 부품(PT) 스키마 =====

/**
 * 부품 전용 필드
 */
const partFieldsSchema = z.object({
  partType: z.preprocess(
    (val) => val === undefined || val === null ? "" : val,
    z.string()
      .min(1, '부품 유형을 선택해주세요')
      .refine(
        (val) => ['ASSEMBLY', 'BENDING', 'PURCHASED'].includes(val),
        { message: '부품 유형을 선택해주세요' }
      )
  ),
  partUsage: z.enum(['GUIDE_RAIL', 'BOTTOM_FINISH', 'CASE', 'DOOR', 'BRACKET', 'GENERAL']).optional(),

  // 조립 부품
  installationType: z.string().max(50).optional(),
  assemblyType: z.string().max(50).optional(),
  sideSpecWidth: z.string().max(50).optional(),
  sideSpecHeight: z.string().max(50).optional(),
  assemblyLength: z.string().max(50).optional(),

  // 가이드레일
  guideRailModelType: z.string().max(100).optional(),
  guideRailModel: z.string().max(100).optional(),

  // 절곡품
  bendingDiagram: z.string().url().optional(),
  bendingDetails: z.array(bendingDetailSchema).optional(),
  material: z.string().max(100).optional(),
  length: z.string().max(50).optional(),
  bendingLength: z.string().max(50).optional(),

  // 구매 부품
  electricOpenerPower: z.string().max(50).optional(),
  electricOpenerCapacity: z.string().max(50).optional(),
  motorVoltage: z.string().max(50).optional(),
  motorCapacity: z.string().max(50).optional(),
  chainSpec: z.string().max(100).optional(),

  // 인정 정보 (부품도 인정 가능)
  certificationNumber: z.string().max(100).optional(),
  certificationStartDate: dateSchema,
  certificationEndDate: dateSchema,
  specificationFile: z.string().optional(),
  specificationFileName: z.string().optional(),
  certificationFile: z.string().optional(),
  certificationFileName: z.string().optional(),
});

/**
 * 부품(PT) 전체 스키마 (refinement 없이)
 * 부품은 itemName을 사용하지 않으므로 선택 사항으로 변경
 */
export const partSchemaBase = itemMasterBaseSchema
  .extend({
    itemName: z.string().max(200).optional(), // 부품은 itemName 선택 사항
  })
  .merge(partFieldsSchema);

/**
 * 부품(PT) 전체 스키마 (refinement 포함)
 */
export const partSchema = partSchemaBase
  .superRefine((data, ctx) => {
    // 1단계: 부품 유형 필수
    if (!data.partType || data.partType === '') {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: '부품 유형을 선택해주세요',
        path: ['partType'],
      });
      return; // 부품 유형이 없으면 더 이상 검증하지 않음
    }

    // 2단계: 부품 유형이 있을 때만 품목명 필수
    if (!data.category1 || data.category1 === '') {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: '품목명을 선택해주세요',
        path: ['category1'],
      });
    }

    // 3단계: 조립 부품 전용 필드
    if (data.partType === 'ASSEMBLY') {
      if (!data.installationType) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '설치 유형을 선택해주세요',
          path: ['installationType'],
        });
      }
      if (!data.sideSpecWidth) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '측면 규격 (가로)를 입력해주세요',
          path: ['sideSpecWidth'],
        });
      }
      if (!data.sideSpecHeight) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '측면 규격 (세로)를 입력해주세요',
          path: ['sideSpecHeight'],
        });
      }
      if (!data.assemblyLength) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '길이를 선택해주세요',
          path: ['assemblyLength'],
        });
      }
    }

    // 절곡품 전용 필드
    if (data.partType === 'BENDING') {
      if (!data.material) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '재질을 선택해주세요',
          path: ['material'],
        });
      }
      if (!data.length) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '폭 합계를 입력해주세요',
          path: ['length'],
        });
      }
      if (!data.bendingLength) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '모양&길이를 선택해주세요',
          path: ['bendingLength'],
        });
      }
    }

    // 구매 부품 전용 필드
    if (data.partType === 'PURCHASED') {
      if (data.category1 === 'electric_opener') {
        if (!data.electricOpenerPower) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: '전원을 선택해주세요',
            path: ['electricOpenerPower'],
          });
        }
        if (!data.electricOpenerCapacity) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: '용량을 선택해주세요',
            path: ['electricOpenerCapacity'],
          });
        }
      }
      if (data.category1 === 'motor' && !data.motorVoltage) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '전압을 선택해주세요',
          path: ['motorVoltage'],
        });
      }
      if (data.category1 === 'chain' && !data.chainSpec) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: '체인 규격을 선택해주세요',
          path: ['chainSpec'],
        });
      }
    }
  });

// ===== 원자재/부자재(RM/SM) 스키마 =====

/**
 * 원자재/부자재 전용 필드
 *
 * 현재 사용하지 않음 (materialSchemaBase에 직접 포함됨)
 */
const _materialFieldsSchema = z.object({
  material: z.string().max(100).optional(),
  length: z.string().max(50).optional(),
});

/**
 * 원자재/부자재 규격 필수 필드 스키마
 */
const materialSpecificationSchema = z.preprocess(
  (val) => val === undefined || val === null ? "" : val,
  z.string().min(1, '규격을 입력해주세요').max(500, '최대 500자')
);

/**
 * 원자재/부자재 단위 필수 필드 스키마
 */
const materialUnitSchema = z.preprocess(
  (val) => val === undefined || val === null ? "" : val,
  z.string().min(1, '단위를 입력해주세요').max(20, '최대 20자')
);

/**
 * 원자재/부자재 Base 스키마 (refinement 없음, 필드만 정의)
 * specification, unit을 필수로 정의 (z.object로 완전히 새로 정의)
 */
export const materialSchemaBase = z.object({
  // 공통 필수 필드
  itemCode: z.string().optional(),
  itemName: itemNameSchema,
  itemType: itemTypeSchema,
  specification: materialSpecificationSchema, // 필수!
  unit: materialUnitSchema, // 필수!
  isActive: z.boolean().default(true),

  // 분류
  category1: z.string().max(100).optional(),
  category2: z.string().max(100).optional(),
  category3: z.string().max(100).optional(),

  // 가격 정보
  purchasePrice: z.number().optional(),
  salesPrice: z.number().optional(),
  marginRate: z.number().min(0).max(100).optional(),
  processingCost: z.number().optional(),
  laborCost: z.number().optional(),
  installCost: z.number().optional(),

  // BOM
  bom: z.array(bomLineSchema).optional(),
  bomCategories: z.array(z.string()).optional(),

  // 메타데이터
  safetyStock: z.number().int().nonnegative().optional(),
  leadTime: z.number().int().nonnegative().optional(),
  isVariableSize: z.boolean().optional(),

  // 버전 관리
  currentRevision: z.number().int().nonnegative().default(0),
  isFinal: z.boolean().default(false),
  finalizedDate: dateSchema,
  finalizedBy: z.string().optional(),

  // 시스템 필드
  createdAt: z.string().optional(),
  updatedAt: z.string().optional(),

  // 원자재/부자재 전용 필드
  material: z.string().max(100).optional(),
  length: z.string().max(50).optional(),
});

/**
 * 원자재/부자재 전체 스키마 (export용)
 */
export const materialSchema = materialSchemaBase;

// ===== 소모품(CS) 스키마 =====

/**
 * 소모품 Base 스키마
 * specification, unit을 필수로 오버라이드
 */
export const consumableSchemaBase = itemMasterBaseSchema
  .extend({
    specification: materialSpecificationSchema, // optional → 필수로 변경
    unit: materialUnitSchema, // optional → 필수로 변경
  });

/**
 * 소모품 전체 스키마 (export용)
 */
export const consumableSchema = consumableSchemaBase;

// ===== 통합 품목 스키마 =====

/**
 * 품목 유형에 따른 동적 검증
 *
 * Zod 4.x에서는 refinement가 있는 스키마를 extend할 수 없으므로,
 * refinement가 없는 base 스키마를 사용합니다.
 */
export const itemMasterSchema = z.discriminatedUnion('itemType', [
  productSchemaBase.extend({ itemType: z.literal('FG') }),
  partSchemaBase.extend({ itemType: z.literal('PT') }),
  materialSchema.extend({ itemType: z.literal('SM') }),
  materialSchema.extend({ itemType: z.literal('RM') }),
  consumableSchema.extend({ itemType: z.literal('CS') }),
]);
