Imports MySql.Data.MySqlClient
Imports Renci.SshNet

Module mySQLModule
    '' MySQL 접속 정보
    Private Const LocalHostIP As String = "192.168.0.250"
    Private Const UserName As String = "root"
    Private Const UserPasswrod As String = "JOMT1646db!!"
    Private DataBaseName As String = "jomtOrderTestDB"

    Private Conn As String = "Server=" + LocalHostIP + ";DataBase=" + DataBaseName + ";user=" + UserName + ";password=" + UserPasswrod + ";"

    Private sqlCon As New MySqlConnection(Conn)
    Private sqlCmd As New MySqlCommand()
    Private sqlData As MySqlDataReader           '' SQL Server와 연결을 유지한 상태에서 한번에 한 레코드(One Row)씩 데이타를 가져오는데 사용된다

    Public sqlDataQuery() As Object

    Public Const SaleDB As String = "jomtTesterDB.jomtSalesPackingTbl"
    Public Const NonTDDB As String = "jomtTesterDB.jomtNonTDTbl"
    Public Const CartTDDB As String = "jomtTesterDB.jomtCartridgeTbl"
    Public Const OrderDB As String = "jomtOrderDB.jomtOrderTbl"
    Public Const PlistDB As String = "jomtTesterDB.jomtProdList"
    Dim genuineProductDtoMap As Dictionary(Of String, GenuineProductDto)
    Private orderCodeList As HashSet(Of String)

    Public Function GetDBConn() As MySqlConnection
        Try
            If sqlCon.State <> ConnectionState.Open Then
                sqlCon.Open()
            End If
            Return sqlCon
        Catch ex As Exception
            MsgBox("MySQL Command Error:" + vbCrLf + Err.Description)
            Return Nothing
        End Try
    End Function
    Public Sub lowProdList(dic As Dictionary(Of String, String))
        Using Conn As MySqlConnection = GetDBConn()
            Dim cmd As New MySqlCommand("SELECT distinct 88_Code, ModelNum, ColorNum FROM jomtTesterDB.jomtProdList WHERE 88_Code IS NOT NULL", Conn)

            Using reader As MySqlDataReader = cmd.ExecuteReader()
                While reader.Read
                    Dim key = reader("88_Code").ToString.Trim
                    Dim value = reader("ModelNum").ToString.Trim + reader("ColorNum").ToString.Trim
                    dic.Add(key, value)
                End While
            End Using
        End Using
    End Sub
    Public Function FindSerialsByDate(targetDate As Date) As ValueTuple(Of List(Of String), List(Of String))
        Using conn As MySqlConnection = GetDBConn()
            Dim getSerialCmd As New MySqlCommand("SELECT Serial_Number,Order_Code FROM jomtOrderDB.jomtOrderTbl 
                                         WHERE Invoice_Number IS NOT NULL 
                                           AND Serial_Number IS NOT NULL                                                       
                                           AND ((LEFT(Serial_Number,1) < '8' AND LENGTH(Serial_Number) > 11 ) OR Serial_Number in (SELECT distinct 88_Code FROM jomtTesterDB.jomtProdList WHERE 88_Code IS NOT NULL))
                                           AND genuine_date is null
                                           AND Shipment_Date = @date", conn)

            getSerialCmd.Parameters.AddWithValue("@date", targetDate)

            Dim serials As New List(Of String)
            Dim unmatchedSerials As New List(Of String)
            orderCodeList = New HashSet(Of String)
            Using reader As MySqlDataReader = getSerialCmd.ExecuteReader()
                While reader.Read()
                    orderCodeList.Add(reader("Order_Code").ToString().Trim())
                    Dim raw = reader("Serial_Number").ToString().Trim()
                    If raw.Contains("/") Then
                        serials.AddRange(raw.Split("/"c).Select(Function(s) s.Trim()).Where(Function(s) s.Length > 0))
                        unmatchedSerials.Add(raw.Split("/"c).Select(Function(s) s.Trim()).FirstOrDefault(Function(s) s.Length > 0))
                    ElseIf raw.Length > 0 Then
                        serials.Add(raw)
                    End If
                End While
            End Using

            Return (serials.ToList(), unmatchedSerials.ToList())
        End Using

    End Function

    Public Sub FillFromOrderTblByLike(dtoMap As Dictionary(Of String, GenuineProductDto), likeClauses As List(Of String))
        Using conn As MySqlConnection = GetDBConn()
            For Each clause In likeClauses
                Dim query As String =
                "SELECT Serial_Number, Item_Code, Item_Name, Invoice_Number, Packing_Code, DATE_FORMAT(Shipment_Date, '%Y-%m-%d') AS Shipment_Date, " &
                "Account_Name, Order_Code, Orderer_Name, Receiver_Name, Phone_Number, Address, Refer " &
                "FROM jomtOrderDB.jomtOrderTbl " &
                "WHERE " & clause

                Using cmd As New MySqlCommand(query, conn)
                    Using reader = cmd.ExecuteReader()
                        While reader.Read()
                            Dim serialRaw = reader("Serial_Number").ToString().Trim()
                            Dim serials = serialRaw.Split("/"c)

                            For Each sn In serials
                                Dim key = sn.Trim()
                                If dtoMap.ContainsKey(key) Then
                                    Dim dto = dtoMap(key)

                                    dto.ModelCode = reader("Item_Code").ToString()
                                    dto.Model = reader("Item_Name").ToString()
                                    dto.InvoiceNumber = reader("Invoice_Number").ToString()
                                    dto.PackingSn = reader("Packing_Code").ToString()
                                    dto.BuyDate = reader("Shipment_Date").ToString()
                                    dto.SalesStore = reader("Account_Name").ToString()
                                    dto.SalesOrderNo = reader("Order_Code").ToString()
                                    dto.OrderName = reader("Orderer_Name").ToString()
                                    dto.RecipientName = reader("Receiver_Name").ToString()
                                    dto.OrderHp = reader("Phone_Number").ToString()
                                    dto.OrderAddress = reader("Address").ToString()
                                    dto.Note = reader("Refer").ToString()
                                End If
                            Next
                        End While
                    End Using
                End Using
            Next
        End Using
    End Sub

    Public Sub FillFromOrderTblByIn(dtoMap As Dictionary(Of String, GenuineProductDto), inClauses As List(Of String))
        Dim serials = dtoMap.Keys.ToList()
        Dim missingItemCodeSNs As New List(Of String)

        Using conn As MySqlConnection = GetDBConn()
            For Each clause In inClauses
                Dim query As String =
                "SELECT Serial_Number, Item_Code, Item_Name, Invoice_Number, Packing_Code, DATE_FORMAT(Shipment_Date, '%Y-%m-%d') AS Shipment_Date, " &
                "Account_Name, Order_Code, Orderer_Name, Receiver_Name, Phone_Number, Address, Refer " &
                "FROM jomtOrderDB.jomtOrderTbl " &
                "WHERE Serial_Number IN " & clause

                Using cmd As New MySqlCommand(query, conn)
                    Using reader = cmd.ExecuteReader()
                        While reader.Read()
                            Dim sn = reader("Serial_Number").ToString().Trim()
                            If dtoMap.ContainsKey(sn) Then
                                Dim dto = dtoMap(sn)

                                dto.ModelCode = reader("Item_Code").ToString()
                                dto.Model = reader("Item_Name").ToString()
                                dto.InvoiceNumber = reader("Invoice_Number").ToString()
                                dto.PackingSn = reader("Packing_Code").ToString()
                                dto.BuyDate = reader("Shipment_Date").ToString()
                                dto.SalesStore = reader("Account_Name").ToString()
                                dto.SalesOrderNo = reader("Order_Code").ToString()
                                dto.OrderName = reader("Orderer_Name").ToString()
                                dto.RecipientName = reader("Receiver_Name").ToString()
                                dto.OrderHp = reader("Phone_Number").ToString()
                                dto.OrderAddress = reader("Address").ToString()
                                dto.Note = reader("Refer").ToString()
                            End If
                        End While
                    End Using
                End Using
            Next
        End Using
    End Sub

    Public Sub FillFromProductTbl(dtoMap As Dictionary(Of String, GenuineProductDto), inClauses As List(Of String))
        Dim serials = dtoMap.Keys.ToList()

        Using conn As MySqlConnection = GetDBConn()
            For Each clause In inClauses
                Dim query As String =
                "SELECT Product_SN, FaceCart_SN, EyeCart_SN " &
                "FROM jomtTesterDB.jomtProductTbl " &
                "WHERE Product_SN IN " & clause

                Using cmd As New MySqlCommand(query, conn)
                    Using reader = cmd.ExecuteReader()
                        While reader.Read()
                            Dim sn = reader("Product_SN").ToString()
                            If dtoMap.ContainsKey(sn) Then
                                dtoMap(sn).FaceSn = reader("FaceCart_SN").ToString()
                                dtoMap(sn).EyeSn = reader("EyeCart_SN").ToString()
                            End If
                        End While
                    End Using
                End Using
            Next
        End Using
    End Sub

    Public Sub FillFromProdData(dtoMap As Dictionary(Of String, GenuineProductDto), inClauses As List(Of String))
        Dim serials = dtoMap.Keys.ToList()

        Using conn As MySqlConnection = GetDBConn()
            For Each clause In inClauses
                Dim query As String =
                "SELECT Product_SN, Ct_Abroad AS Country, DATE_FORMAT(P3_DateTime, '%Y-%m-%d') AS MfgDate " &
                "FROM jomtTesterDB.jomtCartridgeTbl WHERE Product_SN IN " & clause &
                "UNION ALL " &
                "SELECT Product_SN, Abroad AS Country, DATE_FORMAT(DateTime, '%Y-%m-%d') AS MfgDate " &
                "FROM jomtTesterDB.jomtDeviceTbl WHERE Product_SN IN " & clause &
                "UNION ALL " &
                "SELECT Product_SN, Ct_Abroad AS Country, DATE_FORMAT(P3_DateTime, '%Y-%m-%d') AS MfgDate " &
                "FROM jomtTesterDB.jomtNonTDTbl WHERE Product_SN IN " & clause

                Using cmd As New MySqlCommand(query, conn)
                    Using reader = cmd.ExecuteReader()
                        While reader.Read()
                            Dim sn = reader("Product_SN").ToString()
                            If dtoMap.ContainsKey(sn) AndAlso String.IsNullOrEmpty(dtoMap(sn).CountryCode) Then
                                dtoMap(sn).CountryCode = reader("Country").ToString()
                                dtoMap(sn).ManufactureDate = reader("MfgDate").ToString()
                            End If
                        End While
                    End Using
                End Using
            Next
        End Using
    End Sub

    Public Function getOyList(dic As Dictionary(Of String, String)) As Dictionary(Of String, GenuineProductDto)
        Dim TdTableList As New List(Of String) From {"jomtTesterDB.jomtCartridgeTbl", "jomtTesterDB.jomtLDMTbl", "jomtTesterDB.jomtNonTDTbl"}
        genuineProductDtoMap = New Dictionary(Of String, GenuineProductDto)
        Dim OliveYoungRelateDTOList As New List(Of OliveYoungRelateDTO)
        Dim Serial_NumberFilterList As New List(Of String)()
        For Each sn In dic.Keys
            If Not String.IsNullOrWhiteSpace(sn) Then
                Serial_NumberFilterList.Add(sn.Trim())
            End If
        Next

        Using conn As MySqlConnection = GetDBConn()
            '' 첫 번째 쿼리: Serial_Number IN (파라미터)
            If Serial_NumberFilterList.Count > 0 Then
                Dim inParams As New List(Of String)
                For i As Integer = 0 To Serial_NumberFilterList.Count - 1
                    inParams.Add("@sno" & i)
                Next
                Dim inClause As String = String.Join(", ", inParams)
                Dim query As String = "SELECT DISTINCT item_code, item_name, Serial_Number, Invoice_Number, DATE_FORMAT(Shipment_Date, '%Y-%m-%d') AS Shipment_Date, Account_Name FROM jomtOrderDB.jomtOrderTbl WHERE Serial_Number IN (" & inClause & ") AND genuine_date IS NULL"
                Using cmd As New MySqlCommand(query, conn)
                    For i As Integer = 0 To Serial_NumberFilterList.Count - 1
                        cmd.Parameters.AddWithValue("@sno" & i, Serial_NumberFilterList(i))
                    Next
                    Using reader = cmd.ExecuteReader()
                        While reader.Read()
                            Dim oy_object As New OliveYoungRelateDTO(reader("Serial_Number").ToString().Trim())
                            oy_object.colorFlag = dic(oy_object.Serial_Number)
                            oy_object.itemCode = reader("item_code").ToString().Trim()
                            oy_object.item_name = reader("item_name").ToString().Trim()
                            oy_object.invoice = reader("Invoice_Number").ToString().Trim()
                            oy_object.Shipment_Date = reader("Shipment_Date").ToString().Trim()
                            oy_object.Account_Name = reader("Account_Name").ToString().Trim()
                            OliveYoungRelateDTOList.Add(oy_object)
                        End While
                    End Using
                End Using
            End If

            '' 두 번째 쿼리: Product_SN LIKE (파라미터) - TdTableList 각 테이블 조회 (동일 스키마: Product_SN, Ct_Abroad, P3_DateTime, LastQC_Date, TestStep, genuine_date)
            For Each obj In OliveYoungRelateDTOList
                Dim likeValue As String = obj.colorFlag & "%"

                For Each tableName As String In TdTableList
                    If String.IsNullOrWhiteSpace(tableName) Then Continue For
                    Dim query2 As String = "SELECT Product_SN, Ct_Abroad AS Country, DATE_FORMAT(P3_DateTime, '%Y-%m-%d') AS MfgDate FROM " & tableName & " WHERE Product_SN LIKE @colorPrefix AND LastQC_Date IS NOT NULL AND TestStep = 31 AND genuine_date IS NULL"
                    Try
                        Using sec_cmd As New MySqlCommand(query2, conn)
                            sec_cmd.Parameters.AddWithValue("@colorPrefix", likeValue)
                            Using sec_reader = sec_cmd.ExecuteReader()
                                While sec_reader.Read()
                                    Dim productSn As String = sec_reader("Product_SN").ToString()
                                    If genuineProductDtoMap.ContainsKey(productSn) Then Continue While
                                    Dim dto As New GenuineProductDto(productSn)
                                    dto.ModelCode = obj.itemCode
                                    dto.Model = obj.item_name
                                    dto.PackingSn = obj.Serial_Number
                                    dto.SalesStore = obj.Account_Name
                                    dto.ManufactureDate = sec_reader("MfgDate").ToString()
                                    dto.InvoiceNumber = obj.invoice
                                    dto.BuyDate = obj.Shipment_Date
                                    genuineProductDtoMap.Add(productSn, dto)
                                End While
                            End Using
                        End Using
                    Catch ex As MySqlException
                        '' 테이블/컬럼 스키마가 다르면 해당 테이블만 스킵 (예: jomtLDMTbl이 Abroad/DateTime 사용 시)
                        '' 필요 시 로그: MsgBox("테이블 조회 제외: " & tableName & " - " & ex.Message)
                    End Try
                Next
            Next
        End Using

        Return genuineProductDtoMap
    End Function

    Public Function updateOliveYoungGenuineDate(dic As Dictionary(Of String, String)) As Boolean
        '' Product_SN, genuine_date 컬럼이 있는 테이블만 포함 (스키마 동일한 테이블만)
        Dim TdTableList As New List(Of String) From {"jomtTesterDB.jomtCartridgeTbl", "jomtTesterDB.jomtLDMTbl", "jomtTesterDB.jomtNonTDTbl"}
        Try
            Dim productSnList As New List(Of String)()
            If genuineProductDtoMap IsNot Nothing Then
                productSnList.AddRange(genuineProductDtoMap.Keys)
            End If

            Dim serialFilterList As New List(Of String)() ''88코드
            For Each sn In dic.Keys
                If Not String.IsNullOrWhiteSpace(sn) Then serialFilterList.Add(sn.Trim())
            Next

            Dim orderList As New List(Of String)()
            If orderCodeList IsNot Nothing Then
                orderList.AddRange(orderCodeList)
            End If

            Using conn As MySqlConnection = GetDBConn()
                '' TD 테이블들: Product_SN IN (파라미터)
                If productSnList.Count > 0 Then
                    Dim inParams As New List(Of String)
                    For i As Integer = 0 To productSnList.Count - 1
                        inParams.Add("@psn" & i)
                    Next
                    Dim inClause As String = String.Join(", ", inParams)
                    For Each tableName As String In TdTableList
                        Dim query As String = "UPDATE " & tableName & " SET genuine_date = NOW() WHERE Product_SN IN (" & inClause & ")"
                        Using cmd As New MySqlCommand(query, conn)
                            For i As Integer = 0 To productSnList.Count - 1
                                cmd.Parameters.AddWithValue("@psn" & i, productSnList(i))
                            Next
                            cmd.ExecuteNonQuery()
                        End Using
                    Next
                End If

                '' 주문 테이블: Order_Code IN, Serial_Number IN (파라미터)
                If orderList.Count = 0 Then Return True
                Dim orderParams As New List(Of String)
                For i As Integer = 0 To orderList.Count - 1
                    orderParams.Add("@ord" & i)
                Next
                Dim orderInClause As String = String.Join(", ", orderParams)
                Dim serialInClause As String = ""
                '' 조건 충족 시: Serial_Number IN으로 주문 테이블 업데이트
                If serialFilterList.Count > 0 AndAlso productSnList.Count > 0 Then
                    Dim serialParams As New List(Of String)
                    For i As Integer = 0 To serialFilterList.Count - 1
                        serialParams.Add("@sno" & i)
                    Next
                    serialInClause = String.Join(", ", serialParams)
                    Dim queryBySerial As String = "UPDATE jomtOrderDB.jomtOrderTbl SET genuine_date = NOW() WHERE Serial_Number IN (" & serialInClause & ") and genuine_date is null"
                    Using cmd As New MySqlCommand(queryBySerial, conn)
                        For i As Integer = 0 To serialFilterList.Count - 1
                            cmd.Parameters.AddWithValue("@sno" & i, serialFilterList(i))
                        Next
                        cmd.ExecuteNonQuery()
                    End Using
                End If

                '' 공통: Order_Code IN + 시리얼 형식 조건으로 주문 테이블 업데이트
                Dim queryOrder As String = "UPDATE jomtOrderDB.jomtOrderTbl SET genuine_date = NOW() WHERE Order_Code IN (" & orderInClause & ") AND (LEFT(Serial_Number,1) < '8' AND LENGTH(Serial_Number) > 11)"
                Using cmd As New MySqlCommand(queryOrder, conn)
                    For i As Integer = 0 To orderList.Count - 1
                        cmd.Parameters.AddWithValue("@ord" & i, orderList(i))
                    Next
                    cmd.ExecuteNonQuery()
                End Using
            End Using
            Return True
        Catch ex As Exception
            MsgBox("정품 등록 중 NAS 오류 발생!" & vbCrLf & ex.Message)
            Return False
        End Try
    End Function
End Module
