import os
import openpyxl as Workbook

from openpyxl.utils import get_column_letter
from openpyxl.drawing.image import Image

import UtilPack as util

from abc import ABC, abstractmethod

class DBXLStorage(ABC):
    xls_name = "EPoleDB.xlsx"
    xls_infosheet = "DBInfo"
    
    m_wb = None
    m_openedXLS = ""
    m_defaultImgW = 140
    
    def __init__(self, path):
        self.path = path
        
    #def __enter__(self):
        #self.DBXLSOpen(self.path)
        
    def __exit__(self, ex_type, ex_value, traceback):
        self.DBXLSClose()
        
    def DBXLSOpen(self):
        xls_path = self.GetXLSPath(self.path)
        util.DbgOut(xls_path, True)
        
        try:
            self.m_wb = Workbook.load_workbook(xls_path)
            util.DbgOut("xls Open Successed")
        except FileNotFoundError:
            self.m_wb = Workbook.Workbook()
            
            ws = self.m_wb.active
            ws.title = self.xls_infosheet #DBInfo
            ws.cell(row=1,column=1,value="PoleDB_XLS")
            
            self.m_wb.save(xls_path)
            util.DbgOut(f"{xls_path} Created", True)
            
        self.m_openedXLS = xls_path
          
        if self.m_wb is None:
            util.DbgOut("XLS Open Something Wrong...", True)
            self.m_openedXLS = ""
            self.m_wb = None
            return
        
        self.checkSheetsInfo()
        
        
    def DBXLSClose(self):
        if self.m_wb is None or self.m_openedXLS is None:
            util.DbgOut("XLS Close something wrong...", True)
            return
        
        self.m_wb.save(self.m_openedXLS)
        self.m_wb.close()
        util.DbgOut(f"Close : {self.m_openedXLS} Saved")
        
        self.m_wb = None
                
        
    def GetCellValueStr(self, sheetName, nCol, nRow):
        sheet = self.getSheet(sheetName);
        if sheet is None:
            return ""
        
        return sheet.cell(row=nRow, column=nCol).value.str
        
    
    def SetCellValueStr(self, sheetName, nCol, nRow, ValueStr):   
        sheet = self.getSheet(sheetName);
        if sheet is None:
            return
        
        sheet.cell(row=nRow,column=nCol,value=ValueStr)
        
        
    def SetCellValueImg(self, sheetName, nCol, nRow, ImagePath):
        sheet = self.getSheet(sheetName);
        if sheet is None:
            return
        
        if False == os.path.exists(ImagePath):
            return

        xlImg = Image(ImagePath)
        nNewH = util.GetRSzHeight(xlImg.width, 
                                  xlImg.height, self.m_defaultImgW )
        xlImg.height = nNewH
        xlImg.width = self.m_defaultImgW
        
        ColLetter = get_column_letter(nCol)
        TrgCell = f"{ColLetter}{nRow}"
        
        cellW, cellH = util.GetCellSize(xlImg.width, xlImg.height)
        
        sheet.row_dimensions[nRow].height = cellH
        sheet.column_dimensions[ColLetter].width = cellW
        
        sheet.add_image(xlImg, TrgCell)
        
        
    def GetCellValue(self, sheetName, nCol, nRow):
        sheet = self.getSheet(sheetName);
        if sheet is None:
            return ""
        
        return sheet.cell(nRow, nCol).value
        
    
    # 시트를 가져온다. 
    #    엑셀 파일이 안 열려 있으면 None
    def getSheet(self, sheetName:str, bNew:bool = False):
        if self.m_wb is None:
            util.DbgOut("XLS not opened", True)
            return None
        
        if util.IsEmptyStr(sheetName):
            return None
        
        retSheet = None
        
        try:
            retSheet = self.m_wb[sheetName]
        except KeyError:
            if True == bNew:
                retSheet = self.m_wb.create_sheet(title=sheetName)
                util.DbgOut(f"GetSheet : {sheetName} is Created", True)
        
        return retSheet
    
    
    # 데이터베이스용 엑셀 파일의 경로를 얻어온다.
    # 폴더만 입력되었으면 파일이름을 삽입하고, 완전한 경로라면 패스
    def GetXLSPath(self, pathSrc:str)-> str:
        retPath = self.path
        
        if os.path.isdir(pathSrc):
            retPath = os.path.join(pathSrc, self.xls_name)
        
        return retPath
    
    def FindLastRow(self, sheetName:str)-> int:
        sheet = self.getSheet(sheetName)
        if sheet is None:
            return -1
        
        # 마지막 행 찾기
        last_row = sheet.max_row

        # 빈 셀이 있는지 확인하고, 실제로 값이 있는 마지막 행 찾기
        while last_row > 0:
            row = sheet[last_row]  # 현재 행을 가져옴
              
            # 현재 행의 모든 셀을 검사하여 값이 있는지 확인
            is_empty = True
            for cell in row:
                if cell.value is not None:
                    is_empty = False
                    break
              
            # 값이 있는 행을 찾았으면 종료
            if not is_empty:
                break
              
            # 행 번호를 하나씩 감소시켜 이전 행을 검사
            last_row -= 1
            
        return last_row
    
    
    @abstractmethod
    def checkSheetsInfo(self):
       pass

        

        


