<template>
  <div class="modern-item-add">
    <!-- 메인 컨텐츠 -->
    <div class="main-content">
      <div class="form-container">
        <v-form ref="addForm" class="modern-form">
          <div class="form-section">
            <h3 class="section-title">
              <i class="mdi mdi-package-variant"></i>
              {{ pageId }}
            </h3>
            
            <!-- 제품명 -->
            <div class="form-field">
              <label class="field-label">
                제품명
              </label>
              <div class="field-content">
                <div class="display-value">
                  {{ form.formValue1 }}
                </div>
              </div>
            </div>
            <div class="form-field">
              <label class="field-label">
                판매 기간
              </label>
              <div class="field-content df--type w--50">
                <div class="display-value date-range">
                  <i class="mdi mdi-calendar-range"></i>
                  {{ form.order_start_date?.slice(0, 10) }} ~ {{ form.order_end_date?.slice(0, 10) }}
                </div>
                <v-btn
                  v-if="form.formValue8 == 0 && memberType !== 'INFLUENCER'"
                  class="closed-btn"
                  color="primary"
                  variant="outlined"
                  @click="fnCloseEvt"
                >
                  <i class="mdi mdi-power"></i>
                  마감
                </v-btn>
              </div>
            </div>

            <!-- 인플루언서 (공동구매인 경우) -->
            <div class="form-field-group group--2" v-if="memberType !== 'INFLUENCER'">
              <div class="form-field">
                <label class="field-label">인플루언서</label>
                <div class="field-content">
                  <div v-if="form.contact_inf" class="display-value date-range">
                    <i class="mdi mdi-account-circle"></i>
                    {{ form.contact_inf_display }}
                  </div>
                  <div v-else class="display-value date-range">
                    <i class="mdi mdi-account-circle"></i>
                    배정된 인플루언서가 없습니다.
                  </div>
                </div>
              </div>
              <!-- 브랜드사 (공동구매인 경우) -->
              <div v-if="memberType !== 'BRAND'" class="form-field">
                <label class="field-label">브랜드사</label>
                <div class="field-content">
                  <div v-if="form.contact_brd" class="display-value date-range">
                    <i class="mdi mdi-domain"></i>
                    {{ form.contact_brd_display }}
                  </div>
                  <div v-else class="display-value date-range">
                    <i class="mdi mdi-domain"></i>
                    배정된 브랜드사가 없습니다.
                  </div>
                </div>
              </div>
            </div>


            <div class="form-field" v-if="form.order_link">
              <label class="field-label">구매 링크</label>
              <div class="field-content">
                <div v-if="pageType == 'D'" class="display-value link-display">
                  <a 
                    :href="form.order_link" 
                    target="_blank" 
                    rel="noopener noreferrer"
                    class="external-link"
                  >
                    <i class="mdi mdi-link"></i>
                    {{ form.order_link }}
                    <i class="mdi mdi-open-in-new"></i>
                  </a>
                </div>
                <v-text-field
                  v-else
                  v-model="form.order_link"
                  class="modern-input"
                  variant="outlined"
                  placeholder="공동구매 링크를 입력하세요"
                  maxlength="200"
                  hide-details="auto"
                ></v-text-field>
              </div>
            </div>

            <div class="form-field">
              <div class="field-content">
                <div class="btn--actions--wrap pb--rem">
                  <div class="left--sections">
                    <label class="mb--0 field-label">주문 내역</label>
                  </div>
                  <div class="right--sections">
                    <div class="caption--wrap">
                      <i class="ico">!</i>
                      <div class="caption--box">
                        - 주문 내역 입력 후 저장 버튼을 꼭 클릭해 주세요.<br />
                        - 엑셀 파일은 최대 10MB까지 업로드 가능합니다.<br />
                        - 엑셀의 헤더는 20개를 초과할 수 없습니다.<br>
                        - 고유번호는 시스템 관리용 번호입니다. 변경 시 오류가 발생할 수 있습니다.
                      </div>
                    </div>
                    <v-btn v-if="hasData" class="custom-btn btn-white mini" @click="addEmptyRow"
                      ><i class="ico"></i>항목 추가</v-btn
                    >
                    <v-btn v-if="hasData" class="custom-btn btn-white mini" @click="deleteSelectedRows"
                      ><i class="ico"></i>항목 삭제</v-btn
                    >
                    <input
                      ref="excelFileInput"
                      type="file"
                      accept=".xlsx,.xls"
                      @change="handleExcelUpload"
                      style="display: none"
                    />
                    <v-btn class="custom-btn btn-excel" @click="$refs.excelFileInput.click()"
                      ><i class="ico"></i>엑셀 업로드</v-btn
                    >
                    <v-btn v-if="hasData" class="custom-btn btn-excel" @click="downloadExcel"
                      ><i class="ico"></i>엑셀 다운로드</v-btn
                    >
                    <v-btn class="custom-btn btn-purple mini" @click="fnRegEvt"
                      ><i class="ico"></i>저장</v-btn
                    >
                  </div>
                </div>
                <div class="tbl-wrapper">
                  <div class="tbl-wrap">
                    <!-- ag grid -->
                    <ag-grid-vue
                      :style="{ width: '100%', height: gridHeight }"
                      class="ag-theme-quartz order--table"
                      :gridOptions="gridOptions"
                      rowSelection="multiple"
                      :rowData="tblItems"
                      :paginationPageSize="pageObj.pageSize"
                      :suppressPaginationPanel="true"
                      @grid-ready="onGridReady"
                      @cell-value-changed="onCellValueChanged"
                    >
                    </ag-grid-vue>

                    <!-- 페이징 -->
                    <!-- <div class="ag-grid-custom-pagenations">
                      <pagination @chg_page="chgPage" :pageObj="pageObj"></pagination>
                    </div> -->
                  </div>
                </div>
              </div>
            </div>
          </div>
        </v-form>
      </div>

      <!-- 액션 버튼 -->
      <div class="action-buttons">
        <div class="button-group left">
          <v-btn
            class="action-btn secondary"
            variant="outlined"
            @click="listLocated"
          >
            <i class="mdi mdi-format-list-bulleted"></i>
            목록으로
          </v-btn>
          <v-btn
            v-if="memberType !== 'INFLUENCER'"
            class="action-btn danger"
            variant="outlined"
            color="error"
            @click="fnDelEvt"
          >
            <i class="mdi mdi-close-circle"></i>
            삭제
          </v-btn>
        </div>
        <div class="button-group right">
          <v-btn
            v-if="memberType !== 'INFLUENCER'"
            class="action-btn primary"
            color="primary"
            @click="fnBtnEvt"
          >
            <i class="mdi mdi-pencil"></i>
            수정하기
          </v-btn>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import useAxios from "@/composables/useAxios";
import "@vuepic/vue-datepicker/dist/main.css";
import { AgGridVue } from "ag-grid-vue3";
import * as XLSX from "xlsx";
/************************************************************************
|    레이아웃
************************************************************************/
definePageMeta({
  layout: "default",
});

/************************************************************************
|    스토어
 ************************************************************************/
const useDtStore = useDetailStore();
const useAtStore = useAuthStore();

/************************************************************************
|    전역
 ************************************************************************/
const memberType = useAtStore.auth.memberType;
const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
const router = useRouter();
const pageId = ref("");
const itemType = useDtStore.boardInfo.itemType;
let pageObj = ref({
  page: 1, // 현재 페이지
  pageMaxNumSize: 10, // 페이지 숫자 최대 표현 개수
  pageSize: 10, // 테이블 조회 데이터 개수
  totalCnt: 0, // 전체 페이지
});
const addForm = ref(null);
const form = ref({
  formValue1: "",
  formValue2: "",
  formValue3: "",
  formValue4: "",
  formValue5: null,
  formValue6: "",
  formValue7: null,
  formValue8: "0",
  formValue8Arr: [
    { title: "판매중", value: "0" },
    { title: "품절", value: "1" },
  ],
  formValue9: "Y",
  formValue9Arr: [
    { title: "노출", value: "Y" },
    { title: "비노출", value: "N" },
  ],
  formValue10: "",
  contact_inf: "", // 실제 전송될 INFLUENCER_SEQ
  contact_inf_display: "", // 화면에 표시될 이름
  contact_brd: "", // 실제 전송될 contact_brd
  contact_brd_display: "", // 화면에 표시될 브랜드명
  order_link: "",
  order_start_date: "",
  order_end_date: "",
});
const apiUrl = ref("");
apiUrl.value = import.meta.env.VITE_APP_API_URL;
const objProc = ref({
  validErrorMessage: "",
});

const pageType = ref("");

// ag-grid 관련 변수
const tblItems = ref([]);
const gridApi = ref(null);
const uploadedHeaders = ref([]); // 엑셀에서 업로드한 헤더 저장

// 데이터 존재 여부 확인 (컬럼이 있고 데이터도 있어야 함)
const hasData = computed(() => {
  return gridOptions.value.columnDefs && 
         gridOptions.value.columnDefs.length > 0 && 
         tblItems.value && 
         tblItems.value.length > 0;
});
const gridOptions = ref({
  columnDefs: [], // 초기에는 빈 배열, ORDER_HEADER_LIST에서 동적으로 생성
  autoSizeStrategy: {
    type: "fitGridWidth", // width맞춤
  },
  suppressHorizontalScroll: false, // 가로 스크롤 제거
  defaultColDef: {
    sortable: true,
    filter: true,
    resizable: true, // 리사이즈 가능하게 변경
    minWidth: 100, // 최소 너비 설정
  },
  suppressMovableColumns: true,
  suppressPaginationPanel: true, // 하단 default 페이징 컨트롤 숨김
  rowMultiSelectWithClick: true,
  rowSelection: {
    checkboxes: true,
    headerCheckbox: true,
    enableClickSelection: false,
    mode: "multiRow",
  },
  localeText: {
    noRowsToShow: '주문 내역이 없습니다.'
  },
  getRowStyle: (params) => {
    // 새로 추가되거나 수정된 행은 연두색 배경
    if (params.data && params.data._isNewOrModified) {
      return { backgroundColor: '#e8f5e8' }; // 연두색 배경
    }
    return null;
  }
});

/************************************************************************
 |    함수(METHODS)
 ************************************************************************/

// 동적 높이 계산
const gridHeight = computed(() => {
  const rowCount = tblItems.value.length;
  const minRows = 5; // 최소 5줄 높이
  const maxRows = 10; // 최대 15줄 높이 (스크롤 시작점)
  const rowHeight = 2.94; // rem 단위
  
  if (rowCount <= minRows) {
    return `calc(${minRows} * ${rowHeight}rem)`;
  } else if (rowCount > maxRows) {
    return `calc(${maxRows} * ${rowHeight}rem)`;
  } else {
    return `calc(${rowCount} * ${rowHeight}rem)`;
  }
});

const addEmptyRow = () => {
  const newRow = {};
  
  // 현재 시간 포맷팅
  const getCurrentTime = () => {
    const now = new Date();
    return now.getFullYear() + '-' + 
           String(now.getMonth() + 1).padStart(2, '0') + '-' + 
           String(now.getDate()).padStart(2, '0') + ' ' +
           String(now.getHours()).padStart(2, '0') + ':' + 
           String(now.getMinutes()).padStart(2, '0') + ':' + 
           String(now.getSeconds()).padStart(2, '0');
  };

  // 해시 생성 함수
  const generateHash = () => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < 50; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  };
  
  // 현재 컬럼 정의에 따라 빈 행 생성
  const currentColumns = gridOptions.value.columnDefs;
  currentColumns.forEach(col => {
    if (col.field && col.field.startsWith('CONTENT_')) {
      newRow[col.field] = "";
    }
  });

  // 업로드 일자와 고유번호 자동 설정
  newRow['CONTENT_REGDATE'] = getCurrentTime();
  newRow['COLUMN_CODE'] = generateHash();
  
  // 새로 추가된 행 표시
  newRow['_isNewOrModified'] = true;

  // 맨 앞에 추가 (unshift 사용)
  tblItems.value.unshift(newRow);
  pageObj.value.totalCnt = tblItems.value.length;

  // ag-grid 데이터 갱신
  if (gridApi.value) {
    gridApi.value.setGridOption("rowData", tblItems.value);
  }

  $toast.success("새 항목이 추가되었습니다.");
};

const deleteSelectedRows = () => {
  if (!gridApi.value) return;

  const selectedRows = gridApi.value.getSelectedRows();
  if (selectedRows.length === 0) {
    $toast.warning("삭제할 항목을 선택해주세요.");
    return;
  }

  let param = {
    id: pageId,
    title: pageId,
    content: `선택된 ${selectedRows.length}개 항목을 삭제하시겠습니까?`,
    yes: {
      text: "삭제",
      isProc: true,
      event: "FN_DELETE_SELECTED",
      param: selectedRows,
    },
    no: {
      text: "취소",
      isProc: false,
    },
  };
  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
};

const fnDeleteSelected = (selectedRows) => {
  
  // 선택된 행들을 tblItems에서 제거 (고유번호 기준으로 찾기)
  selectedRows.forEach((selectedRow) => {
    const index = tblItems.value.findIndex((item) => {
      // 고유번호가 있으면 고유번호로 비교
      if (selectedRow.COLUMN_CODE && item.COLUMN_CODE) {
        return item.COLUMN_CODE === selectedRow.COLUMN_CODE;
      }
      
      // 고유번호가 없으면 모든 CONTENT_ 필드로 비교
      let isMatch = true;
      for (let i = 1; i <= 20; i++) {
        const contentKey = `CONTENT_${i}`;
        if (selectedRow[contentKey] !== item[contentKey]) {
          isMatch = false;
          break;
        }
      }
      return isMatch;
    });
    
    if (index > -1) {
      tblItems.value.splice(index, 1);
    }
  });

  pageObj.value.totalCnt = tblItems.value.length;

  // 데이터가 모두 삭제되었으면 헤더도 초기화
  if (tblItems.value.length === 0) {
    gridOptions.value.columnDefs = [];
    uploadedHeaders.value = [];
    
    if (gridApi.value) {
      gridApi.value.setGridOption("columnDefs", []);
      gridApi.value.setGridOption("rowData", []);
    }
    
  } else {
    // ag-grid 데이터 갱신
    if (gridApi.value) {
      gridApi.value.setGridOption("rowData", tblItems.value);
    }
  }

  $toast.success(`${selectedRows.length}개 항목이 삭제되었습니다.`);
};

const handleExcelUpload = async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const errorHandler = useErrorHandler();

  // 파일 크기 검증 (10MB)
  const maxSize = 10 * 1024 * 1024;
  if (file.size > maxSize) {
    const sizeError = new Error("파일 크기 초과");
    sizeError.name = "FileSizeError";
    errorHandler.handleFileError(sizeError, file.name);
    event.target.value = "";
    return;
  }

  // 파일 형식 검증
  const allowedTypes = [
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "application/vnd.ms-excel",
  ];
  if (!allowedTypes.includes(file.type)) {
    const typeError = new Error("지원하지 않는 파일 형식");
    typeError.name = "FileTypeError";
    errorHandler.handleFileError(typeError, file.name);
    event.target.value = "";
    return;
  }

  const reader = new FileReader();
  reader.onload = async (e) => {
    try {
      const data = new Uint8Array(e.target.result);
      const workbook = XLSX.read(data, { type: "array", cellDates: true });
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, raw: false });

      if (jsonData.length < 2) {
        $toast.error("엑셀 파일에 데이터가 없습니다. 헤더와 최소 1개 이상의 데이터 행이 필요합니다.");
        return;
      }

      const headers = jsonData[0];
      const rows = jsonData.slice(1);

      // 해시 생성 함수
      const generateHash = () => {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        for (let i = 0; i < 50; i++) {
          result += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        return result;
      };
      
      // 현재 시간 포맷팅
      const getCurrentTime = () => {
        const now = new Date();
        return now.getFullYear() + '-' + 
               String(now.getMonth() + 1).padStart(2, '0') + '-' + 
               String(now.getDate()).padStart(2, '0') + ' ' +
               String(now.getHours()).padStart(2, '0') + ':' + 
               String(now.getMinutes()).padStart(2, '0') + ':' + 
               String(now.getSeconds()).padStart(2, '0');
      };

      // 최초 업로드인지 확인 (기존 데이터가 없으면 최초 업로드)
      const isFirstUpload = tblItems.value.length === 0;
      
      // 엑셀에 업로드 일자와 고유번호 헤더가 있는지 확인
      const hasUploadDateHeader = headers.includes("업로드 일자");
      const hasUniqueIdHeader = headers.includes("고유번호");
      let uploadDateIndex = headers.findIndex(h => h === "업로드 일자");
      let uniqueIdIndex = headers.findIndex(h => h === "고유번호");
      
      // 업데이트할 행과 새로 추가할 행 분리
      let updatedItems = [];
      let updateCount = 0;
      let insertCount = 0;
      
      // 최초 업로드인 경우
      if (isFirstUpload) {
        
        rows.forEach((row) => {
          const mappedRow = {};
          let hasValidData = false;
          let uploadDateValue = null;
          let uniqueIdValue = null;

          // 각 셀을 CONTENT_1, CONTENT_2... 형태로 매핑 (업로드 일자, 고유번호 제외)
          let contentIndex = 0;
          headers.forEach((header, index) => {
            if (header === "업로드 일자") {
              uploadDateValue = row[index] ? row[index].toString().trim() : null;
            } else if (header === "고유번호") {
              uniqueIdValue = row[index] ? row[index].toString().trim() : null;
            } else {
              // 일반 데이터는 CONTENT_ 매핑
              contentIndex++;
              const colKey = `CONTENT_${contentIndex}`;
              if (row[index] !== undefined && row[index] !== "") {
                mappedRow[colKey] = row[index].toString().trim();
                hasValidData = true;
              }
            }
          });
          
          if (hasValidData) {
            // 업로드 일자 설정 (CONTENT_REGDATE에 저장)
            mappedRow['CONTENT_REGDATE'] = getCurrentTime();
            
            // 고유번호 설정 (COLUMN_CODE에 저장)
            if (!hasUniqueIdHeader || !uniqueIdValue) {
              mappedRow['COLUMN_CODE'] = generateHash();
            } else {
              mappedRow['COLUMN_CODE'] = uniqueIdValue;
            }
            
            // 새로 추가된 행 표시
            mappedRow['_isNewOrModified'] = true;
            
            updatedItems.unshift(mappedRow); // 새 데이터를 맨 앞에 추가
            insertCount++;
          }
        });
        
      } else if (hasUniqueIdHeader && uniqueIdIndex >= 0) {
        // 재업로드 + 고유번호 헤더가 있는 경우 - 업데이트/인서트 로직
        
        // 기존 데이터의 고유번호 맵 생성 (COLUMN_CODE 사용)
        const existingDataMap = {};
        tblItems.value.forEach((item, index) => {
          if (item['COLUMN_CODE']) {
            existingDataMap[item['COLUMN_CODE']] = { item, index };
          }
        });
        
        updatedItems = [...tblItems.value];
        const processedUniqueIds = new Set();
        
        // 데이터 처리
        rows.forEach((row) => {
          const mappedRow = {};
          let hasValidData = false;
          let existingUniqueId = null;

          // 각 셀을 CONTENT_1, CONTENT_2... 형태로 매핑 (업로드 일자, 고유번호 제외)
          let contentIndex = 0;
          headers.forEach((header, index) => {
            if (header === "업로드 일자") {
              // 업로드 일자는 매핑하지 않음 (기존 값 유지)
              return;
            } else if (header === "고유번호") {
              // 고유번호만 확인용으로 저장
              if (row[index] !== undefined && row[index] !== "") {
                existingUniqueId = row[index].toString().trim();
              }
              return;
            } else {
              // 일반 데이터만 CONTENT_ 매핑
              contentIndex++;
              const colKey = `CONTENT_${contentIndex}`;
              if (row[index] !== undefined && row[index] !== "") {
                mappedRow[colKey] = row[index].toString().trim();
                hasValidData = true;
              }
            }
          });
          
          if (hasValidData) {
            // 고유번호가 있고 기존 데이터에 존재하는 경우 - 업데이트
            if (existingUniqueId && existingDataMap[existingUniqueId]) {
              const { index } = existingDataMap[existingUniqueId];
              // 업데이트 시에는 업로드 일자와 고유번호를 변경하지 않음 (기존 값 완전 유지)
              const updatedItem = { ...updatedItems[index] };
              
              // 고유번호와 업로드 일자를 제외한 나머지 필드만 업데이트
              Object.keys(mappedRow).forEach(key => {
                updatedItem[key] = mappedRow[key];
              });
              
              // 업데이트된 행은 연두색 표시하지 않음 (기존 데이터이므로)
              
              updatedItems[index] = updatedItem;
              processedUniqueIds.add(existingUniqueId);
              updateCount++;
            } else {
              // 새로운 데이터 - 인서트 (고유번호가 없거나 일치하지 않는 경우)
              if (!existingUniqueId) {
                mappedRow['COLUMN_CODE'] = generateHash(); // 고유번호 없으면 생성
              } else {
                mappedRow['COLUMN_CODE'] = existingUniqueId; // 엑셀에 있던 고유번호 사용
              }
              // 새로운 데이터에만 현재 시간으로 업로드 일자 설정
              mappedRow['CONTENT_REGDATE'] = getCurrentTime(); // 업로드 일자
              
              // 새로 추가된 행 표시
              mappedRow['_isNewOrModified'] = true;
              
              updatedItems.unshift(mappedRow); // 새 데이터를 맨 앞에 추가  
              insertCount++;
            }
          }
        });
        
      } else {
        // 재업로드 + 고유번호 헤더가 없는 경우 - 기존 데이터는 유지하고 새 데이터만 추가
        
        // 기존 데이터는 그대로 유지 (고유번호 변경하지 않음)
        updatedItems = [...tblItems.value];
        
        // 기존 헤더에서 업로드 일자와 고유번호 위치 찾기
        const existingHeaders = uploadedHeaders.value || [];
        const existingUploadDateIndex = existingHeaders.findIndex(h => h === "업로드 일자");
        const existingUniqueIdIndex = existingHeaders.findIndex(h => h === "고유번호");
        
        rows.forEach((row) => {
          const mappedRow = {};
          let hasValidData = false;

          // 각 셀을 CONTENT_1, CONTENT_2... 형태로 매핑 (업로드 일자, 고유번호 제외)
          let contentIndex = 0;
          headers.forEach((header, index) => {
            // 업로드 일자와 고유번호는 CONTENT_ 매핑에서 제외
            if (header !== "업로드 일자" && header !== "고유번호") {
              contentIndex++;
              const colKey = `CONTENT_${contentIndex}`;
              if (row[index] !== undefined && row[index] !== "") {
                mappedRow[colKey] = row[index].toString().trim();
                hasValidData = true;
              }
            }
          });
          
          if (hasValidData) {
            // 새로 추가되는 데이터에만 업로드 일자와 고유번호 부여
            mappedRow['CONTENT_REGDATE'] = getCurrentTime(); // 업로드 일자
            mappedRow['COLUMN_CODE'] = generateHash(); // 고유번호 (새 데이터만)
            
            // 새로 추가된 행 표시
            mappedRow['_isNewOrModified'] = true;
            
            updatedItems.unshift(mappedRow); // 새 데이터를 맨 앞에 추가
            insertCount++;
          }
        });
      }
      
      const mappedData = updatedItems;

      if (mappedData.length === 0) {
        $toast.error("매핑 가능한 데이터가 없습니다.");
        return;
      }

      // 먼저 ORDER_HEADER_LIST 업데이트를 위한 헤더 저장
      const headerData = {};
      headers.forEach((header, index) => {
        const headerKey = `HEADER_${index + 1}`;
        if (index < 20) { // 최대 20개 헤더만
          headerData[headerKey] = header || '';
        }
      });
      
      // ag-grid 컬럼을 엑셀 헤더로 동적 생성
      const newColumnDefs = [];
      
      // 체크박스 컬럼
      newColumnDefs.push({
        checkboxSelection: true,
        headerCheckboxSelection: true,
        width: 50,
        sortable: false,
        filter: false,
      });
      
      // No 컬럼
      newColumnDefs.push({
        headerName: "No",
        valueGetter: (params) => params.api.getDisplayedRowCount() - params.node.rowIndex,
        sortable: false,
        filter: false,
        width: 80,
      });
      
      // 헤더 처리: 업로드 일자와 고유번호를 제외한 순수 헤더만 먼저 추출
      let pureHeaders = headers.filter(header => 
        header !== "업로드 일자" && header !== "고유번호"
      );
      
      // 업로드 일자와 고유번호를 항상 맨 끝에 추가
      let enhancedHeaders = [...pureHeaders];
      
      if (isFirstUpload) {
        // 최초 업로드 시 항상 맨 끝에 추가
        enhancedHeaders.push("업로드 일자");
        enhancedHeaders.push("고유번호");
      } else {
        // 재업로드인 경우에도 항상 맨 끝에 추가
        const existingHeaders = uploadedHeaders.value || [];
        const hasExistingUploadDate = existingHeaders.includes("업로드 일자");
        const hasExistingUniqueId = existingHeaders.includes("고유번호");
        
        // 기존에 있었던 경우 맨 끝에 추가
        if (hasExistingUploadDate || !hasUploadDateHeader) {
          enhancedHeaders.push("업로드 일자");
        }
        if (hasExistingUniqueId || !hasUniqueIdHeader) {
          enhancedHeaders.push("고유번호");
        }
      }
      
      // 전역 변수에 헤더 저장 (저장 시 사용)
      uploadedHeaders.value = enhancedHeaders;
      
      // 엑셀 헤더를 기반으로 컬럼 생성
      enhancedHeaders.forEach((header, index) => {
        if (header) { // 헤더가 있으면 처리
          const colDef = {
            headerName: header,
            field: `CONTENT_${index + 1}`,  // 기본적으로 인덱스 기반 필드명
            editable: header !== "업로드 일자" && header !== "고유번호", // 업로드 일자, 고유번호는 편집 불가
            width: 150,
            resizable: true
          };
          
          // 업로드 일자는 CONTENT_REGDATE 필드 참조
          if (header === "업로드 일자") {
            colDef.field = "CONTENT_REGDATE";
            //colDef.cellStyle = { backgroundColor: '#f5f5f5' };
          }
          
          // 고유번호는 COLUMN_CODE 필드 참조
          if (header === "고유번호") {
            colDef.field = "COLUMN_CODE";
            colDef.cellStyle = { backgroundColor: '#f5f5f5' };
            colDef.hide = true;
          }
          
          // 20개를 초과하지 않는 일반 컬럼이거나, 업로드 일자/고유번호인 경우 추가
          if (index < 20 || header === "업로드 일자" || header === "고유번호") {
            newColumnDefs.push(colDef);
          }
        }
      });
      
      // 데이터 설정
      tblItems.value = mappedData;
      pageObj.value.totalCnt = tblItems.value.length;
      
      // gridOptions와 ag-grid API 모두 업데이트
      gridOptions.value.columnDefs = newColumnDefs;
      
      if (gridApi.value) {
        // 컬럼과 데이터를 순차적으로 업데이트
        gridApi.value.setGridOption("columnDefs", newColumnDefs);
        gridApi.value.setGridOption("rowData", tblItems.value);
        
        // 강제로 그리드 새로고침
        gridApi.value.refreshCells({ force: true });
      }

      // 결과 메시지 표시
      let message = '';
      if (updateCount > 0 && insertCount > 0) {
        message = `${updateCount}건 업데이트, ${insertCount}건 추가되었습니다. (총 ${mappedData.length}건)`;
      } else if (updateCount > 0) {
        message = `${updateCount}건의 주문 내역이 업데이트되었습니다.`;
      } else if (insertCount > 0) {
        message = `${insertCount}건의 주문 내역이 추가되었습니다.`;
      } else {
        message = `처리된 데이터가 없습니다.`;
      }
      $toast.success(message);

      // 컬럼 너비를 그리드 전체 너비에 맞춤
      if (gridApi.value) {
        setTimeout(() => {
          gridApi.value.sizeColumnsToFit();
        }, 100);
      }

      // 파일 입력 초기화
      event.target.value = "";

    } catch (error) {
      $toast.error("엑셀 파일을 읽는 중 오류가 발생했습니다. 파일 형식을 확인해주세요.");
    }
  };

  reader.onerror = () => {
    $toast.error("파일을 읽는 중 오류가 발생했습니다.");
  };

  reader.readAsArrayBuffer(file);
}

const downloadExcel = () => {
  if (!tblItems.value || tblItems.value.length === 0) {
    $toast.warning("다운로드할 데이터가 없습니다.");
    return;
  }

  // 현재 ag-grid에서 사용 중인 컬럼 정의에서 헤더 추출
  const visibleColumns = gridOptions.value.columnDefs?.filter(col => 
    col.headerName && 
    col.headerName !== "" && 
    !col.checkboxSelection && 
    col.headerName !== "No"
    // 엑셀 다운로드에는 숨김 컬럼(고유번호)도 포함
  ) || [];

  if (visibleColumns.length === 0) {
    $toast.warning("다운로드할 컬럼이 없습니다.");
    return;
  }

  // 동적 헤더 생성
  const headers = visibleColumns.map(col => col.headerName);
  
  // 데이터를 엑셀 형식으로 변환
  const excelData = tblItems.value.map((item) => {
    return visibleColumns.map(col => {
      const fieldName = col.field;
      return item[fieldName] || "";
    });
  });

  // 헤더를 첫 번째 행에 추가
  const worksheetData = [headers, ...excelData];

  // 워크시트 생성
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);

  // 워크북 생성
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, "주문관리");

  // 파일명 생성 (제품명과 현재 날짜 포함)
  const today = new Date();
  const dateString =
    today.getFullYear() +
    String(today.getMonth() + 1).padStart(2, "0") +
    String(today.getDate()).padStart(2, "0");
  
  // 제품명에서 파일명에 사용할 수 없는 문자 제거
  const productName = form.value.formValue1 ? 
    form.value.formValue1.replace(/[\\/:*?"<>|]/g, "_") : "제품";
  
  const fileName = `${productName}_주문 내역_${dateString}.xlsx`;

  // 엑셀 파일 다운로드
  XLSX.writeFile(workbook, fileName);

  $toast.success("엑셀 파일이 다운로드되었습니다.");
};

const listLocated = () => {
  router.push({
    path: "/view/common/item",
  });
  useDtStore.boardInfo.itemType  = itemType;
};

// 인플루언서 이름 조회
const getInfName = async (contact_inf) => {
  try {
    // contact_inf 값이 있을 때만 API 호출
    if (!contact_inf) {
      return null;
    }

    const response = await useAxios().get(`/user/getInfName/${contact_inf}`);
    
    if (response.data?.status === 'success') {
      return response.data.data;
    } else {
      return null;
    }
  } catch (error) {
    return null;
  }
};

// 브랜드사 조회
const getBrdName = async (contact_brd) => {
  try {
    if (!contact_brd) {
      return null;
    }

    const response = await useAxios().get(`/user/getBrdName/${contact_brd}`);
    
    if (response.data?.status === 'success') {
      return response.data.data;
    } else {
      return null;
    }
  } catch (error) {
    return null;
  }
};

/*======================================================================
|    작성 시퀀스
| 1. 작성 컨펌
| 2. 버튼 체크
| 3. 등록시 -> 등록 API 호출
======================================================================*/

const fnBtnEvt = () => {
  //await editorContent();
  router.push({
      path: "/view/common/item/add",
    });
    useDtStore.boardInfo.itemType = itemType;
    useDtStore.boardInfo.pageType = "U";
};

const fnDelEvt = () => {
  let param = {
    id: pageId,
    title: pageId,
    content: "공동구매를 종료하시겠습니까?",
    yes: {
      text: "확인",
      isProc: true,
      event: "FN_DELETE",
      param: "",
    },
    no: {
      text: "취소",
      isProc: false,
    },
  };
  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
};

const fnCloseEvt = () => {
  let param = {
    id: pageId,
    title: pageId,
    content: "마감하시겠습니까?",
    yes: {
      text: "확인",
      isProc: true,
      event: "FN_CLOSE",
      param: "",
    },
    no: {
      text: "취소",
      isProc: false,
    },
  };
  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
};

const fnClose = () => {
  let req = {
    seq: useDtStore.boardInfo.seq,
  };

  useAxios()
    .post(`/item/close/${req.seq}`)
    .then((res) => {
      router.push("/view/common/item");
    })
    .catch((error) => {
    })
    .finally(() => {
    });
};

const fnDelete = () => {
  let req = {
    seq: useDtStore.boardInfo.seq,
  };

  useAxios()
    .post(`/item/delete/${req.seq}`)
    .then((res) => {
      router.push("/view/common/item");
    })
    .catch((error) => {
    })
    .finally(() => {
    });
};

const getOrderList = () => {
  let req = {
    ITEM_SEQ: useDtStore.boardInfo.seq
  };
  
  useAxios()
    .get(`/order/orderList/${req.ITEM_SEQ}`, req)
    .then(async (res) => {
      // 특정 아이템의 주문만 필터링
      const filteredHeader = res.data.headerList.filter(item => item.ITEM_SEQ == useDtStore.boardInfo.seq);
      const filteredContent = res.data.orderList.filter(item => item.ITEM_SEQ == useDtStore.boardInfo.seq);

      
      // 헤더가 있으면 새로운 columnDefs 생성
      if (filteredHeader && filteredHeader.length > 0) {
        const headerRow = filteredHeader[0];
        
        // 새로운 columnDefs 배열 생성
        const newColumnDefs = [];
        
        // 체크박스 컬럼 (항상 첫 번째)
        newColumnDefs.push({
          checkboxSelection: true,
          headerCheckboxSelection: true,
          width: 50,
          sortable: false,
          filter: false,
        });
        
        // No 컬럼 (항상 두 번째)
        newColumnDefs.push({
          headerName: "No",
          valueGetter: (params) => params.api.getDisplayedRowCount() - params.node.rowIndex,
          sortable: false,
          filter: false,
          width: 80,
        });
        
        // HEADER_1 ~ HEADER_22에서 값이 있는 것만 컬럼으로 추가 (업로드 일자, 고유번호 포함)
        for (let i = 1; i <= 22; i++) {
          const headerKey = `HEADER_${i}`;
          const colKey = `CONTENT_${i}`;  // ORDER_LIST 테이블의 실제 필드명
          
          if (headerRow[headerKey] && headerRow[headerKey].trim() !== '') {
            const headerName = headerRow[headerKey];
            const colDef = {
              headerName: headerName,
              field: colKey,
              editable: true,
              resizable: true
            };
            
            // 업로드 일자는 CONTENT_REGDATE 필드 참조
            if (headerName === '업로드 일자') {
              colDef.field = 'CONTENT_REGDATE';
              colDef.editable = false;
              //colDef.cellStyle = { backgroundColor: '#f5f5f5' };
            }
            
            // 고유번호는 COLUMN_CODE 필드 참조
            if (headerName === '고유번호') {
              colDef.field = 'COLUMN_CODE';
              colDef.editable = false;
              colDef.cellStyle = { backgroundColor: '#f5f5f5' };
              colDef.resizable = false;
              colDef.hide = true;
              colDef.sortable = false;
            }
            
            newColumnDefs.push(colDef);
          }
        }
        
        // ORDER_LIST 데이터 설정
        tblItems.value = filteredContent;
        pageObj.value.totalCnt = filteredContent.length;
        
        // gridOptions와 ag-grid API 모두 업데이트
        gridOptions.value.columnDefs = newColumnDefs;
        
        if (gridApi.value) {
          // 컬럼과 데이터를 순차적으로 업데이트
          gridApi.value.setGridOption("columnDefs", newColumnDefs);
          gridApi.value.setGridOption("rowData", tblItems.value);
          
          // 강제로 그리드 새로고침
          gridApi.value.refreshCells({ force: true });
          
          // 컬럼 너비를 그리드 전체 너비에 맞춤
          setTimeout(() => {
            gridApi.value.sizeColumnsToFit();
          }, 100);
        }
        
        // DB에서 불러온 헤더도 uploadedHeaders에 저장 (HEADER_21, 22 포함)
        const extractedHeaders = [];
        for (let i = 1; i <= 22; i++) {
          const headerKey = `HEADER_${i}`;
          if (headerRow[headerKey] && headerRow[headerKey].trim() !== '') {
            extractedHeaders.push(headerRow[headerKey]);
          }
        }
        uploadedHeaders.value = extractedHeaders;
        
        
      } else {
        
        // 헤더가 없으면 컬럼 정의를 완전히 비움
        const emptyColumnDefs = [];
        
        tblItems.value = [];
        pageObj.value.totalCnt = 0;
        
        gridOptions.value.columnDefs = emptyColumnDefs;
        
        if (gridApi.value) {
          gridApi.value.setGridOption("columnDefs", emptyColumnDefs);
          gridApi.value.setGridOption("rowData", []);
        }
      }
    })
    .catch((error) => {
    })
    .finally(() => {
    });
};

// ag-grid 관련 함수들
const onGridReady = (params) => {
  gridApi.value = params.api;
  // 그리드가 준비되면 컬럼 너비를 그리드 전체 너비에 맞춤
  setTimeout(() => {
    gridApi.value.sizeColumnsToFit();
  }, 100);
};

const onCellValueChanged = (params) => {
  // 셀 값 변경은 기존 데이터 수정이므로 연두색 표시하지 않음
  // (새로 insert되는 행만 연두색 표시)
};

// 모든 행의 수정 플래그 제거
const clearModifiedFlags = () => {
  if (tblItems.value) {
    tblItems.value.forEach(item => {
      delete item._isNewOrModified;
    });
    
    // 그리드 새로고침
    if (gridApi.value) {
      gridApi.value.refreshCells({ force: true });
    }
  }
};

const chgPage = (page) => {
  pageObj.value.page = page;
  // 페이징이 필요한 경우 여기에 추가 로직 구현
};

const fnRegEvt = () => {
  let param = {
      id: pageId,
      title: pageId,
      content: "주문 내역을 저장하시겠습니까?",
      yes: {
        text: "확인",
        isProc: true,
        event: "FN_INSERT",
        param: "",
      },
      no: {
        text: "취소",
        isProc: false,
      },
    };
    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
};

const fnDetail = () => {
  let req = {
    seq: useDtStore.boardInfo.seq,
  };
  useAxios()
    .get(`/item/detail/${req.seq}`)
    .then(async (res) => {
      form.value.formValue1 = res.data.NAME;
      form.value.formValue8 = res.data.STATUS;
      form.value.formValue9 = res.data.SHOW_YN;
      form.value.formValue10 = res.data.ADD_INFO;
      form.value.order_link = res.data.ORDER_LINK;
      form.value.order_start_date = res.data.ORDER_START_DATE;
      form.value.order_end_date = res.data.ORDER_END_DATE;
      form.value.contact_inf = res.data.CONTACT_INF;
      form.value.contact_brd = res.data.CONTACT_BRD;
      
      // contact_inf 값이 있으면 인플루언서 이름 조회
      if (res.data.CONTACT_INF) {
        const infData = await getInfName(res.data.CONTACT_INF);
        if (infData) {
          form.value.contact_inf_display = infData.NICK_NAME 
            ? `${infData.NICK_NAME} (${infData.NAME})`
            : infData.NAME;
        }
      }
      if (res.data.CONTACT_BRD) {
        const brdData = await getBrdName(res.data.CONTACT_BRD);
        if (brdData) {
          form.value.contact_brd_display = brdData.NAME;
        }
      }
      getOrderList();
    })
    .catch((error) => {
    })
    .finally(() => {
    });
};

const fnInsert = async () => {
  gridApi.value.stopEditing();
  
  try {
    // 데이터가 비어있으면 전체 삭제 처리
    if (!tblItems.value || tblItems.value.length === 0) {
      
      const req = {
        itemSeq: useDtStore.boardInfo.seq,
        headers: [],
        orderData: []
      };
      
      const response = await useAxios().post('/order/reg', req);
      
      
      if (response.data && response.data.success) {
        $toast.success('저장이 완료되었습니다.');
        getOrderList(); // 데이터 다시 로드
      } else if (response.success) {
        $toast.success('저장이 완료되었습니다.');
        getOrderList(); // 데이터 다시 로드
      } else {
        $toast.error('삭제에 실패했습니다.');
      }
      
      return;
    }
    
    // 데이터가 있는 경우 기존 로직
    // uploadedHeaders가 있으면 사용, 없으면 columnDefs에서 추출
    let headers = [];
    
    if (uploadedHeaders.value && uploadedHeaders.value.length > 0) {
      // 엑셀에서 업로드한 헤더 사용 (업로드 일자, 고유번호 제외)
      headers = uploadedHeaders.value.filter(header => 
        header !== '업로드 일자' && header !== '고유번호'
      );
    } else {
      // 기존 데이터에서 헤더 추출 (DB에서 불러온 경우, 업로드 일자와 고유번호 제외)
      const currentColumns = gridOptions.value.columnDefs;
      currentColumns.forEach(col => {
        if (col.field && col.field.startsWith('CONTENT_')) {
          const headerName = col.headerName || '';
          if (headerName !== '업로드 일자' && headerName !== '고유번호') {
            headers.push(headerName);
          }
        }
      });
    }
    
    // 헤더가 비어있는 경우 처리
    if (headers.length === 0) {
      $toast.warning('헤더 정보가 없습니다. 엑셀을 먼저 업로드해주세요.');
      return;
    }
    
    const req = {
      itemSeq: useDtStore.boardInfo.seq,
      headers: headers,
      orderData: tblItems.value || []
    };
    
    const response = await useAxios().post('/order/reg', req);
    
    
    // axios 응답 데이터는 response.data에 있음
    if (response.data && response.data.success) {
      $toast.success(`${response.data.message} (주문: ${response.data.orderCount}건)`);
      
      // 저장 성공 후 모든 행의 수정 플래그 제거
      clearModifiedFlags();
      
      // 저장 후 데이터 다시 로드
      getOrderList();
      
    } else if (response.success) {
      // 만약 response에 직접 success가 있는 경우
      $toast.success(`${response.message} (주문: ${response.orderCount}건)`);
      
      // 저장 성공 후 모든 행의 수정 플래그 제거
      clearModifiedFlags();
      
      // 저장 후 데이터 다시 로드
      getOrderList();
    } else {
      $toast.error('저장에 실패했습니다.');
    }
    
  } catch (error) {
    
    // 백엔드 에러 응답 확인
    if (error.response?.data) {
      const errorData = error.response.data;
      
      if (errorData.error) {
        $toast.error(errorData.error);
      } else if (errorData.message) {
        $toast.error(errorData.message);
      } else {
        $toast.error('저장 중 오류가 발생했습니다.');
      }
    } else {
      if (tblItems.value.length === 0) {
        $toast.warning("저장할 데이터가 없습니다.");
      } else {
        $toast.error('저장 중 오류가 발생했습니다.');
      }
    }
  }
};

/************************************************************************
|    팝업 이벤트버스 정의
************************************************************************/

$eventBus.off("FN_DELETE");
$eventBus.on("FN_DELETE", () => {
  fnDelete();
});

$eventBus.off("FN_CLOSE");
$eventBus.on("FN_CLOSE", () => {
  fnClose();
});

$eventBus.off("FN_INSERT");
$eventBus.on("FN_INSERT", () => {
  fnInsert();
});

$eventBus.off("FN_DELETE_SELECTED");
$eventBus.on("FN_DELETE_SELECTED", (selectedRows) => {
  fnDeleteSelected(selectedRows);
});

/************************************************************************
|    라이프사이클
************************************************************************/
onMounted(() => {
  pageType.value = "D";
  
  if(pageType.value == "I"){
    if(itemType == "G"){
      pageId.value = "공동구매 등록"
    } else {
      pageId.value = "제품 등록"
    }
  } else if(pageType.value == "U"){
    if(itemType == "G"){
      pageId.value = "공동구매 수정"
    } else {
      pageId.value = "제품 수정"
    }
  } else  {
    if(itemType == "G"){
      pageId.value = "공동구매 상세"
    } else {
      pageId.value = "제품 상세"
    }
  }

  //상세 등록 아니 리스트 클릭시 상세 정보로 접근
  if (pageType.value !== "I") {
    fnDetail();
  }
});

</script>

<style scoped>
.cursor-pointer {
  cursor: pointer;
}

.cursor-pointer:hover {
  background-color: #f5f5f5;
}

.order-link {
  color: #1976d2;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: color 0.2s;
}

.order-link:hover {
  color: #1565c0;
  text-decoration: underline;
}

.no-link {
  color: #999;
  font-style: italic;
}
</style>
