import * as XLSX from 'xlsx';
import ExcelJS from 'exceljs';
import { ASSET_SCHEMA } from './schema';
import { LOCATION_DATA, CORP_LIST, ORG_LIST, HW_TYPE_LIST } from '../components/Modal/SharedData';

export interface HardwareAsset {
  [key: string]: any;
  id: string;
  type: string;
  법인: string;
  자산코드: string;
  사용자: string;
  명칭: string;
  위치: string;
  상세위치: string;
  관리자: string;
  IP주소: string;
  MACaddress: string;
  HW사양: string;
  OS: string;
  금액?: string;
  납품업체: string;
  품의서명: string;
  비고?: string;
}

export interface SoftwareAsset {
  [key: string]: any;
  id: string;
  type: string;
  분야?: string;
  법인: string;
  부서?: string;
  제품명: string;
  금액: string;
  수량: number;
  계정명: string;
  납품업체: string;
  비고: string;
}

export interface SWUser {
  id: string;
  sw_id: string;
  법인: string;
  부서: string;
  팀: string;
  직위: string;
  이름: string;
  사용기간: string;
  신청서명: string;
  userData?: any[]; 
}

export interface HardwareLog {
  id: string;
  assetId: string;
  date: string;
  details: string;
  user: string;
  cost?: number;
}

export interface MasterAssetData {
  pc: HardwareAsset[];
  server: HardwareAsset[];
  storage: HardwareAsset[];
  equip: HardwareAsset[];
  mobile: HardwareAsset[];
  subSw: SoftwareAsset[];
  permSw: SoftwareAsset[];
  cloud: SoftwareAsset[];
  domain?: any[];
  hw: HardwareAsset[];
  sw: SoftwareAsset[];
  swUsers: SWUser[];
  logs: HardwareLog[];
}

const PC_HEADERS = [
  ASSET_SCHEMA.CORP.ui, ASSET_SCHEMA.ASSET_CODE.ui, ASSET_SCHEMA.USER.ui, ASSET_SCHEMA.ORG.ui, 
  ASSET_SCHEMA.MAINBOARD.ui, ASSET_SCHEMA.OS.ui, ASSET_SCHEMA.CPU.ui, 'GPU', ASSET_SCHEMA.RAM.ui, 
  ASSET_SCHEMA.STORAGE1.ui, ASSET_SCHEMA.STORAGE2.ui, ASSET_SCHEMA.STORAGE3.ui, 
  ASSET_SCHEMA.IP_ADDR.ui, ASSET_SCHEMA.MANAGER_MAIN.ui, ASSET_SCHEMA.MANAGER_SUB.ui,
  ASSET_SCHEMA.PURCHASE_YM.ui, ASSET_SCHEMA.PRICE.ui, ASSET_SCHEMA.VENDOR.ui, ASSET_SCHEMA.DOC_NAME.ui, ASSET_SCHEMA.REMARKS.ui
];

const BASE_HW_HEADERS = [
  ASSET_SCHEMA.CORP.ui, '유형', ASSET_SCHEMA.ASSET_CODE.ui, ASSET_SCHEMA.PURCHASE_YM.ui, 
  ASSET_SCHEMA.ORG.ui, ASSET_SCHEMA.LOCATION.ui, ASSET_SCHEMA.DETAIL_LOCATION.ui,
  ASSET_SCHEMA.PURPOSE.ui, ASSET_SCHEMA.DETAILS.ui, // 용도, 상세 추가
  ASSET_SCHEMA.MANAGER_MAIN.ui, ASSET_SCHEMA.MANAGER_SUB.ui, 
  ASSET_SCHEMA.MODEL.ui, ASSET_SCHEMA.OS.ui, ASSET_SCHEMA.CPU.ui, ASSET_SCHEMA.RAM.ui, 'GPU',
  ASSET_SCHEMA.STORAGE1.ui, ASSET_SCHEMA.STORAGE2.ui, ASSET_SCHEMA.STORAGE3.ui, 
  ASSET_SCHEMA.IP_ADDR.ui, ASSET_SCHEMA.IP_ADDR2.ui, '원격도구', '서버ID', '서버PW', ASSET_SCHEMA.MONITORING.ui, ASSET_SCHEMA.REMARKS.ui
];

const SERVER_HEADERS = [...BASE_HW_HEADERS];
const STORAGE_HEADERS = [...BASE_HW_HEADERS];

// 1. 전산비품/모바일기기: 현 사용조직 추가
const EQUIP_HEADERS = [
  ASSET_SCHEMA.CORP.ui, '유형', ASSET_SCHEMA.ASSET_CODE.ui, ASSET_SCHEMA.MODEL.ui,
  ASSET_SCHEMA.ORG.ui, // 현 사용조직 추가
  ASSET_SCHEMA.STORE_LOC.ui, ASSET_SCHEMA.DETAIL_LOCATION.ui, 
  ASSET_SCHEMA.MANAGER_MAIN.ui, ASSET_SCHEMA.MANAGER_SUB.ui,
  ASSET_SCHEMA.PURCHASE_YM.ui, ASSET_SCHEMA.PRICE.ui, ASSET_SCHEMA.REMARKS.ui
];
const MOBILE_HEADERS = [...EQUIP_HEADERS];

const SUB_SW_HEADERS = ['분야', ASSET_SCHEMA.CORP.ui, ASSET_SCHEMA.PRODUCT.ui, '부서', ASSET_SCHEMA.QTY.ui, ASSET_SCHEMA.PRICE.ui, ASSET_SCHEMA.PURCHASE_YM.ui, '시작일', ASSET_SCHEMA.EXPIRY.ui, ASSET_SCHEMA.VENDOR.ui, ASSET_SCHEMA.REMARKS.ui];
const PERM_SW_HEADERS = ['분야', ASSET_SCHEMA.CORP.ui, ASSET_SCHEMA.PRODUCT.ui, '부서', ASSET_SCHEMA.QTY.ui, ASSET_SCHEMA.PRICE.ui, ASSET_SCHEMA.PURCHASE_YM.ui, '시작일', ASSET_SCHEMA.LICENSE_KEY.ui, ASSET_SCHEMA.VENDOR.ui, ASSET_SCHEMA.REMARKS.ui];

const CLOUD_HEADERS = [ASSET_SCHEMA.PLATFORM.ui, ASSET_SCHEMA.CORP.ui, ASSET_SCHEMA.PRODUCT.ui, '부서', ASSET_SCHEMA.ACCOUNT.ui, ASSET_SCHEMA.PAY_METHOD.ui, ASSET_SCHEMA.PAY_DAY.ui, ASSET_SCHEMA.CARD_NUM.ui, ASSET_SCHEMA.BILLING.ui, ASSET_SCHEMA.REMARKS.ui];
const DOMAIN_HEADERS = ['유형', ASSET_SCHEMA.CORP.ui, '서비스명', '관리도메인', '시작일', '만료일', ASSET_SCHEMA.PRICE.ui, '담당자', '담당자(부)', ASSET_SCHEMA.REMARKS.ui];

/**
 * 엑셀 양식 다운로드
 */
export async function downloadTemplate() {
  const workbook = new ExcelJS.Workbook();
  const refSheet = workbook.addWorksheet('RefData');
  
  const buildings = Object.keys(LOCATION_DATA);
  const corps = CORP_LIST;
  const orgs = ORG_LIST;
  const typeLists = {
    server: ['서버', 'PC'],
    storage: ['스토리지', 'NAS', 'DAS'],
    equip: ['CPU', 'GPU', 'HDD'],
    mobile: ['태블릿', '모바일', '노트북']
  };

  refSheet.getColumn(1).values = ['CorpList', ...corps];
  refSheet.getColumn(2).values = ['OrgList', ...orgs];
  refSheet.getColumn(3).values = ['LocList', ...buildings];
  refSheet.getColumn(4).values = ['ServerTypes', ...typeLists.server];
  refSheet.getColumn(5).values = ['StorageTypes', ...typeLists.storage];
  refSheet.getColumn(6).values = ['EquipTypes', ...typeLists.equip];
  refSheet.getColumn(7).values = ['MobileTypes', ...typeLists.mobile];

  workbook.definedNames.add('RefData!$A$2:$A$' + (corps.length + 1), 'CorpList');
  workbook.definedNames.add('RefData!$B$2:$B$' + (orgs.length + 1), 'OrgList');
  workbook.definedNames.add('RefData!$C$2:$C$' + (buildings.length + 1), 'LocList');
  workbook.definedNames.add('RefData!$D$2:$D$' + (typeLists.server.length + 1), 'ServerTypes');
  workbook.definedNames.add('RefData!$E$2:$E$' + (typeLists.storage.length + 1), 'StorageTypes');
  workbook.definedNames.add('RefData!$F$2:$F$' + (typeLists.equip.length + 1), 'EquipTypes');
  workbook.definedNames.add('RefData!$G$2:$G$' + (typeLists.mobile.length + 1), 'MobileTypes');

  buildings.forEach((building, idx) => {
    const colIdx = 8 + idx;
    const subLocs = LOCATION_DATA[building];
    const column = refSheet.getColumn(colIdx);
    column.values = [building, ...subLocs];
    const safeName = building.replace(/\s/g, '_');
    workbook.definedNames.add(`RefData!$${column.letter}$2:$${column.letter}$${subLocs.length + 1}`, safeName);
  });

  const tabConfigs = [
    { name: '개인PC', headers: PC_HEADERS, typeRef: '' },
    { name: '서버', headers: SERVER_HEADERS, typeRef: 'ServerTypes' },
    { name: '스토리지', headers: STORAGE_HEADERS, typeRef: 'StorageTypes' },
    { name: '전산비품', headers: EQUIP_HEADERS, typeRef: 'EquipTypes' },
    { name: '모바일기기', headers: MOBILE_HEADERS, typeRef: 'MobileTypes' },
    { name: '구독SW', headers: SUB_SW_HEADERS, typeRef: '' },
    { name: '영구SW', headers: PERM_SW_HEADERS, typeRef: '' },
    { name: '클라우드', headers: CLOUD_HEADERS, typeRef: '' },
    { name: '도메인', headers: DOMAIN_HEADERS, typeRef: '' }
  ];

  tabConfigs.forEach(config => {
    const sheet = workbook.addWorksheet(config.name);
    sheet.getRow(1).values = config.headers;
    sheet.getRow(1).font = { bold: true };
    sheet.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE9EEED' } };

    const rowCount = 200; 
    const codeIdx = config.headers.indexOf(ASSET_SCHEMA.ASSET_CODE.ui) + 1;
    if (codeIdx > 0) sheet.getColumn(codeIdx).hidden = true;

    config.headers.forEach((header, hIdx) => {
      const colNum = hIdx + 1;
      const isFreeTextGroup = (config.name === '전산비품' || config.name === '모바일기기');

      for (let r = 2; r <= rowCount; r++) {
        const cell = sheet.getCell(r, colNum);
        if (header === ASSET_SCHEMA.CORP.ui) {
          cell.dataValidation = { type: 'list', allowBlank: true, formulae: ['CorpList'] };
        } else if (header === ASSET_SCHEMA.ORG.ui) {
          cell.dataValidation = { type: 'list', allowBlank: true, formulae: ['OrgList'] };
        } else if ((header === ASSET_SCHEMA.LOCATION.ui || header === ASSET_SCHEMA.STORE_LOC.ui) && !isFreeTextGroup) {
          cell.dataValidation = { type: 'list', allowBlank: true, formulae: ['LocList'] };
        } else if (header === ASSET_SCHEMA.DETAIL_LOCATION.ui && !isFreeTextGroup) {
          const parentColIdx = config.headers.indexOf(ASSET_SCHEMA.LOCATION.ui) + 1 || config.headers.indexOf(ASSET_SCHEMA.STORE_LOC.ui) + 1;
          if (parentColIdx > 0) {
            const parentLetter = sheet.getColumn(parentColIdx).letter;
            cell.dataValidation = { type: 'list', allowBlank: true, formulae: [`=INDIRECT(SUBSTITUTE(${parentLetter}${r}," ","_"))`] };
          }
        } else if (header === '유형' && config.typeRef) {
          cell.dataValidation = { type: 'list', allowBlank: true, formulae: [config.typeRef] };
        }
      }
    });
    sheet.columns.forEach(col => { col.width = col.hidden ? 0 : 18; });
  });

  refSheet.state = 'veryHidden';
  const buffer = await workbook.xlsx.writeBuffer();
  const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `ITAM_Standard_Template_${new Date().toISOString().split('T')[0]}.xlsx`;
  a.click();
  window.URL.revokeObjectURL(url);
}

export function exportToExcel(masterData: MasterAssetData) {
  const wb = XLSX.utils.book_new();
  const getVal = (obj: any, schemaItem: any) => obj[schemaItem.key] || '';
  const exportMap = [
    { 
      tab: '개인PC', list: masterData.pc, headers: PC_HEADERS, 
      map: (a: any) => [
        getVal(a, ASSET_SCHEMA.CORP), getVal(a, ASSET_SCHEMA.ASSET_CODE), getVal(a, ASSET_SCHEMA.USER), getVal(a, ASSET_SCHEMA.ORG),
        getVal(a, ASSET_SCHEMA.MAINBOARD), getVal(a, ASSET_SCHEMA.OS), getVal(a, ASSET_SCHEMA.CPU), a.GPU, getVal(a, ASSET_SCHEMA.RAM), 
        getVal(a, ASSET_SCHEMA.STORAGE1), getVal(a, ASSET_SCHEMA.STORAGE2), getVal(a, ASSET_SCHEMA.STORAGE3),
        getVal(a, ASSET_SCHEMA.IP_ADDR), getVal(a, ASSET_SCHEMA.MANAGER_MAIN), getVal(a, ASSET_SCHEMA.MANAGER_SUB),
        getVal(a, ASSET_SCHEMA.PURCHASE_YM), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.VENDOR), getVal(a, ASSET_SCHEMA.DOC_NAME), getVal(a, ASSET_SCHEMA.REMARKS)
      ] 
    },
    { 
      tab: '서버', list: masterData.server, headers: SERVER_HEADERS, 
      map: (a: any) => [
        getVal(a, ASSET_SCHEMA.CORP), a.type, getVal(a, ASSET_SCHEMA.ASSET_CODE), getVal(a, ASSET_SCHEMA.PURCHASE_YM), getVal(a, ASSET_SCHEMA.ORG),
        getVal(a, ASSET_SCHEMA.LOCATION), getVal(a, ASSET_SCHEMA.DETAIL_LOCATION), getVal(a, ASSET_SCHEMA.MANAGER_MAIN), getVal(a, ASSET_SCHEMA.MANAGER_SUB), getVal(a, ASSET_SCHEMA.MODEL), 
        getVal(a, ASSET_SCHEMA.OS), getVal(a, ASSET_SCHEMA.CPU), getVal(a, ASSET_SCHEMA.RAM), a.GPU, getVal(a, ASSET_SCHEMA.STORAGE1), 
        getVal(a, ASSET_SCHEMA.STORAGE2), getVal(a, ASSET_SCHEMA.STORAGE3), getVal(a, ASSET_SCHEMA.IP_ADDR), getVal(a, ASSET_SCHEMA.IP_ADDR2), 
        a.원격접속, a.서버ID, a.서버PW, getVal(a, ASSET_SCHEMA.MONITORING), getVal(a, ASSET_SCHEMA.REMARKS)
      ] 
    },
    { tab: '스토리지', list: masterData.storage, headers: STORAGE_HEADERS, map: (a: any) => [getVal(a, ASSET_SCHEMA.CORP), a.type, getVal(a, ASSET_SCHEMA.ASSET_CODE), getVal(a, ASSET_SCHEMA.ORG), getVal(a, ASSET_SCHEMA.LOCATION), getVal(a, ASSET_SCHEMA.DETAIL_LOCATION), getVal(a, ASSET_SCHEMA.MANAGER_MAIN), getVal(a, ASSET_SCHEMA.MANAGER_SUB), getVal(a, ASSET_SCHEMA.MODEL), a.용량, getVal(a, ASSET_SCHEMA.IP_ADDR), getVal(a, ASSET_SCHEMA.PURCHASE_YM), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '전산비품', list: masterData.equip, headers: EQUIP_HEADERS, map: (a: any) => [getVal(a, ASSET_SCHEMA.CORP), a.type, getVal(a, ASSET_SCHEMA.ASSET_CODE), getVal(a, ASSET_SCHEMA.MODEL), getVal(a, ASSET_SCHEMA.ORG), getVal(a, ASSET_SCHEMA.STORE_LOC), getVal(a, ASSET_SCHEMA.DETAIL_LOCATION), getVal(a, ASSET_SCHEMA.MANAGER_MAIN), getVal(a, ASSET_SCHEMA.MANAGER_SUB), getVal(a, ASSET_SCHEMA.PURCHASE_YM), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '모바일기기', list: masterData.mobile, headers: MOBILE_HEADERS, map: (a: any) => [getVal(a, ASSET_SCHEMA.CORP), a.type, getVal(a, ASSET_SCHEMA.ASSET_CODE), getVal(a, ASSET_SCHEMA.MODEL), getVal(a, ASSET_SCHEMA.ORG), getVal(a, ASSET_SCHEMA.STORE_LOC), getVal(a, ASSET_SCHEMA.DETAIL_LOCATION), getVal(a, ASSET_SCHEMA.MANAGER_MAIN), getVal(a, ASSET_SCHEMA.MANAGER_SUB), getVal(a, ASSET_SCHEMA.PURCHASE_YM), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '구독SW', list: masterData.subSw, headers: SUB_SW_HEADERS, map: (a: any) => [a.분야, getVal(a, ASSET_SCHEMA.CORP), getVal(a, ASSET_SCHEMA.PRODUCT), a.부서, getVal(a, ASSET_SCHEMA.QTY), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.PURCHASE_YM), a.시작일, getVal(a, ASSET_SCHEMA.EXPIRY), getVal(a, ASSET_SCHEMA.VENDOR), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '영구SW', list: masterData.permSw, headers: PERM_SW_HEADERS, map: (a: any) => [a.분야, getVal(a, ASSET_SCHEMA.CORP), getVal(a, ASSET_SCHEMA.PRODUCT), a.부서, getVal(a, ASSET_SCHEMA.QTY), getVal(a, ASSET_SCHEMA.PRICE), getVal(a, ASSET_SCHEMA.PURCHASE_YM), a.시작일, getVal(a, ASSET_SCHEMA.LICENSE_KEY), getVal(a, ASSET_SCHEMA.VENDOR), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '클라우드', list: masterData.cloud, headers: CLOUD_HEADERS, map: (a: any) => [getVal(a, ASSET_SCHEMA.PLATFORM), getVal(a, ASSET_SCHEMA.CORP), getVal(a, ASSET_SCHEMA.PRODUCT), a.부서, getVal(a, ASSET_SCHEMA.ACCOUNT), getVal(a, ASSET_SCHEMA.PAY_METHOD), getVal(a, ASSET_SCHEMA.PAY_DAY), getVal(a, ASSET_SCHEMA.CARD_NUM), getVal(a, ASSET_SCHEMA.BILLING), getVal(a, ASSET_SCHEMA.REMARKS)] },
    { tab: '도메인', list: masterData.domain || [], headers: DOMAIN_HEADERS, map: (a: any) => [a.type, a.corp, a.service_name, a.domain_name, a.start_date, a.expiry_date, a.price, a.manager_main, a.manager_sub, a.remarks] }
  ];
  exportMap.forEach(m => {
    const ws = XLSX.utils.aoa_to_sheet([m.headers, ...m.list.map(m.map)]);
    XLSX.utils.book_append_sheet(wb, ws, m.tab);
  });
  XLSX.writeFile(wb, `itam_master_${new Date().toISOString().split('T')[0]}.xlsx`);
}

export async function parseExcel(file: File): Promise<any> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const workbook = XLSX.read(e.target?.result, { type: 'binary' });
        const parsedData: any = {};
        workbook.SheetNames.forEach(sheetName => {
          if (sheetName === 'RefData') return;
          const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]) as any[];
          const list: any[] = [];
          rows.forEach(r => {
            const common = { id: Math.random().toString(36).substring(2, 9) };
            const mapVal = (schemaItem: any) => r[schemaItem.ui] || '';

            if (sheetName === '개인PC') {
              list.push({ 
                ...common, type: 'PC', 상세용도: '개인PC',
                [ASSET_SCHEMA.CORP.key]: mapVal(ASSET_SCHEMA.CORP),
                [ASSET_SCHEMA.ASSET_CODE.key]: mapVal(ASSET_SCHEMA.ASSET_CODE),
                [ASSET_SCHEMA.USER.key]: mapVal(ASSET_SCHEMA.USER),
                [ASSET_SCHEMA.ORG.key]: mapVal(ASSET_SCHEMA.ORG),
                [ASSET_SCHEMA.MAINBOARD.key]: mapVal(ASSET_SCHEMA.MAINBOARD),
                [ASSET_SCHEMA.OS.key]: mapVal(ASSET_SCHEMA.OS),
                [ASSET_SCHEMA.CPU.key]: mapVal(ASSET_SCHEMA.CPU),
                GPU: r['GPU'] || '',
                [ASSET_SCHEMA.RAM.key]: mapVal(ASSET_SCHEMA.RAM),
                [ASSET_SCHEMA.STORAGE1.key]: mapVal(ASSET_SCHEMA.STORAGE1),
                [ASSET_SCHEMA.STORAGE2.key]: mapVal(ASSET_SCHEMA.STORAGE2),
                [ASSET_SCHEMA.STORAGE3.key]: mapVal(ASSET_SCHEMA.STORAGE3),
                [ASSET_SCHEMA.IP_ADDR.key]: mapVal(ASSET_SCHEMA.IP_ADDR),
                [ASSET_SCHEMA.MANAGER_MAIN.key]: mapVal(ASSET_SCHEMA.MANAGER_MAIN),
                [ASSET_SCHEMA.MANAGER_SUB.key]: mapVal(ASSET_SCHEMA.MANAGER_SUB),
                [ASSET_SCHEMA.PURCHASE_YM.key]: mapVal(ASSET_SCHEMA.PURCHASE_YM),
                [ASSET_SCHEMA.PRICE.key]: mapVal(ASSET_SCHEMA.PRICE),
                [ASSET_SCHEMA.VENDOR.key]: mapVal(ASSET_SCHEMA.VENDOR),
                [ASSET_SCHEMA.DOC_NAME.key]: mapVal(ASSET_SCHEMA.DOC_NAME),
                [ASSET_SCHEMA.REMARKS.key]: mapVal(ASSET_SCHEMA.REMARKS)
              });
            } else if (['서버', '스토리지', '전산비품', '모바일기기'].includes(sheetName)) {
              const typeValue = r['유형'] || sheetName;
              list.push({ 
                ...common, 
                type: typeValue, 
                상세용도: sheetName === '서버' ? '서버' : typeValue,
                [ASSET_SCHEMA.CORP.key]: mapVal(ASSET_SCHEMA.CORP),
                [ASSET_SCHEMA.ASSET_CODE.key]: mapVal(ASSET_SCHEMA.ASSET_CODE),
                [ASSET_SCHEMA.PURCHASE_YM.key]: mapVal(ASSET_SCHEMA.PURCHASE_YM),
                [ASSET_SCHEMA.ORG.key]: mapVal(ASSET_SCHEMA.ORG),
                [ASSET_SCHEMA.LOCATION.key]: mapVal(ASSET_SCHEMA.LOCATION) || r[ASSET_SCHEMA.STORE_LOC.ui] || '',
                [ASSET_SCHEMA.DETAIL_LOCATION.key]: mapVal(ASSET_SCHEMA.DETAIL_LOCATION),
                [ASSET_SCHEMA.MANAGER_MAIN.key]: mapVal(ASSET_SCHEMA.MANAGER_MAIN),
                [ASSET_SCHEMA.MANAGER_SUB.key]: mapVal(ASSET_SCHEMA.MANAGER_SUB),
                [ASSET_SCHEMA.IP_ADDR.key]: mapVal(ASSET_SCHEMA.IP_ADDR),
                [ASSET_SCHEMA.IP_ADDR2.key]: mapVal(ASSET_SCHEMA.IP_ADDR2),
                원격접속: r['원격도구'] || '', 서버ID: r['서버ID'] || '', 서버PW: r['서버PW'] || '',
                [ASSET_SCHEMA.MODEL.key]: mapVal(ASSET_SCHEMA.MODEL),
                [ASSET_SCHEMA.OS.key]: mapVal(ASSET_SCHEMA.OS),
                [ASSET_SCHEMA.CPU.key]: mapVal(ASSET_SCHEMA.CPU),
                [ASSET_SCHEMA.RAM.key]: mapVal(ASSET_SCHEMA.RAM),
                GPU: r['GPU'] || '',
                [ASSET_SCHEMA.STORAGE1.key]: mapVal(ASSET_SCHEMA.STORAGE1),
                [ASSET_SCHEMA.STORAGE2.key]: mapVal(ASSET_SCHEMA.STORAGE2),
                [ASSET_SCHEMA.STORAGE3.key]: mapVal(ASSET_SCHEMA.STORAGE3),
                [ASSET_SCHEMA.MONITORING.key]: mapVal(ASSET_SCHEMA.MONITORING),
                [ASSET_SCHEMA.REMARKS.key]: mapVal(ASSET_SCHEMA.REMARKS)
              });
            } else if (sheetName === '구독SW') {
              list.push({ ...common, type: '구독SW', 분야: r['분야'] || '', [ASSET_SCHEMA.CORP.key]: mapVal(ASSET_SCHEMA.CORP), [ASSET_SCHEMA.PRODUCT.key]: mapVal(ASSET_SCHEMA.PRODUCT), 부서: r['부서'] || '', [ASSET_SCHEMA.QTY.key]: mapVal(ASSET_SCHEMA.QTY), [ASSET_SCHEMA.PRICE.key]: mapVal(ASSET_SCHEMA.PRICE), [ASSET_SCHEMA.PURCHASE_YM.key]: mapVal(ASSET_SCHEMA.PURCHASE_YM), 시작일: r['시작일'] || '', [ASSET_SCHEMA.VENDOR.key]: mapVal(ASSET_SCHEMA.VENDOR), [ASSET_SCHEMA.EXPIRY.key]: mapVal(ASSET_SCHEMA.EXPIRY), [ASSET_SCHEMA.REMARKS.key]: mapVal(ASSET_SCHEMA.REMARKS) });
            } else if (sheetName === '영구SW') {
              list.push({ ...common, type: '영구SW', 분야: r['분야'] || '', [ASSET_SCHEMA.CORP.key]: mapVal(ASSET_SCHEMA.CORP), [ASSET_SCHEMA.PRODUCT.key]: mapVal(ASSET_SCHEMA.PRODUCT), 부서: r['부서'] || '', [ASSET_SCHEMA.QTY.key]: mapVal(ASSET_SCHEMA.QTY), [ASSET_SCHEMA.PRICE.key]: mapVal(ASSET_SCHEMA.PRICE), [ASSET_SCHEMA.PURCHASE_YM.key]: mapVal(ASSET_SCHEMA.PURCHASE_YM), 시작일: r['시작일'] || '', [ASSET_SCHEMA.VENDOR.key]: mapVal(ASSET_SCHEMA.VENDOR), [ASSET_SCHEMA.LICENSE_KEY.key]: mapVal(ASSET_SCHEMA.LICENSE_KEY), [ASSET_SCHEMA.REMARKS.key]: mapVal(ASSET_SCHEMA.REMARKS) });
            } else if (sheetName === '클라우드') {
              list.push({ ...common, type: '클라우드', [ASSET_SCHEMA.PLATFORM.key]: mapVal(ASSET_SCHEMA.PLATFORM), [ASSET_SCHEMA.CORP.key]: mapVal(ASSET_SCHEMA.CORP), [ASSET_SCHEMA.PRODUCT.key]: mapVal(ASSET_SCHEMA.PRODUCT), 부서: r['부서'] || '', [ASSET_SCHEMA.ACCOUNT.key]: mapVal(ASSET_SCHEMA.ACCOUNT), [ASSET_SCHEMA.PAY_METHOD.key]: mapVal(ASSET_SCHEMA.PAY_METHOD), [ASSET_SCHEMA.PAY_DAY.key]: mapVal(ASSET_SCHEMA.PAY_DAY), [ASSET_SCHEMA.CARD_NUM.key]: mapVal(ASSET_SCHEMA.CARD_NUM), [ASSET_SCHEMA.BILLING.key]: mapVal(ASSET_SCHEMA.BILLING), [ASSET_SCHEMA.REMARKS.key]: mapVal(ASSET_SCHEMA.REMARKS) });
            } else if (sheetName === '도메인') {
              list.push({ ...common, type: r['유형']||'도메인', corp: r['법인']||'', service_name: r['서비스명']||'', domain_name: r['관리도메인']||'', start_date: r['시작일']||'', expiry_date: r['만료일']||'', price: r['금액']||'', manager_main: r['담당자']||'', manager_sub: r['담당자(부)']||'', remarks: r['비고']||'' });
            }
          });
          if (list.length > 0) parsedData[sheetName] = list;
        });
        resolve(parsedData);
      } catch (err) { reject(err); }
    };
    reader.readAsBinaryString(file);
  });
}
