' ============================================================
' Module Name: Master_Kukan
' Module Desc: M1 Kukan master data management (import/export/validate)
' Module Methods:
'   - CreateEnumDropdown
'   - Worksheet_Change
'   - Validate
' ============================================================

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim HasHeaderEdit As Boolean: HasHeaderEdit = CheckHeaderEdit(Me, Target)
    If HasHeaderEdit = True Then Exit Sub

    ' === Column C changes: Create L column dropdown ===
    If Target.Column = 3 And Target.Row >= 7 Then
        Dim cell As Range
        For Each cell In Target
            If Trim(cell.Value) = "" Then
                Me.Cells(cell.Row, 12).Validation.Delete
                Call ClearDataRow(Me, START_COL + 1, END_COL, cell.Row, ERROR_COL)
            Else
                Call BuildTokubetuDropdown(Me, "L", cell.Row)
                Call BuildRenrakuDropdown(Me, "K", cell.Row)
            End If
        Next
    End If

    ' === Column D changes: Fill E column ===
    If Target.Column = 4 And Target.Row >= 7 Then
        Dim z1Cache As Object: Set z1Cache = GetCache("Z1")

        Dim cellD As Range
        For Each cellD In Target
            Dim dVal As String: dVal = Trim(cellD.Value)
            If dVal = "" Then
                Me.Cells(cellD.Row, 5).ClearContents
            Else
                If Not z1Cache Is Nothing And z1Cache.Exists(dVal) Then
                    Dim valsD As Variant: valsD = z1Cache(dVal)
                    Me.Cells(cellD.Row, 5).Value = valsD(0)
                Else
                    Me.Cells(cellD.Row, 5).ClearContents
                End If
            End If
        Next
    End If
End Sub

Private Sub Validate(ws As Worksheet, ByVal rowNum As Long, ByVal lastDataRow As Long)
    On Error GoTo ErrHandler
    
    Dim sheetConfDict As Object: Set sheetConfDict = GetSheetConfig()
    Dim sheetConf As Object: Set sheetConf = sheetConfDict(ws.CodeName)

    Dim startCol As String: startCol = sheetConf("StartCol")
    Dim endCol As String: endCol = sheetConf("EndCol")
    Dim errorCol As String: errorCol = sheetConf("ErrorCol")

    Dim clearRange As Range: Set clearRange = ws.Range(ws.Cells(rowNum, startCol), ws.Cells(rowNum, endCol))
    clearRange.Interior.Color = vbWhite

    ' Check column required
    Dim colLetter As Variant
    For Each colLetter In Array("C", "D", "E", "F", "G", "I", "L")
        If Trim(ws.Range(colLetter & rowNum).Value) = "" Then
            ws.Cells(rowNum, errorCol).Value = GetErrorMsg("E002", colLetter & rowNum)
            ws.Range(colLetter & rowNum).Interior.Color = RGB(255, 0, 0)
            Exit Sub
        End If
    Next colLetter

    ' Check column numeric
    For Each colLetter In Array("H", "I", "J", "N")
        Dim val As String: val = Trim(ws.Range(colLetter & rowNum).Value)
        If val <> "" And Not IsNumeric(val) Then
            ws.Cells(rowNum, errorCol).Value = GetErrorMsg("E011", colLetter & rowNum)
            ws.Range(colLetter & rowNum).Interior.Color = RGB(255, 0, 0)
            Exit Sub
        End If
    Next colLetter

    ' Check C column repeat
    Dim cValue As String: cValue = Trim(ws.Range("C" & rowNum).Value)
    Dim foundCell As Range
    Set foundCell = ws.Range("C7:C" & lastDataRow).Find(What:=cValue, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
    If Not foundCell Is Nothing Then
        If foundCell.Row <> rowNum Then
            ws.Cells(rowNum, errorCol).Value = "C column value is duplicated"
            ws.Range("C" & rowNum).Interior.Color = RGB(255, 0, 0)
            Exit Sub
        End If
    End If

    ' Check D and E column in the cache
    Dim z1Cache As Object: Set z1Cache = GetCache("Z1")

    Dim dValue As String: dValue = Trim(ws.Range("D" & rowNum).Value)
    Dim eValue As String: eValue = Trim(ws.Range("E" & rowNum).Value)

    If Not z1Cache.Exists(dValue) Then
        ws.Cells(rowNum, errorCol).Value = GetErrorMsg("E004", "D" & rowNum)
        ws.Range("D" & rowNum).Interior.Color = RGB(255, 0, 0)
        Exit Sub
    Else
        Dim valueArray As Variant
        valueArray = z1Cache(dValue)
        If Not IsArray(valueArray) Or UBound(valueArray) < 0 Then
            ws.Cells(rowNum, errorCol).Value = "Invalid reference data for D column."
            Exit Sub
        End If

        Dim expectedEValue As String
        expectedEValue = Trim(CStr(valueArray(0)))

        If eValue <> expectedEValue Then
            ws.Cells(rowNum, errorCol).Value = "E column does not match reference data."
            ws.Range("E" & rowNum).Interior.Color = RGB(255, 0, 0)
            Exit Sub
        End If
    End If

    ' Check L column in the tokubetuList
    Dim tokubetuList As Object: Set tokubetuList = GetCache("tokubetuList")
    Dim lValue As String: lValue = Trim(ws.Range("L" & rowNum).Value)
    If Not tokubetuList.Exists(lValue) Then
        ws.Cells(rowNum, errorCol).Value = "L column does not exist."
        ws.Range("L" & rowNum).Interior.Color = RGB(255, 0, 0)
        Exit Sub
    End If

    ' Validation passed - clear error
    ws.Cells(rowNum, errorCol).ClearContents
    Exit Sub

ErrHandler:
    lastErrorMsg = Err.Description
End Sub

' obtain z1 master data, and update column E
Private Sub Refresh(ws As Worksheet, ByVal startRow As Long, ByVal lastDataRow As Long)
    Dim z1Cache As Object: Set z1Cache = GetCache("Z1")
    
    Application.EnableEvents = False
    On Error GoTo ErrorHandler
    
    Dim r As Long
    For r = startRow To lastDataRow
        Dim dVal As String: dVal = Trim(ws.Cells(r, 4).Value) ' Column D
        If dVal <> "" And z1Cache.Exists(dVal) Then
            Dim valsD As Variant: valsD = z1Cache(dVal)
            ws.Cells(r, 5).Value = valsD(0) ' Column E
        End If
    Next r
    
    Exit Sub

ErrorHandler:
    Application.EnableEvents = True
    Err.Raise ERR_CACHE_NOT_FOUND, "M1.Refresh", "Failed to refresh M1: " & Err.Description
End Sub

Private Sub ValidateWarn(ws As Worksheet, ByVal lastDataRow As Long)
    On Error GoTo ErrorHandler
    Dim exitMsg As String

    ' Get M2 sheet kukan code list directly
    Dim sheetConfDict As Object: Set sheetConfDict = GetSheetConfig()
    Dim m2SheetConf As Object: Set m2SheetConf = sheetConfDict("M2")
    Dim m2StartRow As Long: m2StartRow = m2SheetConf("StartRow")
    Dim wsM2 As Worksheet: Set wsM2 = ThisWorkbook.Worksheets("M2")
    Dim lastRowM2 As Long: lastRowM2 = GetLastDataRowInRange(wsM2)
    If lastRowM2 < m2StartRow Then
        exitMsg = "M2 sheet has no data"
        GoTo ErrorHandler
    End If
    
    ' Build kukan code list from M2 sheet
    Dim kukanList As Object: Set kukanList = CreateObject("Scripting.Dictionary")
    Dim r As Long
    For r = m2StartRow To lastRowM2
        Dim kukanCode As String: kukanCode = Trim(wsM2.Cells(r, 3).Value)
        If kukanCode <> "" And Not kukanList.Exists(kukanCode) Then
            kukanList.Add kukanCode, True
        End If
    Next r

    
    Dim sheetConf As Object: Set sheetConf = sheetConfDict("M1")
    Dim startRow As Long: startRow = sheetConf("StartRow")
    Dim errorCol As String: errorCol = sheetConf("ErrorCol")
    ' Check all rows in M1 sheet
    If lastDataRow < startRow Then
        exitMsg = "M1 sheet has no data"
        GoTo ErrorHandler
    End If
    
    Dim rowNum As Long
    For rowNum = startRow To lastDataRow
        Dim cValue As String: cValue = Trim(ws.Range("C" & rowNum).Value)        
        If Not kukanList.Exists(cValue) Then
            ws.Cells(rowNum, errorCol).Value = GetErrorMsg("W001", cValue)
            ws.Range("C" & rowNum).Interior.Color = RGB(255, 128, 0)
        End If
NextRow:
    Next rowNum
    
    Exit Sub

ErrorHandler:
    If exitMsg <> "" Then
        MsgBox "ValidateWarn: " & exitMsg, vbExclamation
    Else
        MsgBox "ValidateWarn: " & Err.Description, vbExclamation
    End If
End Sub