' =============================================
' Track it All Outlet Export Process
' Purpose: Weekly outlet sync to Track it All API
'          - Wednesday: run push; on failure set PendingRetry
'          - Thursday: retry if PendingRetry; on failure send email
'          - Data: mstCustomer only, full snapshot
' =============================================

Imports Superbowl_Daily_2.SystemFunctions
Imports Superbowl_Daily_2.ProjectFunctions
Imports Superbowl_Daily_2.db
Imports Superbowl_Daily_2.Export_Process
Imports Superbowl_Daily_2.ExcelExport
Imports Superbowl_Daily_2.TrackItAllAPIClient
Imports System.IO

Public Class TrackItAllOutletExport_Process : Inherits Export_Process

	' When True (Debug only): run with mode=preview; no Wednesday/Thursday gate, no PendingRetry
	Public Property PreviewOnly As Boolean = False

	' =============================================
	' Constructor
	' =============================================
	Sub New(ExportProcess As Export_Process)
		MyBase.New(ExportProcess.Name, ExportProcess.Filename, ExportProcess.Path, ExportProcess.SQL)
		Me.barProcess = ExportProcess.barProcess
	End Sub

	' =============================================
	' Override Run Method
	' =============================================
	Public Shadows Sub Run()
		Me.LogProcessStart()

		Try
			' Debug=False: always sync; Debug=True and PreviewOnly=True: preview only (no day gate, no PendingRetry)
			Dim usePreviewMode As Boolean = My.Settings.Debug AndAlso PreviewOnly
			Dim mode As String = If(usePreviewMode, "preview", "sync")

			' Wednesday/Thursday and PendingRetry apply only to sync (production) runs
			If Not usePreviewMode Then
				Dim today As DayOfWeek = DateTime.Now.DayOfWeek

				' Only run on Wednesday (attempt 1) or Thursday (attempt 2 if pending retry)
				If today <> DayOfWeek.Wednesday AndAlso today <> DayOfWeek.Thursday Then
					WriteLog("info", Me.Name, "Process", "Skipped - Track it All Outlet Sync runs only on Wednesday or Thursday")
					Me.LogProcessCompleted()
					Return
				End If

				' Thursday: only run if Wednesday failed (PendingRetry = 1)
				If today = DayOfWeek.Thursday Then
					Dim drState As DataRow = db.getRow("SELECT PendingRetry FROM sysTrackItAllOutletSyncState WHERE StateID = 1")
					If drState Is Nothing OrElse IsDBNull(drState("PendingRetry")) OrElse drState("PendingRetry") = 0 Then
						WriteLog("info", Me.Name, "Process", "Thursday run skipped - no pending retry")
						Me.LogProcessCompleted()
						Return
					End If
				End If
			Else
				WriteLog("info", Me.Name, "Process", "Running in Preview mode (Debug) - no commit")
			End If

			Dim isAttempt2 As Boolean = (Not usePreviewMode AndAlso DateTime.Now.DayOfWeek = DayOfWeek.Thursday)

			' Query outlet data (full snapshot from mstCustomer)
			Dim ds As DataSet = GetOutletData()
			Me.intRecordsTotal = ds.Tables(0).Rows.Count

			If Me.intRecordsTotal = 0 Then
				WriteLog("info", Me.Name, "Process", "No active customers to export")
				If Not usePreviewMode Then ClearPendingRetry()
				Me.LogProcessCompleted()
				Return
			End If

			Me.setProgress()

			' Generate XLSX file
			Dim xlsxFile As String = My.Settings.dirExports & Me.Filename
			If Not GenerateXLSXFile(ds, xlsxFile) Then
				WriteLog("error", Me.Name, "Process", "Failed to generate XLSX file")
				If usePreviewMode Then
					' Preview: no PendingRetry
				Else
					If isAttempt2 Then
						ClearPendingRetry()
						ProjectFunctions.SendTrackItAllFailureNotification("Failed to generate XLSX file")
					Else
						SetPendingRetry("Failed to generate XLSX file")
					End If
				End If
				Me.LogProcessCompleted()
				Return
			End If

			' Upload to Track it All API (preview or sync)
			Dim apiClient As New TrackItAllAPIClient(Me.Name)
			Dim result As TrackItAllUploadResult = apiClient.UploadOutletsFile(xlsxFile, mode)

			If result.Success Then
				If usePreviewMode Then
					WriteLog("info", Me.Name, "Process", "Track it All Preview completed: " & Me.intRecordsTotal & " records")
					If Not String.IsNullOrEmpty(result.ResponseBody) Then
						WriteLog("info", Me.Name, "Preview Response", result.ResponseBody)
						Try
							Dim previewFile As String = My.Settings.dirExports & "TrackItAllPreviewResult.json"
							File.WriteAllText(previewFile, result.ResponseBody)
							WriteLog("info", Me.Name, "Preview Response", "Saved to " & previewFile)
						Catch exFile As Exception
							WriteLog("warning", Me.Name, "Preview Response", "Could not save file: " & exFile.Message)
						End Try
					End If
				Else
					ClearPendingRetry()
					WriteLog("info", Me.Name, "Process", "Track it All Outlet Sync completed successfully: " & Me.intRecordsTotal & " records")
				End If
			Else
				If usePreviewMode Then
					WriteLog("error", Me.Name, "Process", "Preview failed (no retry): " & result.ErrorMessage)
				Else
					If isAttempt2 Then
						ClearPendingRetry()
						ProjectFunctions.SendTrackItAllFailureNotification(result.ErrorMessage)
						WriteLog("error", Me.Name, "Process", "Second attempt failed - failure notification sent: " & result.ErrorMessage)
					Else
						SetPendingRetry(result.ErrorMessage)
						WriteLog("error", Me.Name, "Process", "Push failed - pending retry Thursday: " & result.ErrorMessage)
					End If
				End If
			End If

		Catch ex As Exception
			WriteLog("error", Me.Name, "Process Exception", ex.Message & " :: " & ex.StackTrace)
			Dim usePreviewMode As Boolean = My.Settings.Debug AndAlso PreviewOnly
			If Not usePreviewMode Then
				Dim isAttempt2 As Boolean = (DateTime.Now.DayOfWeek = DayOfWeek.Thursday)
				If isAttempt2 Then
					ClearPendingRetry()
					ProjectFunctions.SendTrackItAllFailureNotification(ex.Message)
				Else
					SetPendingRetry(ex.Message)
				End If
			End If
		Finally
			Me.LogProcessCompleted()
		End Try
	End Sub

	' =============================================
	' Get Outlet Data - mstCustomer with joins
	' Columns match Track it All API: Cust nr, Customer, SB Region, SB Sales Force, strRepEmail, Sales Manager, strEmail, Superbowl Cust, Channel, Segment, strKeyAccount, strSnellAreaName
	' =============================================
	Private Function GetOutletData() As DataSet
		Dim sql As String = "SELECT " &
				"c.strCustomerNo AS [Cust nr], " &
				"ISNULL(c.strCustomerName, '') AS [Customer], " &
				"ISNULL(b.strRegionDesc2, '') AS [SB Region], " &
				"ISNULL(r.strRepName, '-') AS [SB Sales Force], " &
				"ISNULL(r.strRepEmail, 'n/a') AS [strRepEmail], " &
				"ISNULL(u.strUserName, '-') AS [Sales Manager], " &
				"ISNULL(u.strEmail, '') AS [strEmail], " &
				"1 AS [Superbowl Cust], " &
				"ISNULL(RTRIM(ISNULL(cs.strSegmentPrimary, '') + ' ' + ISNULL(cs.strSegment, '')), '') AS [Channel], " &
				"ISNULL(RTRIM(ISNULL(cs.strChannelPrimary, '') + ' ' + ISNULL(cs.strChannel, '')), '') AS [Segment], " &
				"ISNULL(k.strKeyAccount, '-') AS [strKeyAccount], " &
				"ISNULL(s.strSnellAreaName, '') AS [strSnellAreaName] " &
				"FROM mstCustomer c " &
				"LEFT JOIN mstRep r ON c.refRepID = r.RepID " &
				"LEFT JOIN mstUser u ON r.refSalesManagerID = u.UserID " &
				"LEFT JOIN mstBranch b ON c.refBranchID = b.BranchID " &
				"LEFT JOIN mstKeyAccount_Group kg ON c.refKeyAccount_GroupID = kg.KeyAccount_GroupID " &
				"LEFT JOIN mstKeyAccount k ON kg.refKeyAccountID = k.KeyAccountID " &
				"LEFT JOIN mstChannelSegment cs ON c.refChannelSegmentID = cs.ChannelSegmentID " &
				"LEFT JOIN mstSnellArea s ON c.strSnellArea = s.SnellAreaCode " &
				"WHERE c.blnActive = 1 " &
				"ORDER BY c.strCustomerNo"
		Return db.doQuery(sql)
	End Function

	' =============================================
	' Generate XLSX File
	' =============================================
	Private Function GenerateXLSXFile(ds As DataSet, filePath As String) As Boolean
		Try
			WriteLog("info", Me.Name, "Generate XLSX", "Generating XLSX file: " & filePath)

			Dim excelExport As New ExcelExport(ds.Tables(0), filePath, Me, Me.Name)
			excelExport.Execute()

			If excelExport.blnError Then
				WriteLog("error", Me.Name, "Generate XLSX", "Failed: " & excelExport.Message)
				Return False
			Else
				WriteLog("info", Me.Name, "Generate XLSX", "Success: " & excelExport.intRecordsExported & " records exported")
				Return True
			End If

		Catch ex As Exception
			WriteLog("error", Me.Name, "Generate XLSX Exception", ex.Message & " :: " & ex.StackTrace)
			Return False
		End Try
	End Function

	' =============================================
	' Set Pending Retry (Wednesday failed)
	' =============================================
	Private Sub SetPendingRetry(errorMessage As String)
		Try
			Dim sql As String = "UPDATE sysTrackItAllOutletSyncState SET PendingRetry = 1, LastRunDate = GETDATE(), LastError = '" & db.CleanString(errorMessage) & "', dtLastEdit = GETDATE() WHERE StateID = 1"
			db.doQuery(sql)
			WriteLog("info", Me.Name, "State", "PendingRetry set - will retry Thursday")
		Catch ex As Exception
			WriteLog("error", Me.Name, "SetPendingRetry Exception", ex.Message)
		End Try
	End Sub

	' =============================================
	' Clear Pending Retry (success or after sending failure email)
	' =============================================
	Private Sub ClearPendingRetry()
		Try
			Dim sql As String = "UPDATE sysTrackItAllOutletSyncState SET PendingRetry = 0, LastError = NULL, dtLastEdit = GETDATE() WHERE StateID = 1"
			db.doQuery(sql)
		Catch ex As Exception
			WriteLog("error", Me.Name, "ClearPendingRetry Exception", ex.Message)
		End Try
	End Sub

End Class
