<%@ Language=VBScript %>
<%
Option Explicit
Response.Expires = -1
Response.ExpiresAbsolute = Now() - 1
Response.AddHeader "pragma", "no-cache"
Response.AddHeader "cache-control", "private, no-cache, must-revalidate"
'=============================================================================
' FILE: displayudc.asp
' PURPOSE: UDC (Universal Data Collector) Management Dashboard
' SECURITY: Parameterized queries, HTML encoding, input validation
' CREATED: 2025-12-12
'=============================================================================
Dim theme, strSQL, rs, objConn
%>
<!DOCTYPE html>
<html lang="en">
<head>
  <!--#include file="./includes/header.asp"-->
  <!--#include file="./includes/sql.asp"-->
  <title>UDC Dashboard - ShopDB</title>
</head>

<%
    theme = Request.Cookies("theme")
    If theme = "" Then theme = "bg-theme1"

    ' Get filter parameters
    Dim filterMachine, filterBadge, filterPart, filterStart, filterEnd, periodFilter, filterBU
    filterMachine = Trim(Request.QueryString("machine") & "")
    filterBadge = Trim(Request.QueryString("badge") & "")
    filterPart = Trim(Request.QueryString("part") & "")
    filterStart = Trim(Request.QueryString("startdate") & "")
    filterEnd = Trim(Request.QueryString("enddate") & "")
    periodFilter = Trim(Request.QueryString("period") & "")
    filterBU = Trim(Request.QueryString("bu") & "")

    ' Tab persistence
    Dim activeTab
    activeTab = Trim(Request.QueryString("tab") & "")
    If activeTab = "" Then activeTab = "dashboard"

    ' Shift-span filter for manual response times
    Dim excludeShiftSpan, shiftFilter
    excludeShiftSpan = (Request.QueryString("excludeshift") = "1")
    shiftFilter = ""
    If excludeShiftSpan Then
        shiftFilter = " AND mr.responseseconds < 1800"
    End If

    ' Default date range: last 30 days
    If filterStart = "" Then filterStart = Year(DateAdd("d", -30, Date())) & "-" & Right("0" & Month(DateAdd("d", -30, Date())), 2) & "-" & Right("0" & Day(DateAdd("d", -30, Date())), 2)
    If filterEnd = "" Then filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)

    ' Period shortcuts
    Dim periodLabel, tempDate
    If periodFilter = "today" Then
        filterStart = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        filterEnd = filterStart
        periodLabel = "Today"
    ElseIf periodFilter = "yesterday" Then
        tempDate = DateAdd("d", -1, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = filterStart
        periodLabel = "Yesterday"
    ElseIf periodFilter = "7days" Then
        tempDate = DateAdd("d", -6, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "Last 7 Days"
    ElseIf periodFilter = "14days" Then
        tempDate = DateAdd("d", -13, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "Last 14 Days"
    ElseIf periodFilter = "30days" Then
        tempDate = DateAdd("d", -29, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "Last 30 Days"
    ElseIf periodFilter = "90days" Then
        tempDate = DateAdd("d", -89, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "Last 90 Days"
    ElseIf periodFilter = "week" Then
        tempDate = DateAdd("d", -7, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "This Week"
    ElseIf periodFilter = "month" Then
        tempDate = DateAdd("d", -30, Date())
        filterStart = Year(tempDate) & "-" & Right("0" & Month(tempDate), 2) & "-" & Right("0" & Day(tempDate), 2)
        filterEnd = Year(Date()) & "-" & Right("0" & Month(Date()), 2) & "-" & Right("0" & Day(Date()), 2)
        periodLabel = "This Month"
    Else
        periodLabel = "Custom Range"
    End If
%>
<style>
/* Share toast notification */
#shareToast {
  position: fixed;
  top: 80px;
  right: 20px;
  z-index: 9999;
  min-width: 300px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 15px 20px;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
  display: none;
}
@keyframes toastSlideIn {
  from { transform: translateX(100%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
@keyframes toastSlideOut {
  from { transform: translateX(0); opacity: 1; }
  to { transform: translateX(100%); opacity: 0; }
}
</style>
<body class="bg-theme <%=Server.HTMLEncode(theme)%>">

<!-- Share toast notification -->
<div id="shareToast">
  <div style="display: flex; align-items: center;">
    <i class="zmdi zmdi-check-circle" style="font-size: 24px; margin-right: 12px;"></i>
    <div>
      <strong style="display: block; margin-bottom: 5px;">Link Copied!</strong>
      <span style="font-size: 13px; opacity: 0.9;">This link will show the search term and highlight the result</span>
    </div>
  </div>
</div>

<!-- start loader -->
<div id="pageloader-overlay" class="visible incoming"><div class="loader-wrapper-outer"><div class="loader-wrapper-inner"><div class="loader"></div></div></div></div>

<div id="wrapper">
  <!--#include file="./includes/leftsidebar.asp"-->
  <!--#include file="./includes/topbarheader.asp"-->
<div class="clearfix"></div>

<div class="content-wrapper">
  <div class="container-fluid">

    <!-- Page Header -->
    <div class="row mt-3">
      <div class="col-12">
        <div class="card">
          <div class="card-header" style="background: linear-gradient(45deg, #667eea 0%, #764ba2 100%); color: white;">
            <h5 class="mb-0">UDC Performance Dashboard</h5>
          </div>
          <div class="card-body">
            <!-- Filter Controls -->
            <form id="udcFilterForm" method="get" class="mb-0">
              <div class="row">
                <div class="col-md-2">
                  <label class="small">Quick Range</label>
                  <select name="period" class="form-control form-control-sm" onchange="this.form.submit()">
                    <option value="">Custom</option>
                    <option value="today" <%If periodFilter="today" Then Response.Write("selected")%>>Today</option>
                    <option value="yesterday" <%If periodFilter="yesterday" Then Response.Write("selected")%>>Yesterday</option>
                    <option value="7days" <%If periodFilter="7days" Then Response.Write("selected")%>>Last 7 Days</option>
                    <option value="14days" <%If periodFilter="14days" Then Response.Write("selected")%>>Last 14 Days</option>
                    <option value="30days" <%If periodFilter="30days" Then Response.Write("selected")%>>Last 30 Days</option>
                    <option value="90days" <%If periodFilter="90days" Then Response.Write("selected")%>>Last 90 Days</option>
                  </select>
                </div>
                <div class="col-md-2">
                  <label class="small">Start Date</label>
                  <input type="date" name="startdate" class="form-control form-control-sm" value="<%=Server.HTMLEncode(filterStart)%>">
                </div>
                <div class="col-md-2">
                  <label class="small">End Date</label>
                  <input type="date" name="enddate" class="form-control form-control-sm" value="<%=Server.HTMLEncode(filterEnd)%>">
                </div>
                <div class="col-md-2">
                  <label class="small">Business Unit</label>
                  <select name="bu" id="buFilter" class="form-control form-control-sm" onchange="this.form.submit()">
                    <option value="">All BUs</option>
<%
' Get list of business units with UDC machines
Dim rsBUs
Set rsBUs = objConn.Execute("SELECT DISTINCT b.businessunitid, b.businessunit FROM businessunits b " & _
    "JOIN machines m ON m.businessunitid = b.businessunitid " & _
    "JOIN udcsessions s ON m.machinenumber = s.machinenumber " & _
    "ORDER BY b.businessunit")
Do While Not rsBUs.EOF
    Response.Write("<option value=""" & Server.HTMLEncode(rsBUs("businessunitid") & "") & """")
    If filterBU = rsBUs("businessunitid") & "" Then Response.Write(" selected")
    Response.Write(">" & Server.HTMLEncode(rsBUs("businessunit") & "") & "</option>")
    rsBUs.MoveNext
Loop
rsBUs.Close
Set rsBUs = Nothing
%>
                  </select>
                </div>
                <div class="col-md-2">
                  <label class="small">Machine</label>
                  <select name="machine" class="form-control form-control-sm">
                    <option value="">All Machines</option>
<%
' Get list of machines with UDC data, filtered by BU if selected
Dim rsMachines, machineSQL
machineSQL = "SELECT DISTINCT s.machinenumber FROM udcsessions s " & _
    "JOIN machines m ON m.machinenumber = s.machinenumber "
If filterBU <> "" Then
    machineSQL = machineSQL & "WHERE m.businessunitid = " & CLng(filterBU) & " "
End If
machineSQL = machineSQL & "ORDER BY s.machinenumber"
Set rsMachines = objConn.Execute(machineSQL)
Do While Not rsMachines.EOF
    Response.Write("<option value=""" & Server.HTMLEncode(rsMachines("machinenumber") & "") & """")
    If filterMachine = rsMachines("machinenumber") & "" Then Response.Write(" selected")
    Response.Write(">" & Server.HTMLEncode(rsMachines("machinenumber") & "") & "</option>")
    rsMachines.MoveNext
Loop
rsMachines.Close
Set rsMachines = Nothing
%>
                  </select>
                </div>
                <div class="col-md-2">
                  <label class="small">Operator Badge</label>
                  <select name="badge" class="form-control form-control-sm">
                    <option value="">All Operators</option>
<%
' Get list of operators
Dim rsBadges
Set rsBadges = objConn.Execute("SELECT DISTINCT badgenumber FROM udcparts WHERE badgenumber IS NOT NULL AND badgenumber != '' ORDER BY badgenumber")
Do While Not rsBadges.EOF
    Response.Write("<option value=""" & Server.HTMLEncode(rsBadges("badgenumber") & "") & """")
    If filterBadge = rsBadges("badgenumber") & "" Then Response.Write(" selected")
    Response.Write(">" & Server.HTMLEncode(rsBadges("badgenumber") & "") & "</option>")
    rsBadges.MoveNext
Loop
rsBadges.Close
Set rsBadges = Nothing
%>
                  </select>
                </div>
              </div>
              <div class="row mt-2">
                <div class="col-6">
                  <div class="form-check form-check-inline">
                    <input type="checkbox" class="form-check-input" id="excludeshift" name="excludeshift" value="1" <%If excludeShiftSpan Then Response.Write("checked")%>>
                    <label class="form-check-label small" for="excludeshift">Exclude idle time (removes responses over 30 min)</label>
                  </div>
                </div>
                <div class="col-6 text-right">
                  <button type="submit" class="btn btn-primary btn-sm mr-2">Filter</button>
                  <a href="displayudc.asp" class="btn btn-secondary btn-sm mr-2">Clear</a>
                  <button type="button" class="btn btn-outline-info btn-sm" onclick="copyFilterLink(this)" title="Copy a shareable link with your current filters">Share This View</button>
                </div>
              </div>
              <input type="hidden" name="tab" id="activeTabInput" value="<%=Server.HTMLEncode(activeTab)%>">
            </form>
          </div>
        </div>
      </div>
    </div>

    <!-- Summary Cards Row -->
<%
' Build WHERE clause for filters
Dim whereClause
whereClause = " WHERE p.programstart >= '" & Replace(filterStart, "'", "''") & "' " & _
              " AND p.programstart <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"

If filterMachine <> "" Then
    whereClause = whereClause & " AND s.machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    whereClause = whereClause & " AND s.machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If
If filterBadge <> "" Then
    whereClause = whereClause & " AND p.badgenumber = '" & Replace(filterBadge, "'", "''") & "'"
End If
If filterPart <> "" Then
    whereClause = whereClause & " AND p.partnumber LIKE '%" & Replace(filterPart, "'", "''") & "%'"
End If

' Get summary statistics
Dim rsSummary, totalParts, totalOOT, partsWithOOT, avgCycleTime, avgManualTime, ootRate, strSQL2, ootCardClass
strSQL2 = "SELECT COUNT(*) as totalparts, " & _
         "SUM(ootcount) as totaloot, " & _
         "SUM(CASE WHEN ootcount > 0 THEN 1 ELSE 0 END) as partswithoot, " & _
         "AVG(cycletime) as avgcycle, " & _
         "SUM(manualcount) as totalmanual " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & whereClause

Set rsSummary = objConn.Execute(strSQL2)
If Not rsSummary.EOF Then
    If IsNull(rsSummary("totalparts")) Then totalParts = 0 Else totalParts = CLng(rsSummary("totalparts"))
    If IsNull(rsSummary("totaloot")) Then totalOOT = 0 Else totalOOT = CLng(rsSummary("totaloot"))
    If IsNull(rsSummary("partswithoot")) Then partsWithOOT = 0 Else partsWithOOT = CLng(rsSummary("partswithoot"))
    If Not IsNull(rsSummary("avgcycle")) Then
        avgCycleTime = FormatNumber(CDbl(rsSummary("avgcycle")) / 60, 1)
    Else
        avgCycleTime = "0"
    End If
    If totalParts > 0 Then
        ootRate = FormatNumber(CDbl(partsWithOOT) / CDbl(totalParts) * 100, 1)
    Else
        ootRate = "0"
    End If
Else
    totalParts = 0
    totalOOT = 0
    partsWithOOT = 0
    avgCycleTime = "0"
    ootRate = "0"
End If
rsSummary.Close
Set rsSummary = Nothing

' Get avg manual response time
Dim rsManual, avgManualResp
strSQL2 = "SELECT AVG(mr.responseseconds) as avgresponse " & _
         "FROM udcmanualrequests mr " & _
         "JOIN udcparts p ON mr.partrunid = p.partrunid " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & whereClause & shiftFilter
Set rsManual = objConn.Execute(strSQL2)
If Not rsManual.EOF And Not IsNull(rsManual("avgresponse")) Then
    avgManualResp = FormatNumber(CDbl(rsManual("avgresponse")), 0)
Else
    avgManualResp = "0"
End If
rsManual.Close
Set rsManual = Nothing

%>

    <!-- Summary Cards -->
    <div class="row mt-3">
      <div class="col-lg-3 col-md-6">
        <div class="card bg-success text-white">
          <div class="card-body">
            <div class="d-flex align-items-center">
              <div class="media-body">
                <h4 class="mb-0"><%=totalParts%></h4>
                <span>Total Parts Produced</span>
              </div>
                          </div>
          </div>
        </div>
      </div>
      <div class="col-lg-3 col-md-6">
        <div class="card bg-info text-white">
          <div class="card-body">
            <div class="d-flex align-items-center">
              <div class="media-body">
                <h4 class="mb-0"><%=avgCycleTime%>m</h4>
                <span>Avg Cycle Time</span>
              </div>
                          </div>
          </div>
        </div>
      </div>
      <div class="col-lg-3 col-md-6">
        <%
        If CDbl(ootRate) > 5 Then
            ootCardClass = "bg-danger"
        ElseIf CDbl(ootRate) > 0 Then
            ootCardClass = "bg-warning"
        Else
            ootCardClass = "bg-success"
        End If
        %>
        <div class="card <%=ootCardClass%> text-white">
          <div class="card-body">
            <div class="d-flex align-items-center">
              <div class="media-body">
                <h4 class="mb-0"><%=ootRate%>%</h4>
                <span>Parts with OOT (<%=partsWithOOT%> of <%=totalParts%>)</span>
              </div>
                          </div>
          </div>
        </div>
      </div>
      <div class="col-lg-3 col-md-6">
        <div class="card bg-primary text-white">
          <div class="card-body">
            <div class="d-flex align-items-center">
              <div class="media-body">
                <h4 class="mb-0"><%=avgManualResp%>s</h4>
                <span>Avg Manual Response</span>
              </div>
                          </div>
          </div>
        </div>
      </div>
    </div>

<%
' ============================================================================
' DASHBOARD CHARTS DATA QUERIES
' ============================================================================

' Chart 1: Production Trend (daily parts for date range)
Dim rsProductionTrend, prodLabels, prodData, prodDate
prodLabels = ""
prodData = ""
strSQL2 = "SELECT DATE_FORMAT(DATE(p.programstart), '%m/%d') as day_label, COUNT(*) as parts " & _
          "FROM udcparts p " & _
          "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
          whereClause & _
          " GROUP BY DATE(p.programstart) ORDER BY DATE(p.programstart) ASC"
Set rsProductionTrend = objConn.Execute(strSQL2)
Do While Not rsProductionTrend.EOF
    prodDate = rsProductionTrend("day_label") & ""
    If prodLabels <> "" Then prodLabels = prodLabels & ","
    If prodData <> "" Then prodData = prodData & ","
    prodLabels = prodLabels & """" & prodDate & """"
    prodData = prodData & rsProductionTrend("parts")
    rsProductionTrend.MoveNext
Loop
rsProductionTrend.Close
Set rsProductionTrend = Nothing
If prodLabels = "" Then prodLabels = """No Data"""
If prodData = "" Then prodData = "0"

' Chart 2: OOT Rate Trend (daily OOT rate for date range)
Dim rsOOTTrend, ootLabels, ootRateData, ootCountData, ootDay, dayRate
ootLabels = ""
ootRateData = ""
ootCountData = ""
strSQL2 = "SELECT DATE_FORMAT(DATE(p.programstart), '%m/%d') as day_label, " & _
          "SUM(p.ootcount) as oot_count, COUNT(*) as total_parts, " & _
          "ROUND(SUM(p.ootcount)*100.0/COUNT(*), 1) as oot_rate " & _
          "FROM udcparts p " & _
          "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
          whereClause & _
          " GROUP BY DATE(p.programstart) ORDER BY DATE(p.programstart) ASC"
Set rsOOTTrend = objConn.Execute(strSQL2)
Do While Not rsOOTTrend.EOF
    ootDay = rsOOTTrend("day_label") & ""
    If ootLabels <> "" Then ootLabels = ootLabels & ","
    If ootRateData <> "" Then ootRateData = ootRateData & ","
    If ootCountData <> "" Then ootCountData = ootCountData & ","
    ootLabels = ootLabels & """" & ootDay & """"
    If IsNull(rsOOTTrend("oot_rate")) Then
        dayRate = "0"
    Else
        dayRate = rsOOTTrend("oot_rate") & ""
    End If
    ootRateData = ootRateData & dayRate
    ootCountData = ootCountData & (rsOOTTrend("oot_count") & "0")
    rsOOTTrend.MoveNext
Loop
rsOOTTrend.Close
Set rsOOTTrend = Nothing
If ootLabels = "" Then ootLabels = """No Data"""
If ootRateData = "" Then ootRateData = "0"
If ootCountData = "" Then ootCountData = "0"

' Chart 3: Machine Utilization (top 10 by runtime hours)
Dim rsMachineUtil, machLabels, machData, machHours
machLabels = ""
machData = ""
strSQL2 = "SELECT s.machinenumber, ROUND(SUM(p.cycletime)/3600, 1) as runtime_hours " & _
          "FROM udcparts p " & _
          "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
          whereClause & _
          " AND p.cycletime IS NOT NULL AND p.cycletime > 0 " & _
          "GROUP BY s.machinenumber ORDER BY runtime_hours DESC LIMIT 10"
Set rsMachineUtil = objConn.Execute(strSQL2)
Do While Not rsMachineUtil.EOF
    If machLabels <> "" Then machLabels = machLabels & ","
    If machData <> "" Then machData = machData & ","
    machLabels = machLabels & """" & (rsMachineUtil("machinenumber") & "") & """"
    If IsNull(rsMachineUtil("runtime_hours")) Then
        machHours = "0"
    Else
        machHours = rsMachineUtil("runtime_hours") & ""
    End If
    machData = machData & machHours
    rsMachineUtil.MoveNext
Loop
rsMachineUtil.Close
Set rsMachineUtil = Nothing
If machLabels = "" Then machLabels = """No Data"""
If machData = "" Then machData = "0"

' Chart 4: Top Operators (top 10 by parts produced)
Dim rsTopOps, opLabels, opData
opLabels = ""
opData = ""
strSQL2 = "SELECT p.badgenumber, COUNT(*) as parts_count " & _
          "FROM udcparts p " & _
          "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
          whereClause & _
          " AND p.badgenumber IS NOT NULL AND p.badgenumber != '' " & _
          "GROUP BY p.badgenumber ORDER BY parts_count DESC LIMIT 10"
Set rsTopOps = objConn.Execute(strSQL2)
Do While Not rsTopOps.EOF
    If opLabels <> "" Then opLabels = opLabels & ","
    If opData <> "" Then opData = opData & ","
    opLabels = opLabels & """" & (rsTopOps("badgenumber") & "") & """"
    opData = opData & rsTopOps("parts_count")
    rsTopOps.MoveNext
Loop
rsTopOps.Close
Set rsTopOps = Nothing
If opLabels = "" Then opLabels = """No Data"""
If opData = "" Then opData = "0"

' ============================================================================
' HISTORICAL TRENDS DATA (from summary tables - survives 90-day purge)
' ============================================================================

' Monthly measurement trends (last 12 months)
Dim rsMonthlyMeas, monthlyLabels, monthlyMeasData, monthlyOOTData, monthlyOOTRate
monthlyLabels = ""
monthlyMeasData = ""
monthlyOOTData = ""
monthlyOOTRate = ""
strSQL2 = "SELECT yearmonth, SUM(measurement_count) as total_meas, SUM(oot_count) as total_oot, " & _
          "ROUND(SUM(oot_count)*100.0/NULLIF(SUM(measurement_count),0), 2) as oot_rate " & _
          "FROM vwudcmeasurements_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 12"
Set rsMonthlyMeas = objConn.Execute(strSQL2)
Dim monthlyArr(11,3), monthlyIdx
monthlyIdx = 0
Do While Not rsMonthlyMeas.EOF And monthlyIdx < 12
    monthlyArr(monthlyIdx, 0) = rsMonthlyMeas("yearmonth") & ""
    monthlyArr(monthlyIdx, 1) = rsMonthlyMeas("total_meas") & ""
    monthlyArr(monthlyIdx, 2) = rsMonthlyMeas("total_oot") & ""
    If IsNull(rsMonthlyMeas("oot_rate")) Then
        monthlyArr(monthlyIdx, 3) = "0"
    Else
        monthlyArr(monthlyIdx, 3) = rsMonthlyMeas("oot_rate") & ""
    End If
    monthlyIdx = monthlyIdx + 1
    rsMonthlyMeas.MoveNext
Loop
rsMonthlyMeas.Close
Set rsMonthlyMeas = Nothing
' Reverse order for chronological display
Dim mi
For mi = monthlyIdx - 1 To 0 Step -1
    If monthlyLabels <> "" Then monthlyLabels = monthlyLabels & ","
    If monthlyMeasData <> "" Then monthlyMeasData = monthlyMeasData & ","
    If monthlyOOTData <> "" Then monthlyOOTData = monthlyOOTData & ","
    If monthlyOOTRate <> "" Then monthlyOOTRate = monthlyOOTRate & ","
    monthlyLabels = monthlyLabels & """" & monthlyArr(mi, 0) & """"
    monthlyMeasData = monthlyMeasData & monthlyArr(mi, 1)
    monthlyOOTData = monthlyOOTData & monthlyArr(mi, 2)
    monthlyOOTRate = monthlyOOTRate & monthlyArr(mi, 3)
Next
If monthlyLabels = "" Then monthlyLabels = """No Data"""
If monthlyMeasData = "" Then monthlyMeasData = "0"
If monthlyOOTData = "" Then monthlyOOTData = "0"
If monthlyOOTRate = "" Then monthlyOOTRate = "0"

' Machine comparison from summaries (total measurements by machine, all time)
Dim rsMachHist, machHistLabels, machHistMeas, machHistOOT
machHistLabels = ""
machHistMeas = ""
machHistOOT = ""
strSQL2 = "SELECT machinenumber, SUM(measurement_count) as total_meas, SUM(oot_count) as total_oot " & _
          "FROM udcmeasurements_daily GROUP BY machinenumber ORDER BY total_meas DESC LIMIT 15"
Set rsMachHist = objConn.Execute(strSQL2)
Do While Not rsMachHist.EOF
    If machHistLabels <> "" Then machHistLabels = machHistLabels & ","
    If machHistMeas <> "" Then machHistMeas = machHistMeas & ","
    If machHistOOT <> "" Then machHistOOT = machHistOOT & ","
    machHistLabels = machHistLabels & """" & (rsMachHist("machinenumber") & "") & """"
    machHistMeas = machHistMeas & (rsMachHist("total_meas") & "")
    machHistOOT = machHistOOT & (rsMachHist("total_oot") & "")
    rsMachHist.MoveNext
Loop
rsMachHist.Close
Set rsMachHist = Nothing
If machHistLabels = "" Then machHistLabels = """No Data"""
If machHistMeas = "" Then machHistMeas = "0"
If machHistOOT = "" Then machHistOOT = "0"

' Weekly trends for the last 26 weeks
Dim rsWeeklyTrend, weeklyLabels, weeklyMeasData, weeklyOOTRate
weeklyLabels = ""
weeklyMeasData = ""
weeklyOOTRate = ""
strSQL2 = "SELECT week_start, SUM(measurement_count) as total_meas, " & _
          "ROUND(SUM(oot_count)*100.0/NULLIF(SUM(measurement_count),0), 2) as oot_rate " & _
          "FROM vwudcmeasurements_weekly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearweek, week_start ORDER BY week_start DESC LIMIT 26"
Set rsWeeklyTrend = objConn.Execute(strSQL2)
Dim weeklyArr(25,2), weeklyIdx
weeklyIdx = 0
Do While Not rsWeeklyTrend.EOF And weeklyIdx < 26
    weeklyArr(weeklyIdx, 0) = Month(rsWeeklyTrend("week_start")) & "/" & Day(rsWeeklyTrend("week_start"))
    weeklyArr(weeklyIdx, 1) = rsWeeklyTrend("total_meas") & ""
    If IsNull(rsWeeklyTrend("oot_rate")) Then
        weeklyArr(weeklyIdx, 2) = "0"
    Else
        weeklyArr(weeklyIdx, 2) = rsWeeklyTrend("oot_rate") & ""
    End If
    weeklyIdx = weeklyIdx + 1
    rsWeeklyTrend.MoveNext
Loop
rsWeeklyTrend.Close
Set rsWeeklyTrend = Nothing
' Reverse for chronological
Dim wi
For wi = weeklyIdx - 1 To 0 Step -1
    If weeklyLabels <> "" Then weeklyLabels = weeklyLabels & ","
    If weeklyMeasData <> "" Then weeklyMeasData = weeklyMeasData & ","
    If weeklyOOTRate <> "" Then weeklyOOTRate = weeklyOOTRate & ","
    weeklyLabels = weeklyLabels & """" & weeklyArr(wi, 0) & """"
    weeklyMeasData = weeklyMeasData & weeklyArr(wi, 1)
    weeklyOOTRate = weeklyOOTRate & weeklyArr(wi, 2)
Next
If weeklyLabels = "" Then weeklyLabels = """No Data"""
If weeklyMeasData = "" Then weeklyMeasData = "0"
If weeklyOOTRate = "" Then weeklyOOTRate = "0"

' Monthly parts production trends (from udcpartsdaily)
Dim rsMonthlyParts, monthlyPartsLabels, monthlyPartsData
monthlyPartsLabels = ""
monthlyPartsData = ""
strSQL2 = "SELECT yearmonth, SUM(partscount) as total_parts " & _
          "FROM vwudcparts_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 12"
Set rsMonthlyParts = objConn.Execute(strSQL2)
Dim partsArr(11,1), partsIdx
partsIdx = 0
Do While Not rsMonthlyParts.EOF And partsIdx < 12
    partsArr(partsIdx, 0) = rsMonthlyParts("yearmonth") & ""
    partsArr(partsIdx, 1) = rsMonthlyParts("total_parts") & ""
    partsIdx = partsIdx + 1
    rsMonthlyParts.MoveNext
Loop
rsMonthlyParts.Close
Set rsMonthlyParts = Nothing
Dim pi
For pi = partsIdx - 1 To 0 Step -1
    If monthlyPartsLabels <> "" Then monthlyPartsLabels = monthlyPartsLabels & ","
    If monthlyPartsData <> "" Then monthlyPartsData = monthlyPartsData & ","
    monthlyPartsLabels = monthlyPartsLabels & """" & partsArr(pi, 0) & """"
    monthlyPartsData = monthlyPartsData & partsArr(pi, 1)
Next
If monthlyPartsLabels = "" Then monthlyPartsLabels = """No Data"""
If monthlyPartsData = "" Then monthlyPartsData = "0"

' Monthly response time trends (from udcmanualrequestsdaily)
Dim rsMonthlyResp, monthlyRespLabels, monthlyRespData
monthlyRespLabels = ""
monthlyRespData = ""
strSQL2 = "SELECT yearmonth, ROUND(AVG(avgresponseseconds), 1) as avg_resp " & _
          "FROM vwudcmanualrequests_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 12"
Set rsMonthlyResp = objConn.Execute(strSQL2)
Dim respArr(11,1), respIdx
respIdx = 0
Do While Not rsMonthlyResp.EOF And respIdx < 12
    respArr(respIdx, 0) = rsMonthlyResp("yearmonth") & ""
    If IsNull(rsMonthlyResp("avg_resp")) Then
        respArr(respIdx, 1) = "0"
    Else
        respArr(respIdx, 1) = rsMonthlyResp("avg_resp") & ""
    End If
    respIdx = respIdx + 1
    rsMonthlyResp.MoveNext
Loop
rsMonthlyResp.Close
Set rsMonthlyResp = Nothing
Dim ri
For ri = respIdx - 1 To 0 Step -1
    If monthlyRespLabels <> "" Then monthlyRespLabels = monthlyRespLabels & ","
    If monthlyRespData <> "" Then monthlyRespData = monthlyRespData & ","
    monthlyRespLabels = monthlyRespLabels & """" & respArr(ri, 0) & """"
    monthlyRespData = monthlyRespData & respArr(ri, 1)
Next
If monthlyRespLabels = "" Then monthlyRespLabels = """No Data"""
If monthlyRespData = "" Then monthlyRespData = "0"

' Monthly violations trends (CLM specific)
Dim rsMonthlyViol, monthlyViolLabels, monthlyViolData
monthlyViolLabels = ""
monthlyViolData = ""
strSQL2 = "SELECT yearmonth, SUM(violationcount) as total_violations " & _
          "FROM vwudcviolations_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 12"
Set rsMonthlyViol = objConn.Execute(strSQL2)
Dim violArr(11,1), violIdx
violIdx = 0
Do While Not rsMonthlyViol.EOF And violIdx < 12
    violArr(violIdx, 0) = rsMonthlyViol("yearmonth") & ""
    If IsNull(rsMonthlyViol("total_violations")) Then
        violArr(violIdx, 1) = "0"
    Else
        violArr(violIdx, 1) = rsMonthlyViol("total_violations") & ""
    End If
    violIdx = violIdx + 1
    rsMonthlyViol.MoveNext
Loop
rsMonthlyViol.Close
Set rsMonthlyViol = Nothing
Dim vi
For vi = violIdx - 1 To 0 Step -1
    If monthlyViolLabels <> "" Then monthlyViolLabels = monthlyViolLabels & ","
    If monthlyViolData <> "" Then monthlyViolData = monthlyViolData & ","
    monthlyViolLabels = monthlyViolLabels & """" & violArr(vi, 0) & """"
    monthlyViolData = monthlyViolData & violArr(vi, 1)
Next
If monthlyViolLabels = "" Then monthlyViolLabels = """No Data"""
If monthlyViolData = "" Then monthlyViolData = "0"

' Monthly changeover time trends
Dim rsMonthlyChg, monthlyChgLabels, monthlyChgData
monthlyChgLabels = ""
monthlyChgData = ""
strSQL2 = "SELECT yearmonth, ROUND(AVG(avgchangeover)/60, 1) as avg_changeover_min " & _
          "FROM vwudcchangeover_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 12"
Set rsMonthlyChg = objConn.Execute(strSQL2)
Dim chgArr(11,1), chgIdx
chgIdx = 0
Do While Not rsMonthlyChg.EOF And chgIdx < 12
    chgArr(chgIdx, 0) = rsMonthlyChg("yearmonth") & ""
    If IsNull(rsMonthlyChg("avg_changeover_min")) Then
        chgArr(chgIdx, 1) = "0"
    Else
        chgArr(chgIdx, 1) = rsMonthlyChg("avg_changeover_min") & ""
    End If
    chgIdx = chgIdx + 1
    rsMonthlyChg.MoveNext
Loop
rsMonthlyChg.Close
Set rsMonthlyChg = Nothing
Dim ci
For ci = chgIdx - 1 To 0 Step -1
    If monthlyChgLabels <> "" Then monthlyChgLabels = monthlyChgLabels & ","
    If monthlyChgData <> "" Then monthlyChgData = monthlyChgData & ","
    monthlyChgLabels = monthlyChgLabels & """" & chgArr(ci, 0) & """"
    monthlyChgData = monthlyChgData & chgArr(ci, 1)
Next
If monthlyChgLabels = "" Then monthlyChgLabels = """No Data"""
If monthlyChgData = "" Then monthlyChgData = "0"

' Violations by machine (top 10)
Dim rsViolByMachine, violMachLabels, violMachData
violMachLabels = ""
violMachData = ""
strSQL2 = "SELECT machinenumber, SUM(violationcount) as total_violations " & _
          "FROM vwudcviolations_monthly " & _
          "GROUP BY machinenumber ORDER BY total_violations DESC LIMIT 10"
Set rsViolByMachine = objConn.Execute(strSQL2)
Do While Not rsViolByMachine.EOF
    If violMachLabels <> "" Then violMachLabels = violMachLabels & ","
    If violMachData <> "" Then violMachData = violMachData & ","
    violMachLabels = violMachLabels & """" & rsViolByMachine("machinenumber") & """"
    violMachData = violMachData & rsViolByMachine("total_violations")
    rsViolByMachine.MoveNext
Loop
rsViolByMachine.Close
Set rsViolByMachine = Nothing
If violMachLabels = "" Then violMachLabels = """No Data"""
If violMachData = "" Then violMachData = "0"
%>

    <!-- Tabbed Content Area -->
    <div class="row mt-3">
      <div class="col-12">
        <div class="card">
          <div class="card-body">
            <ul class="nav nav-tabs nav-tabs-primary" id="udcTabs">
              <li class="nav-item">
                <a href="#dashboard" data-toggle="tab" class="nav-link<%If activeTab="dashboard" Then Response.Write(" active")%>" onclick="setActiveTab('dashboard')">Dashboard</a>
              </li>
              <li class="nav-item">
                <a href="#liveactivity" data-toggle="tab" class="nav-link<%If activeTab="liveactivity" Then Response.Write(" active")%>" onclick="setActiveTab('liveactivity')">Live Activity</a>
              </li>
              <li class="nav-item">
                <a href="#operators" data-toggle="tab" class="nav-link<%If activeTab="operators" Then Response.Write(" active")%>" onclick="setActiveTab('operators')">Operators</a>
              </li>
              <li class="nav-item">
                <a href="#machines" data-toggle="tab" class="nav-link<%If activeTab="machines" Then Response.Write(" active")%>" onclick="setActiveTab('machines')">Machines</a>
              </li>
              <li class="nav-item">
                <a href="#parts" data-toggle="tab" class="nav-link<%If activeTab="parts" Then Response.Write(" active")%>" onclick="setActiveTab('parts')">Parts</a>
              </li>
              <li class="nav-item">
                <a href="#quality" data-toggle="tab" class="nav-link<%If activeTab="quality" Then Response.Write(" active")%>" onclick="setActiveTab('quality')">Quality/OOT</a>
              </li>
              <li class="nav-item">
                <a href="#timing" data-toggle="tab" class="nav-link<%If activeTab="timing" Then Response.Write(" active")%>" onclick="setActiveTab('timing')">Timing</a>
              </li>
              <li class="nav-item">
                <a href="#activitylog" data-toggle="tab" class="nav-link<%If activeTab="activitylog" Then Response.Write(" active")%>" onclick="setActiveTab('activitylog')">Activity Log</a>
              </li>
              <li class="nav-item">
                <a href="#toolhealth" data-toggle="tab" class="nav-link<%If activeTab="toolhealth" Then Response.Write(" active")%>" onclick="setActiveTab('toolhealth')">Tool Health</a>
              </li>
              <li class="nav-item">
                <a href="#uptime" data-toggle="tab" class="nav-link<%If activeTab="uptime" Then Response.Write(" active")%>" onclick="setActiveTab('uptime')">Uptime</a>
              </li>
              <li class="nav-item">
                <a href="#itdiagnostics" data-toggle="tab" class="nav-link<%If activeTab="itdiagnostics" Then Response.Write(" active")%>" onclick="setActiveTab('itdiagnostics')">IT Diagnostics</a>
              </li>
              <li class="nav-item">
                <a href="#trends" data-toggle="tab" class="nav-link<%If activeTab="trends" Then Response.Write(" active")%>" onclick="setActiveTab('trends')">Historical Trends</a>
              </li>
            </ul>

            <div class="tab-content p-3">
              <!-- Tab: Dashboard (Charts) -->
              <div class="tab-pane<%If activeTab="dashboard" Then Response.Write(" active")%>" id="dashboard">
                <h5 class="mb-3">UDC Performance Dashboard</h5>

                <!-- Charts Row 1 -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-primary text-white py-2">
                        Production Trend
                      </div>
                      <div class="card-body">
                        <div style="height: 220px;">
                          <canvas id="productionChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-danger text-white py-2">
                        OOT Rate Trend
                      </div>
                      <div class="card-body">
                        <div style="height: 220px;">
                          <canvas id="ootChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Charts Row 2 -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-info text-white py-2">
                        Machine Utilization (Hours)
                      </div>
                      <div class="card-body">
                        <div style="height: 220px;">
                          <canvas id="machineChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-success text-white py-2">
                        Top Operators (Parts)
                      </div>
                      <div class="card-body">
                        <div style="height: 220px;">
                          <canvas id="operatorChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- Tab: Live Activity -->
              <div class="tab-pane<%If activeTab="liveactivity" Then Response.Write(" active")%>" id="liveactivity">
                <h5 class="mb-3">Active Machines <span class="badge badge-success">Live</span></h5>
                <p class="text-muted small mb-3">Machines currently running jobs. Data refreshes when page loads.</p>
<%
' Get active sessions with optional machine/BU filter
Dim rsActive, activeCount, activeWhereClause
activeWhereClause = ""
If filterMachine <> "" Then
    activeWhereClause = " WHERE a.machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
ElseIf filterBU <> "" Then
    activeWhereClause = " WHERE a.machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If
strSQL2 = "SELECT a.machinenumber, a.partnumber, a.badgenumber, a.partsrun, a.lastupdate, a.sessionstart, " & _
         "TIMESTAMPDIFF(MINUTE, a.sessionstart, NOW()) as runtime_minutes " & _
         "FROM udcactivesessions a" & activeWhereClause & " ORDER BY a.lastupdate DESC"
Set rsActive = objConn.Execute(strSQL2)
activeCount = 0

If rsActive.EOF Then
%>
                <div class="alert alert-secondary text-center">
                  No active jobs detected
                </div>
<%
Else
%>
                <div class="table-responsive">
                  <table class="table table-hover table-striped" id="activeTable">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Part Number</th>
                        <th>Operator Badge</th>
                        <th>Parts Run</th>
                        <th>Runtime</th>
                        <th>Session Start</th>
                        <th>Last Activity</th>
                      </tr>
                    </thead>
                    <tbody>
<%
    Dim runtimeMinutes, runtimeDisplay
    Do While Not rsActive.EOF
        activeCount = activeCount + 1
        runtimeMinutes = rsActive("runtime_minutes")
        If IsNull(runtimeMinutes) Or runtimeMinutes = "" Then
            runtimeDisplay = "-"
        ElseIf CLng(runtimeMinutes) >= 60 Then
            runtimeDisplay = Int(CLng(runtimeMinutes) / 60) & "h " & (CLng(runtimeMinutes) Mod 60) & "m"
        Else
            runtimeDisplay = CLng(runtimeMinutes) & "m"
        End If
        Response.Write("<tr>")
        Response.Write("<td><a href='displaymachine.asp?machinenumber=" & Server.URLEncode(rsActive("machinenumber") & "") & "'><strong>" & Server.HTMLEncode(rsActive("machinenumber") & "") & "</strong></a></td>")
        Response.Write("<td>" & Server.HTMLEncode(rsActive("partnumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsActive("badgenumber") & "") & "</td>")
        Response.Write("<td><span class='badge badge-info'>" & rsActive("partsrun") & "</span></td>")
        Response.Write("<td>" & runtimeDisplay & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsActive("sessionstart") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsActive("lastupdate") & "") & "</td>")
        Response.Write("</tr>")
        rsActive.MoveNext
    Loop
%>
                    </tbody>
                  </table>
                </div>
                <p class="text-muted small mt-2 mb-0"><strong><%=activeCount%></strong> machine(s) currently active</p>
<%
End If
rsActive.Close
Set rsActive = Nothing
%>
              </div>

              <!-- Tab: Operator Performance -->
              <div class="tab-pane<%If activeTab="operators" Then Response.Write(" active")%>" id="operators">
                <h5 class="mb-3">Operator Performance Leaderboard</h5>
                <div class="table-responsive">
                  <table class="table table-hover table-striped" id="operatorTable">
                    <thead>
                      <tr>
                        <th>Badge #</th>
                        <th>Parts Run</th>
                        <th>Avg Cycle (min)</th>
                        <th>Avg Manual Response (sec)</th>
                        <th>Last Active</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get operator stats
Dim rsOperators, opCycle, opManual, opRowNum, opRowStyle
strSQL2 = "SELECT p.badgenumber, COUNT(*) as partsrun, " & _
         "AVG(p.cycletime) as avgcycle, " & _
         "MAX(p.programend) as lastactive, " & _
         "(SELECT AVG(mr.responseseconds) FROM udcmanualrequests mr " & _
         " JOIN udcparts p2 ON mr.partrunid = p2.partrunid WHERE p2.badgenumber = p.badgenumber) as avgmanual " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND p.badgenumber IS NOT NULL AND p.badgenumber != '' " & _
         "GROUP BY p.badgenumber ORDER BY partsrun DESC, p.badgenumber ASC"
Set rsOperators = objConn.Execute(strSQL2)
opRowNum = 0
If rsOperators.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No operator data found</td></tr>")
Else
    Do While Not rsOperators.EOF
        opRowNum = opRowNum + 1
        If Not IsNull(rsOperators("avgcycle")) Then
            opCycle = FormatNumber(CDbl(rsOperators("avgcycle")) / 60, 1)
        Else
            opCycle = "-"
        End If
        If Not IsNull(rsOperators("avgmanual")) Then
            opManual = FormatNumber(CDbl(rsOperators("avgmanual")), 0)
        Else
            opManual = "-"
        End If

        ' Highlight top 3 performers
        opRowStyle = ""
        If opRowNum = 1 Then
            opRowStyle = "background-color:#28a745; color:#fff;"
        ElseIf opRowNum = 2 Then
            opRowStyle = "background-color:#20c997; color:#fff;"
        ElseIf opRowNum = 3 Then
            opRowStyle = "background-color:#17a2b8; color:#fff;"
        End If

        Response.Write("<tr style='" & opRowStyle & "'>")
        Response.Write("<td><a href='displayudc.asp?badge=" & Server.URLEncode(rsOperators("badgenumber") & "") & "' style='color:inherit;'>" & Server.HTMLEncode(rsOperators("badgenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsOperators("partsrun") & "</td>")
        Response.Write("<td>" & opCycle & "</td>")
        Response.Write("<td>" & opManual & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsOperators("lastactive") & "") & "</td>")
        Response.Write("</tr>")
        rsOperators.MoveNext
    Loop
End If
rsOperators.Close
Set rsOperators = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 2: Machine Performance -->
              <div class="tab-pane<%If activeTab="machines" Then Response.Write(" active")%>" id="machines">
                <h5 class="mb-3">Machine Performance Comparison</h5>
                <div class="table-responsive">
                  <table class="table table-hover table-striped" id="machineTable">
                    <thead>
                      <tr>
                        <th>Machine #</th>
                        <th>Parts Run</th>
                        <th>Avg Cycle (min)</th>
                        <th>Avg Changeover (min)</th>
                        <th>Parts with OOT</th>
                        <th>OOT Rate</th>
                        <th>Last Run</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get machine stats
Dim rsMachStats, machCycle, machChange, machOOTRate, machOOTBadge, machPartsWithOOT
strSQL2 = "SELECT s.machinenumber, COUNT(*) as partsrun, " & _
         "AVG(p.cycletime) as avgcycle, " & _
         "AVG(p.changeover) as avgchangeover, " & _
         "SUM(CASE WHEN p.ootcount > 0 THEN 1 ELSE 0 END) as partswithoot, " & _
         "MAX(p.programend) as lastrun " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " GROUP BY s.machinenumber ORDER BY partsrun DESC, s.machinenumber ASC"
Set rsMachStats = objConn.Execute(strSQL2)
If rsMachStats.EOF Then
    Response.Write("<tr><td colspan='7' class='text-muted text-center'>No machine data found</td></tr>")
Else
    Do While Not rsMachStats.EOF
        If Not IsNull(rsMachStats("avgcycle")) Then
            machCycle = FormatNumber(CDbl(rsMachStats("avgcycle")) / 60, 1)
        Else
            machCycle = "-"
        End If
        If Not IsNull(rsMachStats("avgchangeover")) Then
            machChange = FormatNumber(CDbl(rsMachStats("avgchangeover")) / 60, 1)
        Else
            machChange = "-"
        End If
        machPartsWithOOT = CLng("0" & rsMachStats("partswithoot"))
        If CLng("0" & rsMachStats("partsrun")) > 0 Then
            machOOTRate = FormatNumber(CDbl(machPartsWithOOT) / CDbl(rsMachStats("partsrun")) * 100, 2)
        Else
            machOOTRate = "0"
        End If
        If CDbl(machOOTRate) > 5 Then
            machOOTBadge = "<span class='badge badge-danger'>" & machOOTRate & "%</span>"
        ElseIf CDbl(machOOTRate) > 0 Then
            machOOTBadge = "<span class='badge badge-warning'>" & machOOTRate & "%</span>"
        Else
            machOOTBadge = "<span class='badge badge-success'>" & machOOTRate & "%</span>"
        End If

        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsMachStats("machinenumber") & "") & "'>" & Server.HTMLEncode(rsMachStats("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsMachStats("partsrun") & "</td>")
        Response.Write("<td>" & machCycle & "</td>")
        Response.Write("<td>" & machChange & "</td>")
        Response.Write("<td>" & machPartsWithOOT & "</td>")
        Response.Write("<td>" & machOOTBadge & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsMachStats("lastrun") & "") & "</td>")
        Response.Write("</tr>")
        rsMachStats.MoveNext
    Loop
End If
rsMachStats.Close
Set rsMachStats = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 3: Part Analysis -->
              <div class="tab-pane<%If activeTab="parts" Then Response.Write(" active")%>" id="parts">
                <h5 class="mb-3">Part Number Analysis</h5>
                <div class="table-responsive">
                  <table class="table table-hover table-striped" id="partsTable">
                    <thead>
                      <tr>
                        <th>Part #</th>
                        <th>Count</th>
                        <th>Avg Cycle (min)</th>
                        <th>Parts with OOT</th>
                        <th>OOT Rate</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get part stats
Dim rsPartStats, partCycle, partOOTRate, partOOTBadge, partPartsWithOOT
strSQL2 = "SELECT p.partnumber, COUNT(*) as cnt, " & _
         "AVG(p.cycletime) as avgcycle, " & _
         "SUM(CASE WHEN p.ootcount > 0 THEN 1 ELSE 0 END) as partswithoot " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND p.partnumber IS NOT NULL AND p.partnumber != '' " & _
         "GROUP BY p.partnumber ORDER BY partswithoot DESC, cnt DESC, p.partnumber ASC LIMIT 50"
Set rsPartStats = objConn.Execute(strSQL2)
If rsPartStats.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No part data found</td></tr>")
Else
    Do While Not rsPartStats.EOF
        If Not IsNull(rsPartStats("avgcycle")) Then
            partCycle = FormatNumber(CDbl(rsPartStats("avgcycle")) / 60, 1)
        Else
            partCycle = "-"
        End If
        partPartsWithOOT = CLng("0" & rsPartStats("partswithoot"))
        If CLng("0" & rsPartStats("cnt")) > 0 Then
            partOOTRate = FormatNumber(CDbl(partPartsWithOOT) / CDbl(rsPartStats("cnt")) * 100, 2)
        Else
            partOOTRate = "0"
        End If
        If CDbl(partOOTRate) > 5 Then
            partOOTBadge = "<span class='badge badge-danger'>" & partOOTRate & "%</span>"
        ElseIf CDbl(partOOTRate) > 0 Then
            partOOTBadge = "<span class='badge badge-warning'>" & partOOTRate & "%</span>"
        Else
            partOOTBadge = "<span class='badge badge-success'>0%</span>"
        End If

        Response.Write("<tr>")
        Response.Write("<td>" & Server.HTMLEncode(rsPartStats("partnumber") & "") & "</td>")
        Response.Write("<td>" & rsPartStats("cnt") & "</td>")
        Response.Write("<td>" & partCycle & "</td>")
        Response.Write("<td>" & partPartsWithOOT & "</td>")
        Response.Write("<td>" & partOOTBadge & "</td>")
        Response.Write("</tr>")
        rsPartStats.MoveNext
    Loop
End If
rsPartStats.Close
Set rsPartStats = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 4: Quality/OOT Analysis -->
              <div class="tab-pane<%If activeTab="quality" Then Response.Write(" active")%>" id="quality">
                <h5 class="mb-3">Out-of-Tolerance Analysis</h5>

                <!-- OOT Summary by Machine -->
                <h6 class="mt-3 mb-2">OOT by Machine</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Parts with OOT</th>
                        <th>Parts Run</th>
                        <th>OOT Rate</th>
                        <th style="width:40%">Bar</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get OOT by Machine
Dim rsOOTMach, maxOOT, ootMachRate, barWidth, ootMachParts
maxOOT = 1
strSQL2 = "SELECT s.machinenumber, SUM(CASE WHEN p.ootcount > 0 THEN 1 ELSE 0 END) as partswithoot, COUNT(*) as partsrun " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " GROUP BY s.machinenumber ORDER BY partswithoot DESC, s.machinenumber ASC LIMIT 10"
Set rsOOTMach = objConn.Execute(strSQL2)
If rsOOTMach.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No OOT data found</td></tr>")
Else
    ' Find max for bar scaling
    Do While Not rsOOTMach.EOF
        If CLng("0" & rsOOTMach("partswithoot")) > maxOOT Then maxOOT = CLng("0" & rsOOTMach("partswithoot"))
        rsOOTMach.MoveNext
    Loop
    rsOOTMach.Close
    Set rsOOTMach = objConn.Execute(strSQL2)

    Do While Not rsOOTMach.EOF
        ootMachParts = CLng("0" & rsOOTMach("partswithoot"))
        If CLng("0" & rsOOTMach("partsrun")) > 0 Then
            ootMachRate = FormatNumber(CDbl(ootMachParts) / CDbl(rsOOTMach("partsrun")) * 100, 2)
        Else
            ootMachRate = "0"
        End If
        barWidth = Int((ootMachParts / maxOOT) * 100)

        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsOOTMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsOOTMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & ootMachParts & "</td>")
        Response.Write("<td>" & rsOOTMach("partsrun") & "</td>")
        Response.Write("<td>" & ootMachRate & "%</td>")
        Response.Write("<td><div style='background:#dc3545;height:20px;width:" & barWidth & "%;border-radius:3px;'></div></td>")
        Response.Write("</tr>")
        rsOOTMach.MoveNext
    Loop
End If
rsOOTMach.Close
Set rsOOTMach = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Recent OOT Measurements -->
                <h6 class="mt-4 mb-2">Recent OOT Measurements</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Part #</th>
                        <th>Dimension</th>
                        <th>Min</th>
                        <th>Actual</th>
                        <th>Max</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent OOT measurements
Dim rsOOT
strSQL2 = "SELECT m.eventtime, s.machinenumber, p.partnumber, m.dimid, m.description, " & _
         "m.minval, m.actualval, m.maxval " & _
         "FROM udcmeasurements m " & _
         "JOIN udcparts p ON m.partrunid = p.partrunid " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND m.oot = 1 " & _
         "ORDER BY m.eventtime DESC LIMIT 50"
Set rsOOT = objConn.Execute(strSQL2)
If rsOOT.EOF Then
    Response.Write("<tr><td colspan='7' class='text-muted text-center'>No OOT measurements found</td></tr>")
Else
    Do While Not rsOOT.EOF
        Response.Write("<tr style='background-color:#dc3545; color:#fff;'>")
        Response.Write("<td>" & Server.HTMLEncode(rsOOT("eventtime") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsOOT("machinenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsOOT("partnumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsOOT("dimid") & "") & " - " & Server.HTMLEncode(rsOOT("description") & "") & "</td>")
        Response.Write("<td>" & rsOOT("minval") & "</td>")
        Response.Write("<td><strong>" & rsOOT("actualval") & "</strong></td>")
        Response.Write("<td>" & rsOOT("maxval") & "</td>")
        Response.Write("</tr>")
        rsOOT.MoveNext
    Loop
End If
rsOOT.Close
Set rsOOT = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Best Performing Machines -->
                <h6 class="mt-4 mb-2">Best Performing Machines (Lowest OOT Rates)</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Parts Run</th>
                        <th>OOT Count</th>
                        <th>OOT Rate</th>
                        <th style="width:40%">Quality Bar</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get best performing machines (lowest OOT rate, min 10 parts)
Dim rsBestMach, bestRate, bestStyle, qualityWidth, bestPartsWithOOT
strSQL2 = "SELECT s.machinenumber, COUNT(*) as partsrun, " & _
         "SUM(CASE WHEN p.ootcount > 0 THEN 1 ELSE 0 END) as partswithoot, " & _
         "ROUND(SUM(CASE WHEN p.ootcount > 0 THEN 1 ELSE 0 END)/COUNT(*)*100, 2) as ootrate " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " GROUP BY s.machinenumber HAVING COUNT(*) >= 10 ORDER BY ootrate ASC, partsrun DESC, s.machinenumber ASC LIMIT 10"
Set rsBestMach = objConn.Execute(strSQL2)
If rsBestMach.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No machine data found (min 10 parts required)</td></tr>")
Else
    Do While Not rsBestMach.EOF
        bestPartsWithOOT = CLng("0" & rsBestMach("partswithoot"))
        bestRate = CDbl("0" & rsBestMach("ootrate"))
        qualityWidth = 100 - Int(bestRate)
        If qualityWidth < 0 Then qualityWidth = 0
        If qualityWidth > 100 Then qualityWidth = 100

        If bestRate = 0 Then
            bestStyle = "background-color:#28a745; color:#fff;"
        ElseIf bestRate < 5 Then
            bestStyle = "background-color:#20c997; color:#fff;"
        Else
            bestStyle = ""
        End If

        Response.Write("<tr style='" & bestStyle & "'>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsBestMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsBestMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsBestMach("partsrun") & "</td>")
        Response.Write("<td>" & bestPartsWithOOT & "</td>")
        Response.Write("<td>" & bestRate & "%</td>")
        Response.Write("<td><div style='background:#28a745;height:20px;width:" & qualityWidth & "%;border-radius:3px;'></div></td>")
        Response.Write("</tr>")
        rsBestMach.MoveNext
    Loop
End If
rsBestMach.Close
Set rsBestMach = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 5: Timing Analysis -->
              <div class="tab-pane<%If activeTab="timing" Then Response.Write(" active")%>" id="timing">
                <h5 class="mb-3">Timing Analysis</h5>

                <!-- Manual Response Time by Operator -->
                <h6 class="mt-3 mb-2">Manual Response Time by Operator</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Badge #</th>
                        <th>Requests</th>
                        <th>Avg Response (sec)</th>
                        <th>Max Response (sec)</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get manual response time by operator
Dim rsManualOp, manAvg, manMax
strSQL2 = "SELECT p.badgenumber, COUNT(*) as requests, " & _
         "AVG(mr.responseseconds) as avgresponse, " & _
         "MAX(mr.responseseconds) as maxresponse " & _
         "FROM udcmanualrequests mr " & _
         "JOIN udcparts p ON mr.partrunid = p.partrunid " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND p.badgenumber IS NOT NULL AND p.badgenumber != ''" & shiftFilter & _
         " GROUP BY p.badgenumber ORDER BY avgresponse ASC, p.badgenumber ASC"
Set rsManualOp = objConn.Execute(strSQL2)
If rsManualOp.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No manual request data found</td></tr>")
Else
    Do While Not rsManualOp.EOF
        If Not IsNull(rsManualOp("avgresponse")) Then
            manAvg = FormatNumber(CDbl(rsManualOp("avgresponse")), 0)
        Else
            manAvg = "-"
        End If
        manMax = CLng("0" & rsManualOp("maxresponse"))

        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?badge=" & Server.URLEncode(rsManualOp("badgenumber") & "") & "'>" & Server.HTMLEncode(rsManualOp("badgenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsManualOp("requests") & "</td>")
        Response.Write("<td>" & manAvg & "</td>")
        Response.Write("<td>" & manMax & "</td>")
        Response.Write("</tr>")
        rsManualOp.MoveNext
    Loop
End If
rsManualOp.Close
Set rsManualOp = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Slowest Manual Responses -->
                <h6 class="mt-4 mb-2">Slowest Manual Responses</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Request Time</th>
                        <th>Machine</th>
                        <th>Badge</th>
                        <th>Description</th>
                        <th>Response Time (sec)</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get slowest manual responses
Dim rsSlow, rowStyle
strSQL2 = "SELECT mr.requesttime, s.machinenumber, p.badgenumber, mr.description, mr.responseseconds " & _
         "FROM udcmanualrequests mr " & _
         "JOIN udcparts p ON mr.partrunid = p.partrunid " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & shiftFilter & _
         " ORDER BY mr.responseseconds DESC LIMIT 25"
Set rsSlow = objConn.Execute(strSQL2)
If rsSlow.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No manual requests found</td></tr>")
Else
    Do While Not rsSlow.EOF
        If CLng("0" & rsSlow("responseseconds")) > 300 Then
            rowStyle = "background-color:#dc3545; color:#fff;"
        ElseIf CLng("0" & rsSlow("responseseconds")) > 120 Then
            rowStyle = "background-color:#ffc107; color:#333;"
        Else
            rowStyle = ""
        End If
        Response.Write("<tr style='" & rowStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsSlow("requesttime") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsSlow("machinenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsSlow("badgenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsSlow("description") & "") & "</td>")
        Response.Write("<td>" & rsSlow("responseseconds") & "</td>")
        Response.Write("</tr>")
        rsSlow.MoveNext
    Loop
End If
rsSlow.Close
Set rsSlow = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Fastest Manual Responses -->
                <h6 class="mt-4 mb-2">Fastest Responses (Top Performers)</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Request Time</th>
                        <th>Machine</th>
                        <th>Badge</th>
                        <th>Description</th>
                        <th>Response Time (sec)</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get fastest manual responses
Dim rsFast, fastStyle
strSQL2 = "SELECT mr.requesttime, s.machinenumber, p.badgenumber, mr.description, mr.responseseconds " & _
         "FROM udcmanualrequests mr " & _
         "JOIN udcparts p ON mr.partrunid = p.partrunid " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & shiftFilter & _
         " AND mr.responseseconds > 0 ORDER BY mr.responseseconds ASC LIMIT 25"
Set rsFast = objConn.Execute(strSQL2)
If rsFast.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No manual requests found</td></tr>")
Else
    Do While Not rsFast.EOF
        If CLng("0" & rsFast("responseseconds")) < 30 Then
            fastStyle = "background-color:#28a745; color:#fff;"
        ElseIf CLng("0" & rsFast("responseseconds")) < 60 Then
            fastStyle = "background-color:#20c997; color:#fff;"
        Else
            fastStyle = ""
        End If
        Response.Write("<tr style='" & fastStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsFast("requesttime") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsFast("machinenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsFast("badgenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsFast("description") & "") & "</td>")
        Response.Write("<td>" & rsFast("responseseconds") & "</td>")
        Response.Write("</tr>")
        rsFast.MoveNext
    Loop
End If
rsFast.Close
Set rsFast = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 6: Activity Log (Violations & Badge Changes) -->
              <div class="tab-pane<%If activeTab="activitylog" Then Response.Write(" active")%>" id="activitylog">
                <h5 class="mb-3">Activity Log</h5>
                <p class="text-muted small mb-3">Badge changes and item crossing violations recorded during part runs.</p>

                <!-- Item Violations Summary -->
                <h6 class="mt-3 mb-2">Item Crossing Violations</h6>
                <p class="text-muted small">When operators modify item crossing values during a program run.</p>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Badge</th>
                        <th>Crossing</th>
                        <th>Item#</th>
                        <th>Previous</th>
                        <th>Current</th>
                        <th>Change</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent violations
Dim rsViolations, violWhereClause, violPrev, violCurr, violChange, violStyle
violWhereClause = " WHERE eventtime >= '" & Replace(filterStart, "'", "''") & "' " & _
                  " AND eventtime <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"
If filterMachine <> "" Then
    violWhereClause = violWhereClause & " AND machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    violWhereClause = violWhereClause & " AND machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If
If filterBadge <> "" Then
    violWhereClause = violWhereClause & " AND badgenumber = '" & Replace(filterBadge, "'", "''") & "'"
End If

strSQL2 = "SELECT eventtime, machinenumber, badgenumber, crossingdesc, itemno, previousval, currentval " & _
         "FROM udcviolations " & violWhereClause & _
         " ORDER BY eventtime DESC LIMIT 50"
Set rsViolations = objConn.Execute(strSQL2)
If rsViolations.EOF Then
    Response.Write("<tr><td colspan='8' class='text-muted text-center'>No item violations found in date range</td></tr>")
Else
    Do While Not rsViolations.EOF
        violPrev = CDbl("0" & rsViolations("previousval"))
        violCurr = CDbl("0" & rsViolations("currentval"))
        violChange = violCurr - violPrev

        ' Color code based on change magnitude
        If Abs(violChange) > 10 Then
            violStyle = "background-color:#dc3545; color:#fff;"
        ElseIf Abs(violChange) > 1 Then
            violStyle = "background-color:#ffc107; color:#333;"
        Else
            violStyle = ""
        End If

        Response.Write("<tr style='" & violStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsViolations("eventtime") & "") & "</td>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsViolations("machinenumber") & "") & "'>" & Server.HTMLEncode(rsViolations("machinenumber") & "") & "</a></td>")
        Response.Write("<td><a href='displayudc.asp?badge=" & Server.URLEncode(rsViolations("badgenumber") & "") & "'>" & Server.HTMLEncode(rsViolations("badgenumber") & "") & "</a></td>")
        Response.Write("<td>" & Server.HTMLEncode(rsViolations("crossingdesc") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsViolations("itemno") & "") & "</td>")
        Response.Write("<td>" & FormatNumber(violPrev, 2) & "</td>")
        Response.Write("<td><strong>" & FormatNumber(violCurr, 2) & "</strong></td>")
        If violChange > 0 Then
            Response.Write("<td><span class='text-success'>+" & FormatNumber(violChange, 2) & "</span></td>")
        ElseIf violChange < 0 Then
            Response.Write("<td><span class='text-danger'>" & FormatNumber(violChange, 2) & "</span></td>")
        Else
            Response.Write("<td>0</td>")
        End If
        Response.Write("</tr>")
        rsViolations.MoveNext
    Loop
End If
rsViolations.Close
Set rsViolations = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Violations by Machine -->
                <h6 class="mt-4 mb-2">Violations by Machine</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Total Violations</th>
                        <th>Unique Crossings</th>
                        <th>Last Violation</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get violations summary by machine
Dim rsViolMach, violMachStyle
strSQL2 = "SELECT machinenumber, COUNT(*) as cnt, COUNT(DISTINCT crossingdesc) as crossings, MAX(eventtime) as lasttime " & _
         "FROM udcviolations " & violWhereClause & _
         " GROUP BY machinenumber ORDER BY cnt DESC, machinenumber ASC LIMIT 10"
Set rsViolMach = objConn.Execute(strSQL2)
If rsViolMach.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No violations found</td></tr>")
Else
    Do While Not rsViolMach.EOF
        If CLng("0" & rsViolMach("cnt")) > 100 Then
            violMachStyle = "background-color:#dc3545; color:#fff;"
        ElseIf CLng("0" & rsViolMach("cnt")) > 25 Then
            violMachStyle = "background-color:#ffc107; color:#333;"
        Else
            violMachStyle = ""
        End If
        Response.Write("<tr style='" & violMachStyle & "'>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsViolMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsViolMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsViolMach("cnt") & "</td>")
        Response.Write("<td>" & rsViolMach("crossings") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsViolMach("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsViolMach.MoveNext
    Loop
End If
rsViolMach.Close
Set rsViolMach = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Badge Changes -->
                <h6 class="mt-4 mb-2">Badge Changes</h6>
                <p class="text-muted small">Operator badge scans and changes during part runs.</p>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Badge</th>
                        <th>Details</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent badge changes
Dim rsBadgeChanges, badgeWhereClause
badgeWhereClause = " WHERE eventtime >= '" & Replace(filterStart, "'", "''") & "' " & _
                   " AND eventtime <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"
If filterMachine <> "" Then
    badgeWhereClause = badgeWhereClause & " AND machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    badgeWhereClause = badgeWhereClause & " AND machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If
If filterBadge <> "" Then
    badgeWhereClause = badgeWhereClause & " AND badgenumber = '" & Replace(filterBadge, "'", "''") & "'"
End If

strSQL2 = "SELECT eventtime, machinenumber, badgenumber, details, description " & _
         "FROM udcheaderupdates " & badgeWhereClause & _
         " ORDER BY eventtime DESC LIMIT 50"
Set rsBadgeChanges = objConn.Execute(strSQL2)
If rsBadgeChanges.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No badge changes found in date range</td></tr>")
Else
    Do While Not rsBadgeChanges.EOF
        Response.Write("<tr>")
        Response.Write("<td>" & Server.HTMLEncode(rsBadgeChanges("eventtime") & "") & "</td>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsBadgeChanges("machinenumber") & "") & "'>" & Server.HTMLEncode(rsBadgeChanges("machinenumber") & "") & "</a></td>")
        Response.Write("<td><a href='displayudc.asp?badge=" & Server.URLEncode(rsBadgeChanges("badgenumber") & "") & "'><span class='badge badge-info'>" & Server.HTMLEncode(rsBadgeChanges("badgenumber") & "") & "</span></a></td>")
        Response.Write("<td>" & Server.HTMLEncode(rsBadgeChanges("description") & "") & "</td>")
        Response.Write("</tr>")
        rsBadgeChanges.MoveNext
    Loop
End If
rsBadgeChanges.Close
Set rsBadgeChanges = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Badge Activity by Operator -->
                <h6 class="mt-4 mb-2">Badge Activity by Operator</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Badge #</th>
                        <th>Badge Scans</th>
                        <th>Machines Used</th>
                        <th>Last Activity</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get badge activity summary
Dim rsBadgeSum
strSQL2 = "SELECT badgenumber, COUNT(*) as cnt, COUNT(DISTINCT machinenumber) as machines, MAX(eventtime) as lasttime " & _
         "FROM udcheaderupdates " & badgeWhereClause & _
         " AND badgenumber IS NOT NULL AND badgenumber != '' " & _
         " GROUP BY badgenumber ORDER BY cnt DESC, badgenumber ASC LIMIT 15"
Set rsBadgeSum = objConn.Execute(strSQL2)
If rsBadgeSum.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No badge activity found</td></tr>")
Else
    Do While Not rsBadgeSum.EOF
        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?badge=" & Server.URLEncode(rsBadgeSum("badgenumber") & "") & "'><span class='badge badge-info'>" & Server.HTMLEncode(rsBadgeSum("badgenumber") & "") & "</span></a></td>")
        Response.Write("<td>" & rsBadgeSum("cnt") & "</td>")
        Response.Write("<td>" & rsBadgeSum("machines") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsBadgeSum("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsBadgeSum.MoveNext
    Loop
End If
rsBadgeSum.Close
Set rsBadgeSum = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 7: Tool Health -->
              <div class="tab-pane<%If activeTab="toolhealth" Then Response.Write(" active")%>" id="toolhealth">
                <h5 class="mb-3">Tool Health</h5>
                <p class="text-muted small mb-3">Tool offset measurements and wear tracking.</p>

                <!-- Tool Summary by Machine -->
                <h6 class="mt-3 mb-2">Tool Measurements by Machine</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Measurements</th>
                        <th>Unique Tools</th>
                        <th>OOT Count</th>
                        <th>Last Measurement</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get tool data summary by machine
Dim rsToolMach, toolWhereClause, toolMachStyle
toolWhereClause = " WHERE t.eventtime >= '" & Replace(filterStart, "'", "''") & "' " & _
                  " AND t.eventtime <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"
If filterMachine <> "" Then
    toolWhereClause = toolWhereClause & " AND s.machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    toolWhereClause = toolWhereClause & " AND s.machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If

strSQL2 = "SELECT s.machinenumber, COUNT(*) as cnt, COUNT(DISTINCT t.toolnumber) as tools, " & _
         "SUM(t.oot) as ootcount, MAX(t.eventtime) as lasttime " & _
         "FROM udctooldata t " & _
         "JOIN udcsessions s ON t.sessionid = s.sessionid " & _
         toolWhereClause & _
         " GROUP BY s.machinenumber ORDER BY cnt DESC, s.machinenumber ASC LIMIT 15"
Set rsToolMach = objConn.Execute(strSQL2)
If rsToolMach.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No tool data found in date range</td></tr>")
Else
    Do While Not rsToolMach.EOF
        If CLng("0" & rsToolMach("ootcount")) > 0 Then
            toolMachStyle = "background-color:#ffc107; color:#333;"
        Else
            toolMachStyle = ""
        End If
        Response.Write("<tr style='" & toolMachStyle & "'>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsToolMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsToolMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsToolMach("cnt") & "</td>")
        Response.Write("<td>" & rsToolMach("tools") & "</td>")
        Response.Write("<td>")
        If CLng("0" & rsToolMach("ootcount")) > 0 Then
            Response.Write("<span class='badge badge-danger'>" & rsToolMach("ootcount") & "</span>")
        Else
            Response.Write("<span class='badge badge-success'>0</span>")
        End If
        Response.Write("</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsToolMach("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsToolMach.MoveNext
    Loop
End If
rsToolMach.Close
Set rsToolMach = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Tool Usage by Tool Number - Only shown when machine filter selected -->
<%
If filterMachine <> "" Then
%>
                <h6 class="mt-4 mb-2">Most Used Tools on Machine <%=Server.HTMLEncode(filterMachine)%></h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Tool #</th>
                        <th>Description</th>
                        <th>Measurements</th>
                        <th>Avg Deviation</th>
                        <th>OOT Count</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get tool usage by tool number for this specific machine
Dim rsToolNum, toolNumStyle, avgDev
strSQL2 = "SELECT t.toolnumber, MAX(t.description) as description, COUNT(*) as cnt, " & _
         "AVG(ABS(t.deviation)) as avgdev, SUM(t.oot) as ootcount " & _
         "FROM udctooldata t " & _
         "JOIN udcsessions s ON t.sessionid = s.sessionid " & _
         toolWhereClause & _
         " AND t.toolnumber IS NOT NULL " & _
         " GROUP BY t.toolnumber ORDER BY cnt DESC, t.toolnumber ASC LIMIT 20"
Set rsToolNum = objConn.Execute(strSQL2)
If rsToolNum.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No tool data found</td></tr>")
Else
    Do While Not rsToolNum.EOF
        If CLng("0" & rsToolNum("ootcount")) > 0 Then
            toolNumStyle = "background-color:#ffc107; color:#333;"
        Else
            toolNumStyle = ""
        End If
        If Not IsNull(rsToolNum("avgdev")) Then
            avgDev = FormatNumber(CDbl(rsToolNum("avgdev")), 4)
        Else
            avgDev = "-"
        End If
        Response.Write("<tr style='" & toolNumStyle & "'>")
        Response.Write("<td><strong>Tool " & rsToolNum("toolnumber") & "</strong></td>")
        Response.Write("<td>" & Server.HTMLEncode(Trim(rsToolNum("description") & "")) & "</td>")
        Response.Write("<td>" & rsToolNum("cnt") & "</td>")
        Response.Write("<td>" & avgDev & "</td>")
        Response.Write("<td>")
        If CLng("0" & rsToolNum("ootcount")) > 0 Then
            Response.Write("<span class='badge badge-danger'>" & rsToolNum("ootcount") & "</span>")
        Else
            Response.Write("<span class='badge badge-success'>0</span>")
        End If
        Response.Write("</td>")
        Response.Write("</tr>")
        rsToolNum.MoveNext
    Loop
End If
rsToolNum.Close
Set rsToolNum = Nothing
%>
                    </tbody>
                  </table>
                </div>
<%
End If ' filterMachine
%>

                <!-- Recent Tool Measurements -->
                <h6 class="mt-4 mb-2">Recent Tool Measurements</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Tool #</th>
                        <th>Description</th>
                        <th>Min</th>
                        <th>Actual</th>
                        <th>Max</th>
                        <th>Status</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent tool measurements
Dim rsToolRecent, toolRecentStyle
strSQL2 = "SELECT t.eventtime, s.machinenumber, t.toolnumber, t.description, " & _
         "t.minval, t.actualval, t.maxval, t.oot " & _
         "FROM udctooldata t " & _
         "JOIN udcsessions s ON t.sessionid = s.sessionid " & _
         toolWhereClause & _
         " ORDER BY t.eventtime DESC LIMIT 30"
Set rsToolRecent = objConn.Execute(strSQL2)
If rsToolRecent.EOF Then
    Response.Write("<tr><td colspan='8' class='text-muted text-center'>No tool measurements found</td></tr>")
Else
    Do While Not rsToolRecent.EOF
        If CLng("0" & rsToolRecent("oot")) > 0 Then
            toolRecentStyle = "background-color:#dc3545; color:#fff;"
        Else
            toolRecentStyle = ""
        End If
        Response.Write("<tr style='" & toolRecentStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsToolRecent("eventtime") & "") & "</td>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsToolRecent("machinenumber") & "") & "'>" & Server.HTMLEncode(rsToolRecent("machinenumber") & "") & "</a></td>")
        Response.Write("<td>Tool " & rsToolRecent("toolnumber") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsToolRecent("description") & "") & "</td>")
        Response.Write("<td>" & rsToolRecent("minval") & "</td>")
        Response.Write("<td><strong>" & rsToolRecent("actualval") & "</strong></td>")
        Response.Write("<td>" & rsToolRecent("maxval") & "</td>")
        If CLng("0" & rsToolRecent("oot")) > 0 Then
            Response.Write("<td><span class='badge badge-danger'>OOT</span></td>")
        Else
            Response.Write("<td><span class='badge badge-success'>OK</span></td>")
        End If
        Response.Write("</tr>")
        rsToolRecent.MoveNext
    Loop
End If
rsToolRecent.Close
Set rsToolRecent = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 8: Uptime -->
              <div class="tab-pane<%If activeTab="uptime" Then Response.Write(" active")%>" id="uptime">
                <h5 class="mb-3">Machine Uptime</h5>
                <p class="text-muted small mb-3">Runtime calculated from actual part cycle times within the selected date range.</p>

                <!-- Uptime Summary Cards -->
                <div class="row mb-4">
<%
' Calculate uptime summary
Dim rsUptimeSummary, totalRuntimeHours, totalMachines, avgUtilization
strSQL2 = "SELECT COUNT(DISTINCT s.machinenumber) as machines, " & _
         "ROUND(SUM(p.cycletime)/3600, 1) as total_hours, " & _
         "ROUND(AVG(p.cycletime)/60, 1) as avg_cycle " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND p.cycletime IS NOT NULL AND p.cycletime > 0"
Set rsUptimeSummary = objConn.Execute(strSQL2)
If Not rsUptimeSummary.EOF Then
    totalMachines = CLng("0" & rsUptimeSummary("machines"))
    If Not IsNull(rsUptimeSummary("total_hours")) Then
        totalRuntimeHours = FormatNumber(CDbl(rsUptimeSummary("total_hours")), 1)
    Else
        totalRuntimeHours = "0"
    End If
Else
    totalMachines = 0
    totalRuntimeHours = "0"
End If
rsUptimeSummary.Close
Set rsUptimeSummary = Nothing
%>
                  <div class="col-md-4">
                    <div class="card bg-info text-white">
                      <div class="card-body text-center">
                        <h3 class="mb-0"><%=totalRuntimeHours%></h3>
                        <small>Total Runtime Hours</small>
                      </div>
                    </div>
                  </div>
                  <div class="col-md-4">
                    <div class="card bg-success text-white">
                      <div class="card-body text-center">
                        <h3 class="mb-0"><%=totalMachines%></h3>
                        <small>Active Machines</small>
                      </div>
                    </div>
                  </div>
                  <div class="col-md-4">
                    <div class="card bg-primary text-white">
                      <div class="card-body text-center">
                        <h3 class="mb-0"><%=totalParts%></h3>
                        <small>Parts Produced</small>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Machine Uptime Table -->
                <h6 class="mt-3 mb-2">Runtime by Machine</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped" id="uptimeTable">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Runtime (hrs)</th>
                        <th>Parts Run</th>
                        <th>Avg Cycle (min)</th>
                        <th>Days Active</th>
                        <th>Utilization</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get uptime by machine
Dim rsUptime, uptimeHours, uptimeCycle, uptimeDays, uptimeUtil, uptimeUtilClass
strSQL2 = "SELECT s.machinenumber, " & _
         "ROUND(SUM(p.cycletime)/3600, 1) as runtime_hours, " & _
         "COUNT(*) as parts_run, " & _
         "ROUND(AVG(p.cycletime)/60, 1) as avg_cycle_min, " & _
         "DATEDIFF(MAX(p.programend), MIN(p.programstart)) + 1 as days_active, " & _
         "MIN(p.programstart) as first_run, " & _
         "MAX(p.programend) as last_run " & _
         "FROM udcparts p " & _
         "JOIN udcsessions s ON p.sessionid = s.sessionid " & _
         whereClause & _
         " AND p.cycletime IS NOT NULL AND p.cycletime > 0 " & _
         "GROUP BY s.machinenumber ORDER BY runtime_hours DESC"
Set rsUptime = objConn.Execute(strSQL2)
If rsUptime.EOF Then
    Response.Write("<tr><td colspan='6' class='text-muted text-center'>No uptime data found</td></tr>")
Else
    Do While Not rsUptime.EOF
        If Not IsNull(rsUptime("runtime_hours")) Then
            uptimeHours = FormatNumber(CDbl(rsUptime("runtime_hours")), 1)
        Else
            uptimeHours = "0"
        End If
        If Not IsNull(rsUptime("avg_cycle_min")) Then
            uptimeCycle = FormatNumber(CDbl(rsUptime("avg_cycle_min")), 1)
        Else
            uptimeCycle = "-"
        End If
        uptimeDays = CLng("0" & rsUptime("days_active"))
        If uptimeDays < 1 Then uptimeDays = 1

        ' Calculate utilization (runtime hours / (days * 16 hours for 2 shifts) * 100)
        If uptimeDays > 0 And Not IsNull(rsUptime("runtime_hours")) Then
            uptimeUtil = Round((CDbl(rsUptime("runtime_hours")) / (uptimeDays * 16)) * 100, 1)
            If uptimeUtil > 100 Then uptimeUtil = 100
        Else
            uptimeUtil = 0
        End If

        ' Color code utilization
        If uptimeUtil >= 70 Then
            uptimeUtilClass = "badge badge-success"
        ElseIf uptimeUtil >= 40 Then
            uptimeUtilClass = "badge badge-warning"
        Else
            uptimeUtilClass = "badge badge-danger"
        End If

        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsUptime("machinenumber") & "") & "'>" & Server.HTMLEncode(rsUptime("machinenumber") & "") & "</a></td>")
        Response.Write("<td><strong>" & uptimeHours & "</strong></td>")
        Response.Write("<td>" & rsUptime("parts_run") & "</td>")
        Response.Write("<td>" & uptimeCycle & "</td>")
        Response.Write("<td>" & uptimeDays & "</td>")
        Response.Write("<td><span class='" & uptimeUtilClass & "'>" & uptimeUtil & "%</span></td>")
        Response.Write("</tr>")
        rsUptime.MoveNext
    Loop
End If
rsUptime.Close
Set rsUptime = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab 9: IT Diagnostics -->
              <div class="tab-pane<%If activeTab="itdiagnostics" Then Response.Write(" active")%>" id="itdiagnostics">
                <h5 class="mb-3">IT Diagnostics</h5>

                <!-- Error Summary by Type -->
                <h6 class="mt-3 mb-2">Error Summary by Type</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Error Type</th>
                        <th>Count</th>
                        <th>Machines Affected</th>
                        <th>Last Occurrence</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get error summary by type
Dim rsErrSummary, errWhereClause, errRowStyle
errWhereClause = " WHERE eventtime >= '" & Replace(filterStart, "'", "''") & "' " & _
                 " AND eventtime <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"
If filterMachine <> "" Then
    errWhereClause = errWhereClause & " AND machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    errWhereClause = errWhereClause & " AND machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If

strSQL2 = "SELECT errortype, COUNT(*) as cnt, COUNT(DISTINCT machinenumber) as machines, MAX(eventtime) as lasttime " & _
         "FROM udcerrors " & errWhereClause & _
         " GROUP BY errortype ORDER BY cnt DESC, errortype ASC LIMIT 10"
Set rsErrSummary = objConn.Execute(strSQL2)
If rsErrSummary.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No errors found in date range</td></tr>")
Else
    Do While Not rsErrSummary.EOF
        If CLng("0" & rsErrSummary("cnt")) > 50 Then
            errRowStyle = "background-color:#dc3545; color:#fff;"
        ElseIf CLng("0" & rsErrSummary("cnt")) > 10 Then
            errRowStyle = "background-color:#ffc107; color:#333;"
        Else
            errRowStyle = ""
        End If
        Response.Write("<tr style='" & errRowStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsErrSummary("errortype") & "") & "</td>")
        Response.Write("<td>" & rsErrSummary("cnt") & "</td>")
        Response.Write("<td>" & rsErrSummary("machines") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsErrSummary("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsErrSummary.MoveNext
    Loop
End If
rsErrSummary.Close
Set rsErrSummary = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Error Summary by Machine -->
                <h6 class="mt-4 mb-2">Errors by Machine</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Total Errors</th>
                        <th>Error Types</th>
                        <th>Last Error</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get errors by machine
Dim rsErrMach, errMachStyle
strSQL2 = "SELECT machinenumber, COUNT(*) as cnt, COUNT(DISTINCT errortype) as types, MAX(eventtime) as lasttime " & _
         "FROM udcerrors " & errWhereClause & _
         " GROUP BY machinenumber ORDER BY cnt DESC, machinenumber ASC LIMIT 10"
Set rsErrMach = objConn.Execute(strSQL2)
If rsErrMach.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No errors found</td></tr>")
Else
    Do While Not rsErrMach.EOF
        If CLng("0" & rsErrMach("cnt")) > 100 Then
            errMachStyle = "background-color:#dc3545; color:#fff;"
        ElseIf CLng("0" & rsErrMach("cnt")) > 25 Then
            errMachStyle = "background-color:#ffc107; color:#333;"
        Else
            errMachStyle = ""
        End If
        Response.Write("<tr style='" & errMachStyle & "'>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsErrMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsErrMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsErrMach("cnt") & "</td>")
        Response.Write("<td>" & rsErrMach("types") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsErrMach("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsErrMach.MoveNext
    Loop
End If
rsErrMach.Close
Set rsErrMach = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Recent Errors -->
                <h6 class="mt-4 mb-2">Recent Errors</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Type</th>
                        <th>Message</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent errors
Dim rsRecentErr, recentErrStyle
strSQL2 = "SELECT eventtime, machinenumber, errortype, errormessage " & _
         "FROM udcerrors " & errWhereClause & _
         " ORDER BY eventtime DESC LIMIT 25"
Set rsRecentErr = objConn.Execute(strSQL2)
If rsRecentErr.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No errors found</td></tr>")
Else
    Do While Not rsRecentErr.EOF
        If InStr(1, rsRecentErr("errortype") & "", "Exception", 1) > 0 Then
            recentErrStyle = "background-color:#dc3545; color:#fff;"
        Else
            recentErrStyle = ""
        End If
        Response.Write("<tr style='" & recentErrStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentErr("eventtime") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentErr("machinenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentErr("errortype") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(Left(rsRecentErr("errormessage") & "", 100)) & "</td>")
        Response.Write("</tr>")
        rsRecentErr.MoveNext
    Loop
End If
rsRecentErr.Close
Set rsRecentErr = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Connection Events -->
                <h6 class="mt-4 mb-2">Connection Events by Machine</h6>
                <div class="table-responsive mb-4">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Machine</th>
                        <th>Total Events</th>
                        <th>COM Ports Used</th>
                        <th>Last Event</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get connection events by machine
Dim rsConnMach, connWhereClause
connWhereClause = " WHERE eventtime >= '" & Replace(filterStart, "'", "''") & "' " & _
                  " AND eventtime <= '" & Replace(filterEnd, "'", "''") & " 23:59:59'"
If filterMachine <> "" Then
    connWhereClause = connWhereClause & " AND machinenumber = '" & Replace(filterMachine, "'", "''") & "'"
End If
If filterBU <> "" Then
    connWhereClause = connWhereClause & " AND machinenumber IN (SELECT machinenumber FROM machines WHERE businessunitid = " & CLng(filterBU) & ")"
End If

strSQL2 = "SELECT machinenumber, COUNT(*) as cnt, COUNT(DISTINCT comport) as ports, MAX(eventtime) as lasttime " & _
         "FROM udcconnections " & connWhereClause & _
         " GROUP BY machinenumber ORDER BY cnt DESC, machinenumber ASC LIMIT 10"
Set rsConnMach = objConn.Execute(strSQL2)
If rsConnMach.EOF Then
    Response.Write("<tr><td colspan='4' class='text-muted text-center'>No connection events found</td></tr>")
Else
    Do While Not rsConnMach.EOF
        Response.Write("<tr>")
        Response.Write("<td><a href='displayudc.asp?machine=" & Server.URLEncode(rsConnMach("machinenumber") & "") & "'>" & Server.HTMLEncode(rsConnMach("machinenumber") & "") & "</a></td>")
        Response.Write("<td>" & rsConnMach("cnt") & "</td>")
        Response.Write("<td>" & rsConnMach("ports") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsConnMach("lasttime") & "") & "</td>")
        Response.Write("</tr>")
        rsConnMach.MoveNext
    Loop
End If
rsConnMach.Close
Set rsConnMach = Nothing
%>
                    </tbody>
                  </table>
                </div>

                <!-- Recent Connection Events -->
                <h6 class="mt-4 mb-2">Recent Connection Events</h6>
                <div class="table-responsive">
                  <table class="table table-hover table-striped table-sm">
                    <thead>
                      <tr>
                        <th>Time</th>
                        <th>Machine</th>
                        <th>Event</th>
                        <th>COM Port</th>
                        <th>Details</th>
                      </tr>
                    </thead>
                    <tbody>
<%
' Get recent connection events
Dim rsRecentConn, connStyle
strSQL2 = "SELECT eventtime, machinenumber, eventtype, comport, details " & _
         "FROM udcconnections " & connWhereClause & _
         " ORDER BY eventtime DESC LIMIT 25"
Set rsRecentConn = objConn.Execute(strSQL2)
If rsRecentConn.EOF Then
    Response.Write("<tr><td colspan='5' class='text-muted text-center'>No connection events found</td></tr>")
Else
    Do While Not rsRecentConn.EOF
        If rsRecentConn("eventtype") & "" = "OPEN" Then
            connStyle = "background-color:#28a745; color:#fff;"
        ElseIf rsRecentConn("eventtype") & "" = "CLOSE" Then
            connStyle = "background-color:#6c757d; color:#fff;"
        Else
            connStyle = ""
        End If
        Response.Write("<tr style='" & connStyle & "'>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentConn("eventtime") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentConn("machinenumber") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentConn("eventtype") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentConn("comport") & "") & "</td>")
        Response.Write("<td>" & Server.HTMLEncode(rsRecentConn("details") & "") & "</td>")
        Response.Write("</tr>")
        rsRecentConn.MoveNext
    Loop
End If
rsRecentConn.Close
Set rsRecentConn = Nothing
%>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- Tab: Historical Trends (from summary tables) -->
              <div class="tab-pane<%If activeTab="trends" Then Response.Write(" active")%>" id="trends">
                <div class="alert mb-3" style="background-color: #e7f3ff; border: 1px solid #b6d4fe; color: #084298;">
                  <strong>Historical Data:</strong> This data comes from daily summaries and includes all historical data beyond the 90-day retention period. Individual measurements are aggregated into daily/weekly/monthly totals.
                </div>

                <!-- Charts Row 1: Monthly Trends -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-info text-white py-2">
                        Monthly Measurement Trend (12 Months)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyMeasChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-danger text-white py-2">
                        Monthly OOT Rate Trend
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyOOTChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Charts Row 2: Production and Response Times -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-success text-white py-2">
                        Monthly Production Trend (Parts)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyPartsChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-warning text-white py-2">
                        Monthly Avg Response Time (seconds)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyResponseChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Charts Row 3: Weekly and Machine Comparison -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-primary text-white py-2">
                        Weekly Measurement Trend (26 Weeks)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="weeklyMeasChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-secondary text-white py-2">
                        All-Time Machine Comparison (Top 15)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="machineHistChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Charts Row 4: CLM-Specific - Violations and Changeover -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header text-white py-2" style="background: linear-gradient(to right, #dc3545, #c82333);">
                        Monthly Parameter Violations (CLM)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyViolChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header text-white py-2" style="background: linear-gradient(to right, #17a2b8, #138496);">
                        Monthly Avg Changeover Time (minutes)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="monthlyChangeoverChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Charts Row 5: Violations by Machine -->
                <div class="row">
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header text-white py-2" style="background: linear-gradient(to right, #6f42c1, #5a32a3);">
                        Violations by Machine (All Time Top 10)
                      </div>
                      <div class="card-body">
                        <div style="height: 250px;">
                          <canvas id="violByMachineChart"></canvas>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-lg-6 mb-3">
                    <div class="card">
                      <div class="card-header bg-gradient-dark text-white py-2">
                        CLM Data Notes
                      </div>
                      <div class="card-body">
                        <p><strong>Parameter Violations:</strong> Tracked when operators change machine parameters outside allowed limits during CLM runs. High violation counts may indicate calibration issues or training needs.</p>
                        <p><strong>Changeover Time:</strong> Time between consecutive part runs on the same machine. Helps identify efficiency opportunities and scheduling patterns.</p>
                        <p class="mb-0 text-muted"><small>Note: CLM data comes from JSON files in CLM_Data folder. Violations and changeover times are only tracked for CLM sessions, not UDC log sessions.</small></p>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Summary Table -->
                <div class="card">
                  <div class="card-header bg-gradient-dark text-white py-2">
                    Monthly Summary Data
                  </div>
                  <div class="card-body">
                    <div class="table-responsive">
                      <table class="table table-sm table-striped table-hover" id="monthlySummaryTable">
                        <thead class="thead-dark">
                          <tr>
                            <th>Month</th>
                            <th>Total Measurements</th>
                            <th>OOT Count</th>
                            <th>OOT Rate</th>
                          </tr>
                        </thead>
                        <tbody>
<%
Dim rsMonthlySummary
strSQL2 = "SELECT yearmonth, SUM(measurement_count) as total_meas, SUM(oot_count) as total_oot, " & _
          "ROUND(SUM(oot_count)*100.0/NULLIF(SUM(measurement_count),0), 2) as oot_rate " & _
          "FROM vwudcmeasurements_monthly "
If filterMachine <> "" Then
    strSQL2 = strSQL2 & "WHERE machinenumber = '" & Replace(filterMachine, "'", "''") & "' "
End If
strSQL2 = strSQL2 & "GROUP BY yearmonth ORDER BY yearmonth DESC LIMIT 24"
Set rsMonthlySummary = objConn.Execute(strSQL2)
Do While Not rsMonthlySummary.EOF
    Dim ootRateVal
    If IsNull(rsMonthlySummary("oot_rate")) Then
        ootRateVal = "0.00"
    Else
        ootRateVal = rsMonthlySummary("oot_rate") & ""
    End If
    Response.Write("<tr>")
    Response.Write("<td>" & Server.HTMLEncode(rsMonthlySummary("yearmonth") & "") & "</td>")
    Response.Write("<td>" & Server.HTMLEncode(FormatNumber(rsMonthlySummary("total_meas"), 0)) & "</td>")
    Response.Write("<td>" & Server.HTMLEncode(FormatNumber(rsMonthlySummary("total_oot"), 0)) & "</td>")
    Response.Write("<td>" & Server.HTMLEncode(ootRateVal) & "%</td>")
    Response.Write("</tr>")
    rsMonthlySummary.MoveNext
Loop
rsMonthlySummary.Close
Set rsMonthlySummary = Nothing
%>
                        </tbody>
                      </table>
                    </div>
                  </div>
                </div>
              </div>

            </div>
          </div>
        </div>
      </div>
    </div>

  </div><!-- End container-fluid -->
</div><!-- End content-wrapper -->

<a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i></a>

<footer class="footer">
  <div class="container"><div class="text-center"></div></div>
</footer>

</div><!-- End wrapper -->

<!-- JavaScript -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
<script src="assets/plugins/Chart.js/Chart.min.js"></script>
<script>
// Tab persistence - update hidden input when tab is clicked
function setActiveTab(tabName) {
    document.getElementById('activeTabInput').value = tabName;
}

// Copy current URL with filters to clipboard
function copyFilterLink(btn) {
    var url = window.location.href;
    var temp = document.createElement('textarea');
    temp.value = url;
    document.body.appendChild(temp);
    temp.select();
    document.execCommand('copy');
    document.body.removeChild(temp);

    // Show toast notification
    showToast();
}

function showToast() {
    var toast = document.getElementById('shareToast');
    toast.style.display = 'block';
    toast.style.animation = 'toastSlideIn 0.3s ease-out';

    setTimeout(function() {
        toast.style.animation = 'toastSlideOut 0.3s ease-out';
        setTimeout(function() {
            toast.style.display = 'none';
        }, 300);
    }, 2500);
}

// Dashboard Charts
$(function() {
    // Chart 1: Production Trend (Line Chart)
    var ctxProd = document.getElementById('productionChart').getContext('2d');
    new Chart(ctxProd, {
        type: 'line',
        data: {
            labels: [<%=prodLabels%>],
            datasets: [{
                label: 'Parts Produced',
                data: [<%=prodData%>],
                backgroundColor: 'rgba(102, 126, 234, 0.2)',
                borderColor: 'rgba(102, 126, 234, 1)',
                borderWidth: 2,
                pointBackgroundColor: 'rgba(102, 126, 234, 1)',
                pointRadius: 4,
                fill: true
            }]
        },
        options: {
            maintainAspectRatio: false,
            legend: { display: false },
            scales: {
                yAxes: [{ ticks: { beginAtZero: true } }],
                xAxes: [{ gridLines: { display: false } }]
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                        return tooltipItem.yLabel + ' parts';
                    }
                }
            }
        }
    });

    // Chart 2: OOT Rate Trend (Line Chart)
    var ctxOOT = document.getElementById('ootChart').getContext('2d');
    new Chart(ctxOOT, {
        type: 'line',
        data: {
            labels: [<%=ootLabels%>],
            datasets: [{
                label: 'OOT Rate %',
                data: [<%=ootRateData%>],
                backgroundColor: 'rgba(220, 53, 69, 0.2)',
                borderColor: 'rgba(220, 53, 69, 1)',
                borderWidth: 2,
                pointBackgroundColor: 'rgba(220, 53, 69, 1)',
                pointRadius: 4,
                fill: true
            }]
        },
        options: {
            maintainAspectRatio: false,
            legend: { display: false },
            scales: {
                yAxes: [{ ticks: { beginAtZero: true, callback: function(value) { return value + '%'; } } }],
                xAxes: [{ gridLines: { display: false } }]
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                        return tooltipItem.yLabel + '% OOT';
                    }
                }
            }
        }
    });

    // Chart 3: Machine Utilization (Horizontal Bar Chart)
    var ctxMach = document.getElementById('machineChart').getContext('2d');
    new Chart(ctxMach, {
        type: 'horizontalBar',
        data: {
            labels: [<%=machLabels%>],
            datasets: [{
                label: 'Runtime Hours',
                data: [<%=machData%>],
                backgroundColor: 'rgba(23, 162, 184, 0.7)',
                borderColor: 'rgba(23, 162, 184, 1)',
                borderWidth: 1
            }]
        },
        options: {
            maintainAspectRatio: false,
            legend: { display: false },
            scales: {
                xAxes: [{ ticks: { beginAtZero: true } }],
                yAxes: [{ gridLines: { display: false } }]
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                        return tooltipItem.xLabel + ' hours';
                    }
                }
            }
        }
    });

    // Chart 4: Top Operators (Horizontal Bar Chart)
    var ctxOps = document.getElementById('operatorChart').getContext('2d');
    new Chart(ctxOps, {
        type: 'horizontalBar',
        data: {
            labels: [<%=opLabels%>],
            datasets: [{
                label: 'Parts Produced',
                data: [<%=opData%>],
                backgroundColor: 'rgba(40, 167, 69, 0.7)',
                borderColor: 'rgba(40, 167, 69, 1)',
                borderWidth: 1
            }]
        },
        options: {
            maintainAspectRatio: false,
            legend: { display: false },
            scales: {
                xAxes: [{ ticks: { beginAtZero: true } }],
                yAxes: [{ gridLines: { display: false } }]
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                        return tooltipItem.xLabel + ' parts';
                    }
                }
            }
        }
    });

    // ========================================
    // Historical Trends Charts (from summaries)
    // ========================================

    // Monthly Measurement Trend
    var ctxMonthlyMeas = document.getElementById('monthlyMeasChart');
    if (ctxMonthlyMeas) {
        new Chart(ctxMonthlyMeas.getContext('2d'), {
            type: 'bar',
            data: {
                labels: [<%=monthlyLabels%>],
                datasets: [{
                    label: 'Measurements',
                    data: [<%=monthlyMeasData%>],
                    backgroundColor: 'rgba(23, 162, 184, 0.7)',
                    borderColor: 'rgba(23, 162, 184, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Monthly OOT Rate Trend
    var ctxMonthlyOOT = document.getElementById('monthlyOOTChart');
    if (ctxMonthlyOOT) {
        new Chart(ctxMonthlyOOT.getContext('2d'), {
            type: 'line',
            data: {
                labels: [<%=monthlyLabels%>],
                datasets: [{
                    label: 'OOT Rate %',
                    data: [<%=monthlyOOTRate%>],
                    backgroundColor: 'rgba(220, 53, 69, 0.2)',
                    borderColor: 'rgba(220, 53, 69, 1)',
                    borderWidth: 2,
                    pointBackgroundColor: 'rgba(220, 53, 69, 1)',
                    pointRadius: 4,
                    fill: true
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true, callback: function(v) { return v + '%'; } } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Weekly Measurement Trend
    var ctxWeeklyMeas = document.getElementById('weeklyMeasChart');
    if (ctxWeeklyMeas) {
        new Chart(ctxWeeklyMeas.getContext('2d'), {
            type: 'line',
            data: {
                labels: [<%=weeklyLabels%>],
                datasets: [{
                    label: 'Measurements',
                    data: [<%=weeklyMeasData%>],
                    backgroundColor: 'rgba(102, 126, 234, 0.2)',
                    borderColor: 'rgba(102, 126, 234, 1)',
                    borderWidth: 2,
                    pointBackgroundColor: 'rgba(102, 126, 234, 1)',
                    pointRadius: 3,
                    fill: true
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Machine Historical Comparison
    var ctxMachHist = document.getElementById('machineHistChart');
    if (ctxMachHist) {
        new Chart(ctxMachHist.getContext('2d'), {
            type: 'horizontalBar',
            data: {
                labels: [<%=machHistLabels%>],
                datasets: [{
                    label: 'Total Measurements',
                    data: [<%=machHistMeas%>],
                    backgroundColor: 'rgba(108, 117, 125, 0.7)',
                    borderColor: 'rgba(108, 117, 125, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    xAxes: [{ ticks: { beginAtZero: true } }],
                    yAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Monthly Parts Production Trend
    var ctxMonthlyParts = document.getElementById('monthlyPartsChart');
    if (ctxMonthlyParts) {
        new Chart(ctxMonthlyParts.getContext('2d'), {
            type: 'bar',
            data: {
                labels: [<%=monthlyPartsLabels%>],
                datasets: [{
                    label: 'Parts Produced',
                    data: [<%=monthlyPartsData%>],
                    backgroundColor: 'rgba(40, 167, 69, 0.7)',
                    borderColor: 'rgba(40, 167, 69, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Monthly Response Time Trend
    var ctxMonthlyResp = document.getElementById('monthlyResponseChart');
    if (ctxMonthlyResp) {
        new Chart(ctxMonthlyResp.getContext('2d'), {
            type: 'line',
            data: {
                labels: [<%=monthlyRespLabels%>],
                datasets: [{
                    label: 'Avg Response (sec)',
                    data: [<%=monthlyRespData%>],
                    backgroundColor: 'rgba(255, 193, 7, 0.2)',
                    borderColor: 'rgba(255, 193, 7, 1)',
                    borderWidth: 2,
                    pointBackgroundColor: 'rgba(255, 193, 7, 1)',
                    pointRadius: 4,
                    fill: true
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true, callback: function(v) { return v + 's'; } } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // ========================================
    // CLM-Specific Charts
    // ========================================

    // Monthly Violations Trend (CLM)
    var ctxMonthlyViol = document.getElementById('monthlyViolChart');
    if (ctxMonthlyViol) {
        new Chart(ctxMonthlyViol.getContext('2d'), {
            type: 'bar',
            data: {
                labels: [<%=monthlyViolLabels%>],
                datasets: [{
                    label: 'Violations',
                    data: [<%=monthlyViolData%>],
                    backgroundColor: 'rgba(220, 53, 69, 0.7)',
                    borderColor: 'rgba(220, 53, 69, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Monthly Changeover Time Trend
    var ctxMonthlyChg = document.getElementById('monthlyChangeoverChart');
    if (ctxMonthlyChg) {
        new Chart(ctxMonthlyChg.getContext('2d'), {
            type: 'line',
            data: {
                labels: [<%=monthlyChgLabels%>],
                datasets: [{
                    label: 'Avg Changeover (min)',
                    data: [<%=monthlyChgData%>],
                    backgroundColor: 'rgba(23, 162, 184, 0.2)',
                    borderColor: 'rgba(23, 162, 184, 1)',
                    borderWidth: 2,
                    pointBackgroundColor: 'rgba(23, 162, 184, 1)',
                    pointRadius: 4,
                    fill: true
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true, callback: function(v) { return v + ' min'; } } }],
                    xAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }

    // Violations by Machine (Horizontal Bar)
    var ctxViolMach = document.getElementById('violByMachineChart');
    if (ctxViolMach) {
        new Chart(ctxViolMach.getContext('2d'), {
            type: 'horizontalBar',
            data: {
                labels: [<%=violMachLabels%>],
                datasets: [{
                    label: 'Violations',
                    data: [<%=violMachData%>],
                    backgroundColor: 'rgba(111, 66, 193, 0.7)',
                    borderColor: 'rgba(111, 66, 193, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                maintainAspectRatio: false,
                legend: { display: false },
                scales: {
                    xAxes: [{ ticks: { beginAtZero: true } }],
                    yAxes: [{ gridLines: { display: false } }]
                }
            }
        });
    }
});
</script>

</body>
</html>
<%
objConn.Close
%>
