Imports System.Text
Imports UTS_Core.UTSModule
Imports UTS_Core.UTSModule.Station
Imports UTS_Core.UTSModule.Test

Public Class FrmMain
    Implements IProcessStation
    Implements IProductionLine

    Private _utsApp As UtsAppForm

    Private _txtList As New List(Of TextBox)

    ''' <summary>
    ''' 条码总数
    ''' </summary>
    Private _barCodeCount As Integer

    ''' <summary>
    ''' 测试总数
    ''' </summary>
    Private _testCount As Integer = 0
    ''' <summary>
    ''' 测试成功总数
    ''' </summary>
    Private _testFailCount As Integer = 0
    ''' <summary>
    ''' 测试失败总数
    ''' </summary>
    Private _testPassCount As Integer = 0


    Public Sub ProductionLineChanged() Implements IProductionLine.ProductionLineChanged
        TssLblProductionLine.Text = CboProductionLines.Text

        My.Settings.ProductionLine = CboProductionLines.Text
    End Sub

    Public Sub StationChanged() Implements IProcessStation.StationChanged
        My.Settings.Project = _utsApp.ProcessStation.ParentProject.Name
        My.Settings.ProcessStation = _utsApp.ProcessStation.Name

        UpdateStation(_utsApp.ProcessStation.ParentProject.Name, _utsApp.ProcessStation.Name)

    End Sub

    Public Sub UpdateStation(projectName As String, stationName As String)
        If String.IsNullOrWhiteSpace(projectName) OrElse
           String.IsNullOrWhiteSpace(stationName) Then
            TssLblStaion.Text = $"Invalid Station"
        Else
            TssLblStaion.Text = $"{projectName} - {stationName}"
            lab_ModelName.Text = $"{projectName} - {stationName}"
        End If
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        '自动保存设置
        My.Application.SaveMySettingsOnExit = True

        '初始化UTS窗体信息,失败则关闭窗体
        If InitializeUtsApp() = False Then Return

        '初始化界面信息 
        InitializeForm()

    End Sub

    Private Function InitializeUtsApp() As Boolean
        _utsApp = UtsAppForm.CreateSingleton()

        Try
            If _utsApp.IsInitialized = False Then
                _utsApp.AddStatisticsObserver(Me)
                _utsApp.Initialize(ProcessStation.StationTypeEnum.Assem)
                _utsApp.LoadStation(My.Settings.Project, My.Settings.ProcessStation)
            End If
        Catch ex As Exception
            MsgBox($"Initialize UtsForm Error:{ex.Message}")
            Close()
            Return False
        End Try

        Return True
    End Function

    Private Sub InitializeForm()
        '初始化产线信息
        CboProductionLines.Items.Clear()
        CboProductionLines.Items.AddRange(_utsApp.ProductionLines.GetLineNames())
        CboProductionLines.SelectedIndex = CboProductionLines.Items.IndexOf(My.Settings.ProductionLine)

        _txtList.Clear()
        _txtList.Add(TxtFirstRecord)
        _txtList.Add(TxtSecondRecord)
        _txtList.Add(TxtThirdRecord)
        _txtList.Add(TxtFourthRecord)
        _txtList.Add(TxtFifthRecord)

        RtxLog.Clear()

        _barCodeCount = My.Settings.BarCount
        If _barCodeCount < 1 Then _barCodeCount = 1
        If _barCodeCount > 4 Then _barCodeCount = 4
        Select Case _barCodeCount
            Case 1
                RadSingle.Checked = True
            Case 2
                RadTwo.Checked = True
            Case 3
                RadThree.Checked = True
            Case 4
                RadFour.Checked = True
        End Select

        Text = $"{Application.ProductName} {Application.ProductVersion}  User:{_utsApp.Account.UserName}"
    End Sub

    Private Sub CboProductionLines_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CboProductionLines.SelectedIndexChanged
        ProductionLineChanged()
    End Sub

    Private Sub BtnOpenProject_Click(sender As Object, e As EventArgs) Handles BtnOpenProject.Click
        Try
            _utsApp.ChangeStation()
        Catch ex As Exception
            MsgBox($"ChangeStation Error:{ex.Message}")
        End Try
    End Sub


    Private Sub Tb_FirstRecord_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtFirstRecord.KeyDown
        If e.KeyCode = Keys.Enter Then

            e.SuppressKeyPress = True
            e.Handled = True

            TxtSecondRecord.Focus()
            TxtSecondRecord.SelectAll()
        End If
    End Sub

    Private Sub Tb_SecondRecord_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtSecondRecord.KeyDown
        If e.KeyCode <> Keys.Enter Then Return

        e.SuppressKeyPress = True
        e.Handled = True

        If _barCodeCount > 1 Then
            TxtThirdRecord.Focus()
            TxtThirdRecord.SelectAll()
        Else
            '此处为单个条码对应的执行逻辑
            SaveTestResult()
        End If
    End Sub


    Private Sub TxtThirdRecord_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtThirdRecord.KeyDown
        If e.KeyCode <> Keys.Enter Then Return

        e.SuppressKeyPress = True
        e.Handled = True

        If _barCodeCount > 2 Then
            TxtFourthRecord.Focus()
            TxtFourthRecord.SelectAll()
        Else
            SaveTestResult()
        End If
    End Sub


    Private Sub TxtFourthRecord_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtFourthRecord.KeyDown
        If e.KeyCode <> Keys.Enter Then Return

        e.SuppressKeyPress = True
        e.Handled = True

        If _barCodeCount > 3 Then
            TxtFifthRecord.Focus()
            TxtFifthRecord.SelectAll()
        Else
            SaveTestResult()
        End If
    End Sub

    Private Sub TxtFifthRecord_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtFifthRecord.KeyDown
        If e.KeyCode <> Keys.Enter Then Return

        e.SuppressKeyPress = True
        e.Handled = True

        If _barCodeCount > 4 Then
            MsgBox("条码达到上限,请重新选择条码数")
        Else
            SaveTestResult()
        End If
    End Sub

    Private Sub BtnStartProgramming_Click(sender As Object, e As EventArgs) Handles BtnStartProgramming.Click
        SaveTestResult()
    End Sub


    Private Sub SaveTestResult()
        If _utsApp.ProcessStation Is Nothing Then
            MsgBox($"请选择项目与测试站后再尝试录入！")
            Return
        End If

        If String.IsNullOrWhiteSpace(CboProductionLines.Text) Then
            MsgBox($"请选择生产线后再尝试录入！")
            Return
        End If

        If String.IsNullOrWhiteSpace(TxtFirstRecord.Text) Then
            MsgBox($"请输入成品序号！")
            TxtFirstRecord.Focus()
            Return
        End If

        Dim snMain As String = TxtFirstRecord.Text
        Dim sb As New StringBuilder
        Dim snLst As New List(Of String)
        snLst.Add(TxtFirstRecord.Text)

        For i As Integer = 1 To _barCodeCount
            If String.IsNullOrWhiteSpace(_txtList(i).Text) Then
                MsgBox($"请输入第 [{i}] 个其他序号！")
                _txtList(i).Focus()
                Return
            Else
                If snLst.Contains(_txtList(i).Text) Then
                    MsgBox($"第 [{i}] 个序号 [{_txtList(i).Text}] 与已有序号重复,请重新输入！")
                    _txtList(i).SelectAll()
                    _txtList(i).Focus()
                    Return
                Else
                    snLst.Add(_txtList(i).Text)
                    sb.Append($"{_txtList(i).Text},")
                End If
            End If
        Next

        Dim assemblyString As String = sb.ToString()

        If assemblyString.Length >= 128 Then
            MsgBox($"整机序号超过128个字符,无法录入,请联系管理员！")
            Return
        End If

        assemblyString = assemblyString.Replace("，"c, ",")
        If assemblyString.EndsWith(","c) OrElse assemblyString.EndsWith("，"c) Then
            assemblyString = assemblyString.Substring(0, assemblyString.Length - 1)
        End If

        Dim saveDb As Boolean
        Try
            FillTestResult(snMain, assemblyString)
            _utsApp.CommitTestResult(uniqueRecord:=True)

            DbConnect.DbConnector.SaveOtherSn(snLst, _utsApp.ProcessStation, _utsApp.TestResult)

            saveDb = True
        Catch ex As Exception
            MsgBox($"测试结果录入失败：{ex.Message}")
            saveDb = False
        End Try

        Static inputCount As Integer = 0
        inputCount += 1 : If inputCount > 9999 Then inputCount = 0
        RtxLog.SelectionStart = 0
        RtxLog.SelectionLength = RtxLog.TextLength
        RtxLog.SelectionColor = Color.Gray

        If saveDb Then
            lab_Result.ForeColor = Color.Green
            lab_Result.Text = $"{snMain}-Pass"

            RtxLog.SelectionStart = RtxLog.TextLength
            RtxLog.SelectionColor = Color.Green
            AppendRecord($"{inputCount:D4}.BarcodeSn:{snMain},AssemblySn:{assemblyString},录入成功！")
            _testPassCount += 1
        Else
            lab_Result.ForeColor = Color.Red
            lab_Result.Text = $"{snMain}-Fail"

            RtxLog.SelectionStart = RtxLog.TextLength
            RtxLog.SelectionColor = Color.Red
            AppendRecord($"{inputCount:D4}.BarcodeSn:{snMain},AssemblySn:{assemblyString},录入失败！")
            _testFailCount += 1
        End If

        _testCount += 1

        TssLblPassCount.Text = "Pass:" & _testPassCount.ToString
        TssLblFailCount.Text = "Fail:" & _testFailCount.ToString
        TsLblCheckSum.Text = "Sum:" & _testCount.ToString
        TssLblYield.Text = "Yield:" & (_testPassCount / _testCount * 100).ToString("F2") & "%"

        TxtFirstRecord.Focus()
        TxtFirstRecord.SelectAll()
    End Sub

    Public Sub AppendRecord(logString As String)
        If RtxLog.InvokeRequired Then '判断是否需要开委托
            RtxLog.Invoke(New Action(Of String)(AddressOf AppendRecord), New Object() {logString})
            Return
        End If

        With RtxLog
            If .Lines.Length > 256 Then '超过上限则移除最初行内容
                .ReadOnly = False
                .SelectionStart = 0
                .SelectionLength = .GetFirstCharIndexFromLine(1)
                .SelectedText = String.Empty
                .ReadOnly = True
                .SelectionStart = .TextLength
            End If

            .AppendText($"{Now:yyyy:MM:dd HH:mm:ss} - {logString}{vbNewLine}")

            .ScrollToCaret()
        End With
    End Sub

    ''' <summary>
    ''' 填充测试记录内容，每个应用程序这个部分有所差异
    ''' </summary>
    Public Sub FillTestResult(barcodeString As String, assemblyString As String)
        _utsApp.TestResult.ResetTestResult()

        '产线索引
        Dim lineID As Integer = _utsApp.ProductionLines(CboProductionLines.Text).ID
        _utsApp.TestResult.ProductionLineID = lineID


        '测试开始时间
        _utsApp.TestResult.StartTime = Now
        _utsApp.TestResult.DUT_SN = barcodeString
        _utsApp.TestResult.TestResult = TestResult.TestResultEnum.Pass

        '自定义字段
        _utsApp.TestResult.AddCustomRecord("AssemblySn", $"{assemblyString}")
    End Sub




    Private Sub RadSingle_CheckedChanged(sender As Object, e As EventArgs) Handles RadTwo.CheckedChanged, RadThree.CheckedChanged, RadSingle.CheckedChanged, RadFour.CheckedChanged
        Dim rad As RadioButton = CType(sender, RadioButton)
        If rad.Checked Then
            _barCodeCount = CInt(rad.Tag)
            My.Settings.BarCount = _barCodeCount

            Select Case _barCodeCount
                Case 1
                    TxtSecondRecord.Visible = True
                    TxtThirdRecord.Visible = False
                    TxtFourthRecord.Visible = False
                    TxtFifthRecord.Visible = False
                Case 2
                    TxtSecondRecord.Visible = True
                    TxtThirdRecord.Visible = True
                    TxtFourthRecord.Visible = False
                    TxtFifthRecord.Visible = False
                Case 3
                    TxtSecondRecord.Visible = True
                    TxtThirdRecord.Visible = True
                    TxtFourthRecord.Visible = True
                    TxtFifthRecord.Visible = False
                Case 4
                    TxtSecondRecord.Visible = True
                    TxtThirdRecord.Visible = True
                    TxtFourthRecord.Visible = True
                    TxtFifthRecord.Visible = True
            End Select

        End If
    End Sub
End Class