<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <base href="{{ base_path }}">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>PrintLab</title>
  <link rel="icon" type="image/svg+xml" href="static/PrintLab-Logo.svg">
  <style>
    :root {
      --primary: #152044;
      --accent: #24325f;
      --border: #c7cdd9;
      --bg: #f5f7fb;
      --white: #ffffff;
      --text: #1f1f1f;
    }
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
      color: var(--text);
      background: var(--bg);
    }
    button {
      cursor: pointer;
      font-family: inherit;
    }
    /* Login */
    #login-screen {
      display: flex;
      min-height: 100vh;
    }
    .login-left {
      flex: 1;
      background: #000;
      color: #fff;
      padding: 48px;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
    }
    .login-left h1 {
      margin: 0;
      font-size: 46px;
      line-height: 1.1;
    }
    .login-form {
      max-width: 360px;
      margin-top: 40px;
    }
    .login-form label {
      display: block;
      font-size: 14px;
      color: #c5c5c5;
      margin-bottom: 4px;
    }
    .login-form input:not([type="checkbox"]) {
      width: 100%;
      padding: 10px 12px;
      border: none;
      border-bottom: 1px solid #444;
      background: #000;
      color: #fff;
      outline: none;
      margin-bottom: 18px;
    }
    .password-field {
      position: relative;
      display: flex;
      align-items: center;
    }
    .password-field input {
      padding-right: 44px;
      margin-bottom: 0;
    }
    .password-toggle {
      position: absolute;
      right: 6px;
      background: none;
      border: none;
      padding: 4px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .password-toggle img {
      height: 20px;
      width: 20px;
      pointer-events: none;
    }
    .login-form .remember {
      display: flex;
      align-items: center;
      gap: 8px;
      color: #c5c5c5;
      margin-bottom: 16px;
      font-size: 14px;
    }
    .login-form .remember input {
      width: auto;
      height: auto;
      margin: 0;
    }
    .login-actions button {
      width: 100%;
      padding: 12px;
      margin-bottom: 10px;
      border-radius: 6px;
      border: 1px solid #fff;
      background: #fff;
      color: #000;
      font-weight: 600;
    }
    .login-actions .outline {
      background: #000;
      color: #fff;
      border-color: #fff;
    }
    .login-error {
      color: #ff6b6b;
      font-size: 13px;
      margin-top: 6px;
      display: none;
    }
    .login-logo {
      max-width: 220px;
    }
    .login-right {
      flex: 1;
      background: var(--bg);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 24px;
    }
    .login-right img {
      max-width: 100%;
      height: auto;
      border-radius: 8px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.08);
    }
    /* App shell */
    #app-shell {
      display: none;
      min-height: 100vh;
    }
    .shell {
      display: grid;
      grid-template-columns: 160px 1fr;
      min-height: 100vh;
    }
    .sidebar {
      background: #eef2fb;
      padding: 16px 12px;
      border-right: 1px solid var(--border);
    }
    .sidebar h3 {
      margin: 0 0 12px 0;
      color: var(--primary);
      font-size: 15px;
      text-align: center;
    }
    .side-btn {
      width: 100%;
      border: 1px solid var(--border);
      background: var(--white);
      color: var(--primary);
      padding: 10px 8px;
      margin-bottom: 8px;
      border-radius: 8px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 6px;
      font-size: 12px;
    }
    .side-btn img {
      height: 26px;
      width: 26px;
    }
    .side-btn[data-target="relatorio"] { display: none !important; }
    .content {
      padding: 24px;
    }
    .card {
      background: var(--white);
      border: 1px solid var(--border);
      border-radius: 10px;
      padding: 18px;
      box-shadow: 0 8px 20px rgba(0,0,0,0.05);
    }
    .form-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 12px;
      margin-top: 8px;
    }
    .field label {
      display: block;
      font-size: 13px;
      margin-bottom: 4px;
      color: var(--primary);
    }
    .field input, .field select {
      width: 100%;
      padding: 10px 12px;
      border: 1px solid var(--border);
      border-radius: 6px;
      background: #fbfbfd;
      font-size: 14px;
    }
    .table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 12px;
    }
    .table th, .table td {
      border: 1px solid var(--border);
      padding: 10px 8px;
      text-align: center;
      font-size: 13px;
    }
    .table th {
      background: #f0f2f8;
      color: var(--primary);
      font-weight: 600;
    }
    .chat-layout {
      display: grid;
      grid-template-columns: 1.2fr 0.8fr;
      gap: 16px;
      margin-top: 12px;
    }
    .list-card {
      border: 1px solid var(--border);
      border-radius: 10px;
      background: var(--white);
      padding: 14px;
      box-shadow: 0 6px 16px rgba(0,0,0,0.05);
    }
    .list-card h4 {
      margin: 0 0 10px 0;
      color: var(--primary);
    }
    .user-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 8px 0;
      border-bottom: 1px solid #eceff6;
      font-size: 14px;
    }
    .user-row:last-child { border-bottom: none; }
    .user-meta {
      display: flex;
      align-items: center;
      gap: 8px;
      color: #2b3553;
    }
    .status-dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: #c7cdd9;
    }
    .status-dot.online { background: #1cc88a; }
    .pill {
      padding: 4px 10px;
      border-radius: 999px;
      background: #e7f5ed;
      color: #1b864c;
      font-size: 12px;
      border: 1px solid #c6e6d3;
    }
    .chat-window {
      display: flex;
      flex-direction: column;
      gap: 10px;
      border: 1px solid var(--border);
      border-radius: 10px;
      padding: 12px;
      background: #f9fbff;
      height: 380px;
    }
    .chat-messages {
      flex: 1;
      overflow-y: auto;
      display: flex;
      flex-direction: column;
      gap: 8px;
      padding-right: 4px;
    }
    .bubble {
      max-width: 70%;
      padding: 10px 12px;
      border-radius: 12px;
      background: #eef2fb;
      align-self: flex-start;
      box-shadow: 0 2px 6px rgba(0,0,0,0.05);
      display: inline-flex;
      flex-direction: column;
      gap: 4px;
    }
    .bubble.me {
      background: #152044;
      color: #fff;
      align-self: flex-end;
    }
    .bubble .meta {
      font-size: 11px;
      color: #6b7280;
    }
    .bubble.me .meta { color: #c7d1ff; }
    .chat-input {
      display: flex;
      gap: 8px;
    }
    .chat-input textarea {
      flex: 1;
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 10px;
      font-family: inherit;
      background: #fff;
      min-height: 64px;
      resize: vertical;
    }
    .actions {
      margin-top: 12px;
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
    }
    .icon-btn {
      border: 1px solid var(--border);
      background: #fff;
      border-radius: 6px;
      padding: 8px 12px;
      display: inline-flex;
      align-items: center;
      gap: 6px;
      color: var(--primary);
    }
    .summary {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 12px;
      margin-top: 16px;
    }
    /* Agenda */
    .agenda-shell {
      display: grid;
      grid-template-columns: 1.3fr 0.8fr;
      gap: 18px;
    }
    .agenda-header {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      align-items: center;
      gap: 12px;
      margin-bottom: 12px;
    }
    .agenda-month {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      font-weight: 700;
      color: var(--primary);
    }
    .agenda-month button {
      border: 1px solid var(--border);
      background: var(--white);
      border-radius: 8px;
      padding: 8px 10px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      font-weight: 700;
      color: var(--primary);
    }
    .agenda-month .prev-btn { justify-self: start; }
    .agenda-month .next-btn { justify-self: end; }
    .agenda-grid {
      background: #E6E7E8;
      border-radius: 16px;
      padding: 14px;
      box-shadow: inset 0 0 0 1px #1d2658, 0 12px 26px rgba(0,0,0,0.12);
    }
    .agenda-days {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 10px;
    }
    .agenda-day {
      position: relative;
      min-height: 110px;
      background: #D2D3D5;
      border: 1px solid #232d68;
      border-radius: 14px;
      padding: 10px;
      color: #727376;
      box-shadow: 0 6px 18px rgba(0,0,0,0.2), inset 0 0 0 1px rgba(255,255,255,0.03);
      cursor: pointer;
      transition: transform 0.08s ease, border-color 0.12s ease, box-shadow 0.12s ease;
    }
    .agenda-day:hover {
      transform: translateY(-2px);
      border-color: #4d63ff;
      box-shadow: 0 10px 24px rgba(0,0,0,0.22);
    }
    .agenda-day.muted {
      opacity: 0.85;
      background: #BDBFC1;
      color: #A9ABAE;
    }
    .agenda-date {
      font-size: 18px;
      font-weight: 700;
      color: #727376;
    }
    .agenda-day.muted .agenda-date {
      color: #A9ABAE;
    }
    .agenda-events {
      margin-top: 6px;
      display: flex;
      flex-direction: column;
      gap: 6px;
    }
    .agenda-event {
      display: flex;
      align-items: center;
      gap: 6px;
      padding: 6px 8px;
      border-radius: 10px;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.08);
      color: #fff;
      font-size: 12px;
    }
    .agenda-dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      flex-shrink: 0;
    }
    .agenda-legend {
      display: flex;
      align-items: center;
      gap: 14px;
      font-size: 12px;
      margin-top: 10px;
      color: #4b5670;
    }
    .agenda-legend span {
      display: inline-flex;
      align-items: center;
      gap: 6px;
    }
    .agenda-weeklist {
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    .agenda-week-card {
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      background: #f8f9fe;
      box-shadow: 0 6px 16px rgba(0,0,0,0.06);
    }
    .agenda-week-card h4 {
      margin: 0 0 8px 0;
      color: var(--primary);
      font-size: 14px;
    }
    .agenda-week-card ul {
      margin: 0;
      padding-left: 16px;
      color: #3c4462;
      display: grid;
      gap: 4px;
    }
    .agenda-empty {
      color: #778;
      font-size: 13px;
    }
    .upper-input {
      text-transform: uppercase;
    }
    .agenda-visita-actions {
      display: flex;
      justify-content: flex-end;
      margin-top: 6px;
    }
    .agenda-visita-actions .actions {
      margin-top: 0;
    }
    .agenda-visita-note {
      font-size: 12px;
      color: #6b7280;
      margin-top: 4px;
    }
    .agenda-visita-textarea {
      min-height: 140px;
    }
    /* CRM */
    .crm-layout {
      display: grid;
      grid-template-columns: 1fr 1.2fr;
      gap: 16px;
      margin-top: 12px;
    }
    .crm-board {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
      gap: 10px;
    }
    .crm-card {
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      background: #f9fbff;
      box-shadow: 0 6px 14px rgba(0,0,0,0.05);
    }
    .crm-card h4 {
      margin: 0 0 6px 0;
      color: var(--primary);
      font-size: 14px;
    }
    .crm-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 10px;
    }
    .crm-table th, .crm-table td {
      border: 1px solid var(--border);
      padding: 8px;
      font-size: 13px;
      text-align: left;
    }
    .crm-table th {
      background: #eef2fb;
      color: var(--primary);
      font-weight: 700;
    }
    .crm-actions {
      display: flex;
      align-items: center;
      gap: 10px;
      flex-wrap: wrap;
    }
    /* Financeiro */
    .finance-layout {
      display: grid;
      grid-template-columns: 210px 1fr;
      gap: 16px;
      align-items: start;
    }
    .finance-subnav {
      background: #eef2fb;
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    .finance-subnav .sub-btn {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 12px;
      border: 1px solid var(--border);
      background: #fff;
      border-radius: 10px;
      font-weight: 600;
      color: var(--primary);
      text-align: left;
    }
    .finance-subnav .sub-btn img {
      width: 24px;
      height: 24px;
    }
    .finance-subnav .sub-btn.active {
      background: var(--primary);
      color: #fff;
      border-color: var(--primary);
    }
    .finance-panel {
      display: flex;
      flex-direction: column;
      gap: 14px;
    }
    .status-summary {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 10px;
    }
    .status-card {
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #fbfbfd;
    }
    .status-pill {
      padding: 6px 12px;
      border-radius: 999px;
      color: #fff;
      font-weight: 700;
      font-size: 12px;
      display: inline-flex;
      align-items: center;
      gap: 6px;
      background: #c7cdd9;
    }
    .status-pill.liq { background: #5CA47A; }
    .status-pill.avencer { background: #51A8B1; }
    .status-pill.vencido { background: #F8AC92; }
    .status-pill.bloq { background: #C37377; }
    .parcel-list {
      border: 1px dashed var(--border);
      border-radius: 10px;
      padding: 12px;
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
      gap: 10px;
    }
    .parcel-row {
      display: grid;
      grid-template-columns: 1fr 0.9fr;
      gap: 8px;
      align-items: end;
    }
    .finance-note {
      background: #f7fafc;
      border: 1px solid #d9e2ef;
      border-radius: 10px;
      padding: 10px 12px;
      font-size: 13px;
      color: #425466;
    }
    @media (max-width: 960px) {
      .finance-layout {
        grid-template-columns: 1fr;
      }
      .finance-subnav {
        flex-direction: row;
        flex-wrap: wrap;
      }
      .finance-subnav .sub-btn {
        flex: 1 1 150px;
      }
    }
    /* Modal */
    .modal-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.55);
      display: none;
      align-items: center;
      justify-content: center;
      padding: 16px;
      z-index: 10;
    }
    /* Popups usados sobre o pedido de venda */
    #produto-search-modal, #cliente-search-modal {
      z-index: 40;
    }
    #status-modal {
      z-index: 50;
    }
    #status-choices {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin: 0 0 6px 0;
      padding: 0;
    }
    /* Popups de vinculo de pedido na OP */
    #pedido-ref-modal, #pedido-items-modal {
      z-index: 60;
    }
    #whats-modal {
      z-index: 70;
    }
    .modal {
      background: #fff;
      border-radius: 10px;
      width: 100%;
      max-width: 420px;
      box-shadow: 0 12px 30px rgba(0,0,0,0.16);
      padding: 20px;
      border: 1px solid var(--border);
    }
    .modal h3 {
      margin: 0 0 12px 0;
      color: var(--primary);
    }
    .modal .field {
      margin-bottom: 12px;
    }
    .modal .actions {
      justify-content: flex-end;
    }
    .modal .error {
      color: #b00020;
      font-size: 13px;
      margin-bottom: 8px;
      display: none;
    }
    .modal .success {
      color: #0a7c2f;
      font-size: 13px;
      margin-bottom: 8px;
      display: none;
    }
    /* Pedido de Venda Modal */
    #pedido-modal {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.55);
      display: none;
      align-items: center;
      justify-content: center;
      padding: 16px;
      z-index: 20;
    }
    .pedido-modal-inner {
      background: #fff;
      border-radius: 12px;
      width: 100%;
      max-width: 1250px;
      max-height: 90vh;
      overflow-y: auto;
      box-shadow: 0 14px 40px rgba(0,0,0,0.18);
      border: 1px solid var(--border);
      padding: 24px;
    }
    .pedido-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 12px;
      margin-bottom: 12px;
    }
    .close-btn {
      border: 1px solid var(--border);
      background: #fff;
      border-radius: 6px;
      padding: 6px 10px;
      color: var(--primary);
    }
    .pedido-grid {
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .pedido-grid .field textarea {
      width: 100%;
      min-height: 72px;
      padding: 10px 12px;
      border: 1px solid var(--border);
      border-radius: 6px;
      background: #fbfbfd;
      font-size: 14px;
      resize: vertical;
    }
    .items-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 8px;
    }
    .items-table thead { display: none; }
    .items-table tbody tr {
      display: grid;
      grid-template-columns: 1fr;
      gap: 10px;
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      margin-bottom: 10px;
      background: #f9fbff;
    }
    .items-table td {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      border: none;
      padding: 0;
      text-align: left;
      font-size: 13px;
    }
    .items-table td::before {
      content: attr(data-label);
      font-size: 12px;
      color: var(--primary);
      font-weight: 600;
      margin-bottom: 4px;
    }
    .inline-input {
      width: 100%;
      padding: 8px 10px;
      border: 1px solid var(--border);
      border-radius: 6px;
      background: #fbfbfd;
      font-size: 13px;
    }
    #pv-cliente,
    #pv-contato,
    #pv-endereco,
    input[data-field="material"],
    input[data-field="descricao"] {
      text-transform: uppercase;
    }
    /* Cadastro de produto */
    .produto-form-shell {
      border: 1px solid var(--border);
      border-radius: 12px;
      background: #f6f8fc;
      padding: 14px;
      margin: 14px 0;
      box-shadow: 0 8px 18px rgba(0,0,0,0.06);
    }
    .produto-form-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      flex-wrap: wrap;
    }
    .produto-form-head h3 {
      margin: 0;
      color: var(--primary);
    }
    .produto-form-actions {
      display: flex;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
    }
    .produto-form-scroll {
      display: flex;
      flex-direction: column;
      gap: 12px;
      margin-top: 10px;
    }
    .produto-block {
      background: #fff;
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 12px;
      box-shadow: 0 6px 14px rgba(0,0,0,0.04);
    }
    .produto-block + .produto-block {
      margin-top: 8px;
    }
    .produto-block .block-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
      flex-wrap: wrap;
      margin-bottom: 8px;
    }
    .produto-block h4 {
      margin: 0;
      color: var(--primary);
    }
    .produto-row {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
      gap: 10px;
    }
    .produto-card {
      background: #f9fbff;
      border: 1px solid var(--border);
      border-radius: 10px;
      padding: 10px;
      display: flex;
      flex-direction: column;
      gap: 8px;
      min-height: 72px;
    }
    .produto-card .title {
      font-size: 13px;
      font-weight: 600;
      color: var(--primary);
    }
    .produto-card .inline-group {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
      align-items: center;
    }
    .produto-card .inline-group input[type="text"] {
      flex: 1;
    }
    .produto-card .options {
      display: flex;
      flex-wrap: wrap;
      gap: 10px 14px;
      font-size: 13px;
    }
    .produto-card .options label {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      cursor: pointer;
    }
    .produto-card textarea {
      width: 100%;
      min-height: 60px;
      border: 1px solid var(--border);
      border-radius: 6px;
      padding: 8px 10px;
      font-family: inherit;
      background: #fbfbfd;
      resize: vertical;
    }
    .produto-actions-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
      margin-top: 8px;
    }
    .produto-table-like {
      width: 100%;
      border: 1px solid var(--border);
      border-radius: 10px;
      overflow: hidden;
      background: #fff;
    }
    .produto-table-like table {
      width: 100%;
      border-collapse: collapse;
    }
    .produto-table-like th,
    .produto-table-like td {
      border-bottom: 1px solid var(--border);
      padding: 10px;
      text-align: left;
      font-size: 13px;
    }
    .produto-table-like th {
      background: #f2f4f9;
      color: var(--primary);
    }
    .produto-table-like tr:last-child td {
      border-bottom: none;
    }
    /* Produto popup */
    #produto-form-modal {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.55);
      display: none;
      align-items: center;
      justify-content: center;
      padding: 16px;
      z-index: 30;
    }
    .produto-form-inner {
      background: #fff;
      border-radius: 12px;
      width: 100%;
      max-width: 1280px;
      max-height: 90vh;
      overflow-y: auto;
      box-shadow: 0 14px 40px rgba(0,0,0,0.18);
      border: 1px solid var(--border);
      padding: 20px;
    }
    .produto-form-inner .popup-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
      margin-bottom: 10px;
    }
    .pedido-actions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin-top: 14px;
      justify-content: flex-end;
    }
    .config-grid {
      display: grid;
      grid-template-columns: 1.1fr 1fr;
      gap: 16px;
      align-items: start;
    }
    .muted {
      color: #6b7280;
      font-size: 13px;
    }
    .primary-btn, .ghost-btn {
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 10px 14px;
      font-weight: 600;
      display: inline-flex;
      align-items: center;
      gap: 8px;
    }
    .primary-btn {
      background: var(--primary);
      color: #fff;
      border-color: var(--primary);
    }
    .ghost-btn {
      background: #fff;
      color: var(--primary);
    }
    .divider {
      height: 1px;
      background: var(--border);
      margin: 14px 0;
    }
    .small-muted {
      color: #6b7280;
      font-size: 12px;
    }
    .ordem-img-wrap {
      max-height: 70vh;
      overflow: auto;
    }
    #ordem-img-preview {
      width: 100%;
      max-width: 100%;
      height: auto;
      display: block;
    }
  </style>
</head>
<body>
  <!-- LOGIN -->
  <section id="login-screen">
    <div class="login-left">
      <div>
        <h1>Oi,<br> Tudo bem?</h1>
        <div class="login-form">
          <label for="user">Usuario</label>
          <input id="user" type="text" placeholder="Seu usuario">
          <label for="pass">Senha</label>
          <div class="password-field">
            <input id="pass" type="password" placeholder="Senha">
            <button type="button" class="password-toggle" id="pass-toggle" aria-label="Mostrar senha">
              <img src="static/icone_mostrar_fundo_branco.svg" alt="Mostrar senha" id="pass-toggle-icon">
            </button>
          </div>
          <label class="remember">
            <input type="checkbox" id="remember"> Lembrar
          </label>
          <div id="login-error" class="login-error"></div>
          <div class="login-actions">
            <button id="btn-login">LOGIN</button>
          </div>
        </div>
      </div>
      <img src="static/PrintLab-Logo-Branco.svg" alt="PrintLab" class="login-logo">
    </div>
    <div class="login-right">
      <img src="static/fundo_lateral_tela_login.jpg" alt="Ilustracao inicial">
    </div>
  </section>

  <!-- REGISTER MODAL -->
  <div class="modal-backdrop" id="register-modal">
    <div class="modal">
      <h3>Novo cadastro</h3>
      <div class="error" id="register-error"></div>
      <div class="success" id="register-success"></div>
      <div class="field">
        <label>Nome</label>
        <input type="text" id="reg-name" placeholder="Seu nome">
      </div>
      <div class="field">
        <label>Email</label>
        <input type="email" id="reg-email" placeholder="email@exemplo.com">
      </div>
      <div class="field">
        <label>Usuario</label>
        <input type="text" id="reg-user" placeholder="usuario">
      </div>
      <div class="field">
        <label>Senha</label>
        <input type="password" id="reg-pass" placeholder="Senha">
      </div>
      <div class="field">
        <label>Perfil</label>
        <select id="reg-role">
          <option value="Administrador">Administrador</option>
          <option value="Atendimento">Atendimento</option>
          <option value="Designer">Designer</option>
          <option value="Producao">Producao</option>
          <option value="Financeiro">Financeiro</option>
          <option value="Recursos Humanos">Recursos Humanos</option>
        </select>
      </div>
      <div class="actions">
        <button class="outline" id="reg-cancel">Cancelar</button>
        <button id="reg-save">Salvar</button>
      </div>
    </div>
  </div>

  <!-- PEDIDO DE VENDA MODAL -->
  <div id="pedido-modal">
    <div class="pedido-modal-inner">
      <div class="pedido-head">
        <div>
          <h2 style="margin:0; color:var(--primary)">Emitir Pedido de Venda</h2>
          <div id="pedido-alert" class="small-muted"></div>
        </div>
        <button class="close-btn" id="pedido-close">Fechar</button>
      </div>
      <div class="pedido-grid">
        <div class="field">
          <label>Número Pedido de Venda</label>
          <input type="text" id="pv-numero" class="inline-input" readonly>
        </div>
        <div class="field">
          <label>EMISSOR</label>
          <input type="text" id="pv-emissor" class="inline-input" readonly>
        </div>
        <div class="field">
          <label>DATA EMISSÃO</label>
          <input type="text" id="pv-data" class="inline-input" readonly>
        </div>
        <div class="field">
          <label>Designer</label>
          <select id="pv-designer" class="inline-input">
            <option value="">Selecione</option>
            <option>Gregori</option>
            <option>Karoline</option>
            <option>Adriana</option>
            <option>Beatriz</option>
          </select>
        </div>
        <div class="field" id="pv-tipo-field" style="display:none;">
          <label>Tipo</label>
          <select id="pv-tipo" class="inline-input">
            <option>Pedido de Venda</option>
            <option>Ordem de Produção</option>
            <option>Amostra</option>
            <option>Doação</option>
            <option>Reposição</option>
            <option>Interno</option>
          </select>
        </div>
        <div class="field">
          <label>CLIENTE</label>
          <div style="display:flex; gap:8px;">
            <input type="text" id="pv-cliente" class="inline-input" placeholder="Nome do cliente">
            <button class="ghost-btn" id="pv-busca-cliente"><img src="static/icone_pesquisa.svg" alt="" height="16">Buscar</button>
          </div>
        </div>
        <div class="field">
          <label>CONTATO</label>
          <input type="text" id="pv-contato" class="inline-input" placeholder="Nome do contato">
        </div>
        <div class="field">
          <label>TELEFONE</label>
          <input type="text" id="pv-telefone" class="inline-input" placeholder="Telefone">
        </div>
        <div class="field" id="pv-orc-field" style="display:none;">
          <label>Importar Orçamento</label>
          <div style="display:flex; gap:8px;">
            <input type="text" id="pv-orc-ref" class="inline-input" placeholder="Número do orçamento">
            <button class="ghost-btn" type="button" id="pv-orc-buscar"><img src="static/icone_pesquisa.svg" alt="" height="16">Buscar</button>
          </div>
          <div class="small-muted" id="pv-orc-hint"></div>
        </div>
        <div class="field" id="pv-pedido-ref-field" style="display:none;">
          <label>Vincular Pedido de Venda</label>
          <div style="display:flex; gap:8px;">
            <input type="text" id="pv-pedido-ref" class="inline-input" placeholder="Número do pedido de venda">
            <button class="ghost-btn" type="button" id="pv-pedido-buscar"><img src="static/icone_pesquisa.svg" alt="" height="16">Buscar</button>
          </div>
          <div class="small-muted" id="pv-pedido-hint"></div>
        </div>
      </div>

      <div class="divider"></div>
      <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
        <h3 style="margin:0; color:var(--primary)">Itens</h3>
        <button class="ghost-btn" id="pv-add-item"><img src="static/icone_novo_emissor.svg" alt="" height="16">Adicionar item</button>
      </div>
      <table class="items-table" id="pv-items-table">
        <thead>
          <tr>
            <th>ITEM</th>
            <th>Produto</th>
            <th>MATERIAL</th>
            <th>DESCRIÇÃO</th>
            <th>Unidade</th>
            <th>Arquivo</th>
            <th>QUANTIDADE</th>
            <th>PREÇO UNITÁRIO (R$)</th>
            <th>SUBTOTAL</th>
          </tr>
        </thead>
        <tbody id="pv-items-body"></tbody>
      </table>
      <div class="small-muted">Subtotal = Quantidade x Preco Unitario. Total inclui entrega quando aplicavel.</div>

      <div class="divider"></div>
      <div class="pedido-grid">
        <div class="field">
          <label>OBSERVAÇÃO</label>
          <textarea id="pv-observacao" maxlength="300" placeholder="Ate 300 caracteres"></textarea>
        </div>
        <div class="field">
          <label>Imagem (JPG, max 1 MB)</label>
          <input type="file" id="pv-imagem" accept="image/jpeg">
          <div class="small-muted" id="pv-img-hint"></div>
          <img id="pv-img-preview" alt="Imagem do pedido" style="max-width: 240px; max-height: 180px; object-fit: contain; margin-top: 8px; border: 1px solid var(--border); border-radius: 6px; display: none;">
        </div>
        <div class="field">
          <label>ENTREGA</label>
          <select id="pv-entrega" class="inline-input">
            <option value="Cliente">Cliente</option>
            <option value="Balcão">Balcão</option>
          </select>
        </div>
        <div class="field">
          <label>PREÇO ENTREGA</label>
          <input type="text" id="pv-preco-entrega" class="inline-input" placeholder="0,00">
        </div>
        <div class="field">
          <label>ENDEREÇO</label>
          <input type="text" id="pv-endereco" class="inline-input" placeholder="Endereco de entrega">
        </div>
        <div class="field">
          <label>Forma de Pagamento</label>
          <select id="pv-forma" class="inline-input">
            <option value="">Selecione</option>
            <option>A vista - PIX</option>
            <option>A vista - Dinheiro</option>
            <option>A vista - Cartao de Debito</option>
            <option>Cartao de Credito</option>
            <option>Boleto bancario</option>
          </select>
        </div>
        <div class="field">
          <label>Condicao de Pagamento</label>
          <select id="pv-condicao" class="inline-input">
            <option value="">Selecione</option>
          </select>
        </div>
        <div class="field">
          <label>PRAZO DE ENTREGA</label>
          <input type="datetime-local" id="pv-prazo" class="inline-input">
        </div>
        <div class="field">
          <label>TOTAL</label>
          <input type="text" id="pv-total" class="inline-input" readonly>
        </div>
      </div>

      <div class="pedido-actions">
        <div style="display:flex; gap:8px; flex-wrap:wrap;">
          <button class="ghost-btn" id="pv-export"><img src="static/icone_arquivo.svg" alt="" height="16">Exportar PDF</button>
          <button class="ghost-btn" id="pv-whats"><img src="static/icone_whats.svg" alt="" height="16">Whatsapp</button>
        </div>
        <button class="primary-btn" id="pv-save"><img src="static/icone_arquivo.svg" alt="" height="16">Salvar Pedido</button>
      </div>
    </div>
  </div>

  <!-- BUSCA PRODUTO -->
  <div class="modal-backdrop" id="produto-search-modal">
    <div class="modal">
      <h3>Buscar produto</h3>
      <div class="field">
        <label>Termo</label>
        <input type="text" id="prod-search-term" placeholder="Material ou descricao">
      </div>
      <div class="field">
        <label>Resultados</label>
        <div id="prod-search-results" class="list-card" style="max-height:220px; overflow:auto; padding:8px;"></div>
      </div>
      <div class="actions">
        <button class="ghost-btn" id="prod-search-cancel">Cancelar</button>
        <button class="primary-btn" id="prod-search-apply">Usar selecionado</button>
      </div>
      <div class="muted" id="prod-search-hint"></div>
    </div>
  </div>

  <!-- PRODUTO FORM POPUP -->
  <div id="produto-form-modal">
    <div class="produto-form-inner">
      <div class="popup-head">
        <h3 style="margin:0; color:var(--primary)">Cadastro de produto</h3>
        <div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
          <button class="primary-btn" type="button" id="produto-form-apply">Aplicar no item</button>
          <button class="close-btn" id="produto-form-close">Fechar</button>
        </div>
      </div>
      <div class="produto-form-shell" style="box-shadow:none; border:none; padding:0; margin:0;">
        <div class="produto-form-head">
          <h3 style="margin:0;">Detalhes do produto</h3>
          <div class="produto-form-actions">
            <input type="search" class="inline-input" style="max-width:220px;" placeholder="Buscar campo">
            <button class="ghost-btn" type="button" id="produto-form-clear">Limpar</button>
          </div>
        </div>
        <div class="produto-form-scroll">
          <div class="produto-block" id="form-impressao">
            <div class="block-head">
              <h4>Impressao</h4>
              <input type="search" class="inline-input" style="max-width:200px;" placeholder="Start typing...">
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tipo:</div>
                <select class="inline-input" id="pf-tipo">
                  <option>Tipo de Impressão</option>
                  <option>Cópia</option>
                  <option>Impressão</option>
                  <option>Digitalização</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Cor:</div>
                <select class="inline-input" id="pf-cor">
                  <option>Escolha cor</option>
                  <option>4x0 (Frente)</option>
                  <option>1x0 (Frente)</option>
                  <option>4x4 (Frente x Verso)</option>
                  <option>1x1 (Frente x Verso)</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Papel:</div>
                <select class="inline-input" id="pf-papel">
                  <option>Escolha papel</option>
                  <option>Sulfite 75 gramas</option>
                  <option>Offset 90 gramas</option>
                  <option>Offset 120 gramas</option>
                  <option>Offset 150 gramas</option>
                  <option>Offset 180 gramas</option>
                  <option>Offset 230 gramas</option>
                  <option>Couchê 120 gramas</option>
                  <option>Couchê 150 gramas</option>
                  <option>Couchê 180 gramas</option>
                  <option>Couchê 250 gramas</option>
                  <option>Couchê 300 gramas</option>
                  <option>Sulfite Azul 75 gramas</option>
                  <option>Reciclado 120 gramas</option>
                  <option>Reciclado 230 gramas</option>
                  <option>Aspen 230 gramas</option>
                  <option>Linho 230 gramas</option>
                  <option>Poliéster</option>
                  <option>Transparência</option>
                  <option>Transfer Laser</option>
                  <option>Transfer Sublimático</option>
                  <option>Adesivo Papel Fosco</option>
                  <option>Adesivo Papel Brilho</option>
                  <option>Adesivo Vinil Transparente</option>
                  <option>Adesivo Vinil Branco</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Encadernacao:</div>
                <select class="inline-input" id="pf-encad">
                  <option>Escolha encadernação</option>
                  <option>Encadernação Espiral Preto</option>
                  <option>Encadernação Espiral Transparente</option>
                  <option>Encadernação Airô Preto</option>
                  <option>Encadernação Airô Branco</option>
                  <option>Encadernação Capa Dura</option>
                  <option>Blocado</option>
                  <option>Grampo Canoa</option>
                  <option>Encadernação Colada</option>
                </select>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tamanho:</div>
                <div class="options">
                  <label><input type="radio" name="imp-tam" value="A6" checked> A6</label>
                  <label><input type="radio" name="imp-tam" value="A5"> A5</label>
                  <label><input type="radio" name="imp-tam" value="A4"> A4</label>
                  <label><input type="radio" name="imp-tam" value="A3"> A3</label>
                </div>
                <div class="inline-group">
                  <input type="text" class="inline-input" id="pf-largura" placeholder="Largura (mm)">
                  <input type="text" class="inline-input" id="pf-altura" placeholder="Altura (mm)">
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Acabamento:</div>
                <div class="options" id="pf-acabamentos">
                  <label><input type="checkbox" value="Refile"> Refile</label>
                  <label><input type="checkbox" value="Bopp Fosco"> Bopp Fosco</label>
                  <label><input type="checkbox" value="Plastificacao"> Plastificacao</label>
                  <label><input type="checkbox" value="Serrilha"> Serrilha</label>
                  <label><input type="checkbox" value="Corte Manual"> Corte Manual</label>
                  <label><input type="checkbox" value="Furo"> Furo</label>
                  <label><input type="checkbox" value="Recorte"> Recorte</label>
                  <label><input type="checkbox" value="Dobra"> Dobra</label>
                  <label><input type="checkbox" value="Bopp Brilho"> Bopp Brilho</label>
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Servicos padroes:</div>
                <div class="inline-group" style="flex-direction:column; align-items:flex-start;">
                  <select class="inline-input" style="width:100%;" aria-label="Cartao de Visita">
                    <option>Cartão de visita</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto - laminação fosca</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto - laminação fosca</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto - laminação brilho</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto - laminação brilho</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado - laminação fosca</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado - laminação fosca</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado - laminação brilho</option>
                    <option>Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado - laminação brilho</option>
                  </select>
                  <select class="inline-input" style="width:100%;" aria-label="Flyer">
                    <option>Flyer</option>
                    <option>Sulfite 75 gramas - A6 - 1x0 - refile</option>
                    <option>Couchê 120 gramas - A6 - 1x0 - refile</option>
                    <option>Couchê 150 gramas - A6 - 1x0 - refile</option>
                    <option>Sulfite 75 gramas - A6 - 1x1 - refile</option>
                    <option>Couchê 120 gramas - A6 - 1x1 - refile</option>
                    <option>Couchê 150 gramas - A6 - 1x1 - refile</option>
                    <option>Sulfite 75 gramas - A6 - 4x0 - refile</option>
                    <option>Couchê 120 gramas - A6 - 4x0 - refile</option>
                    <option>Couchê 150 gramas - A6 - 4x0 - refile</option>
                    <option>Sulfite 75 gramas - A6 - 4x4 - refile</option>
                    <option>Couchê 120 gramas - A6 - 4x4 - refile</option>
                    <option>Couchê 150 gramas - A6 - 4x4 - refile</option>
                    <option>Sulfite 75 gramas - A5 - 1x0 - refile</option>
                    <option>Couchê 120 gramas - A5 - 1x0 - refile</option>
                    <option>Couchê 150 gramas - A5 - 1x0 - refile</option>
                    <option>Sulfite 75 gramas - A5 - 1x1 - refile</option>
                    <option>Couchê 120 gramas - A5 - 1x1 - refile</option>
                    <option>Couchê 150 gramas - A5 - 1x1 - refile</option>
                    <option>Sulfite 75 gramas - A5 - 4x0 - refile</option>
                    <option>Couchê 120 gramas - A5 - 4x0 - refile</option>
                    <option>Couchê 150 gramas - A5 - 4x0 - refile</option>
                    <option>Sulfite 75 gramas - A5 - 4x4 - refile</option>
                    <option>Couchê 120 gramas - A5 - 4x4 - refile</option>
                    <option>Couchê 150 gramas - A5 - 4x4 - refile</option>
                    <option>Sulfite 75 gramas - A4 - 1x0 - refile</option>
                    <option>Couchê 120 gramas - A4 - 1x0 - refile</option>
                    <option>Couchê 150 gramas - A4 - 1x0 - refile</option>
                    <option>Sulfite 75 gramas - A4 - 1x1 - refile</option>
                    <option>Couchê 120 gramas - A4 - 1x1 - refile</option>
                    <option>Couchê 150 gramas - A4 - 1x1 - refile</option>
                    <option>Sulfite 75 gramas - A4 - 4x0 - refile</option>
                    <option>Couchê 120 gramas - A4 - 4x0 - refile</option>
                    <option>Couchê 150 gramas - A4 - 4x0 - refile</option>
                    <option>Sulfite 75 gramas - A4 - 4x4 - refile</option>
                    <option>Couchê 120 gramas - A4 - 4x4 - refile</option>
                    <option>Couchê 150 gramas - A4 - 4x4 - refile</option>
                  </select>
                  <select class="inline-input" style="width:100%;" aria-label="Pastas">
                    <option>Pastas</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha - laminação fosca</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha - laminação brilho</option>
                    <option>Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha - laminação brilho</option>
                  </select>
                  <select class="inline-input" style="width:100%;" aria-label="Credencial">
                    <option>Credencial</option>
                    <option>Couchê 150 gramas - 95 mm x 145 mm - 4x0 - sem cordão</option>
                    <option>Couchê 150 gramas - 95 mm x 145 mm - 4x4 - sem cordão</option>
                    <option>Couchê 150 gramas - 95 mm x 145 mm - 4x0 - com cordão</option>
                    <option>Couchê 150 gramas - 95 mm x 145 mm - 4x4 - com cordão</option>
                    <option>Offset 150 gramas - 95 mm x 145 mm - 4x0 - plastificado - sem cordão</option>
                    <option>Offset 150 gramas - 95 mm x 145 mm - 4x4 - plastificado - sem cordão</option>
                    <option>Offset 150 gramas - 95 mm x 145 mm - 4x0 - plastificado - com cordão</option>
                    <option>Offset 150 gramas - 95 mm x 145 mm - 4x4 - plastificado - com cordão</option>
                    <option>Couchê 300 gramas - 95 mm x 145 mm - 4x0 - sem cordão</option>
                    <option>Couchê 300 gramas - 95 mm x 145 mm - 4x4 - sem cordão</option>
                    <option>Couchê 300 gramas - 95 mm x 145 mm - 4x0 - com cordão</option>
                    <option>Couchê 300 gramas - 95 mm x 145 mm - 4x4 - com cordão</option>
                  </select>
                  <select class="inline-input" style="width:100%;" aria-label="Diversos">
                    <option>Diversos</option>
                    <option>Máscara - A4 - Sem cordão</option>
                    <option>Máscara - A4 - Com cordão</option>
                    <option>Máscara - A3 - Sem cordão</option>
                    <option>Máscara - A3 - Com cordão</option>
                    <option>Receituário B1</option>
                  </select>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Valores:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" id="pf-quantidade" placeholder="Quantidade">
                  <input type="text" class="inline-input" id="pf-preco-pagina" placeholder="Preco (Pagina)">
                </div>
                <div class="inline-group">
                  <input type="text" class="inline-input" id="pf-preco-unit" placeholder="Preco Unitario">
                  <input type="text" class="inline-input" id="pf-subtotal" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao" id="pf-observacao"></textarea>
              </div>
              <div class="produto-card">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao" id="pf-descricao"></textarea>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-plotagem">
            <div class="block-head">
              <h4>Plotagem</h4>
              <div class="produto-form-actions">
                <button class="ghost-btn" type="button">Remover</button>
                <button class="primary-btn" type="button">Adicionar</button>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tipo:</div>
                <div class="options">
                  <label><input type="radio" name="plot-tipo" checked> Copia</label>
                  <label><input type="radio" name="plot-tipo"> Impressao</label>
                  <label><input type="radio" name="plot-tipo"> Digitalizacao</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Modo:</div>
                <div class="options">
                  <label><input type="radio" name="plot-modo" checked> Linhas</label>
                  <label><input type="radio" name="plot-modo"> Imagem</label>
                  <label><input type="radio" name="plot-modo"> Banner</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Cor:</div>
                <div class="options">
                  <label><input type="radio" name="plot-cor" checked> 4x0 (Colorido)</label>
                  <label><input type="radio" name="plot-cor"> 1x0 (Preto e Branco)</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Papel:</div>
                <div class="options">
                  <label><input type="radio" name="plot-papel" checked> Sulfite 75 gramas</label>
                  <label><input type="radio" name="plot-papel"> Offset 90 gramas</label>
                  <label><input type="radio" name="plot-papel"> Offset 120 gramas</label>
                  <label><input type="radio" name="plot-papel"> Offset 150 gramas</label>
                  <label><input type="radio" name="plot-papel"> Offset 180 gramas</label>
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tamanho:</div>
                <div class="options">
                  <label><input type="radio" name="plot-tamanho" checked> A4</label>
                  <label><input type="radio" name="plot-tamanho"> A3</label>
                  <label><input type="radio" name="plot-tamanho"> A2</label>
                  <label><input type="radio" name="plot-tamanho"> A1</label>
                  <label><input type="radio" name="plot-tamanho"> A0</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Metro linear:</div>
                <input type="text" class="inline-input" placeholder="Metro Linear">
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Valores:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Preco (Metro Linear)">
                </div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Preco Unitario">
                  <input type="text" class="inline-input" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao"></textarea>
              </div>
              <div class="produto-card">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao"></textarea>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-sublimacao">
            <div class="block-head">
              <h4>Sublimacao</h4>
              <div class="produto-form-actions">
                <button class="ghost-btn" type="button">Remover</button>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tipo:</div>
                <div class="options">
                  <label><input type="radio" name="sub-tipo" checked> Caneca</label>
                  <label><input type="radio" name="sub-tipo"> Mousepad</label>
                  <label><input type="radio" name="sub-tipo"> Quebra Cabeca</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Valores:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Preco unitario">
                  <input type="text" class="inline-input" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao"></textarea>
              </div>
              <div class="produto-card">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao"></textarea>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-uv-rigida">
            <div class="block-head">
              <h4>Impressao UV - Rigida</h4>
            </div>
            <div class="produto-row">
              <div class="produto-card" style="display:flex; flex-direction:column; gap:8px;">
                <div class="title">Material:</div>
                <select class="inline-input">
                  <option>Material</option>
                  <option>P.S Branco 0.50 mm</option>
                  <option>P.S Branco 1.00 mm</option>
                  <option>P.S Branco 2.00 mm</option>
                  <option>P.S Branco 3.00 mm</option>
                  <option>PVC Branco 5.00 mm</option>
                  <option>PVC Branco 10 mm</option>
                  <option>PVC Branco 20 mm</option>
                  <option>Acrílico Cristal 2 mm</option>
                  <option>Acrílico Cristal 3 mm</option>
                  <option>Plastionda 2 mm</option>
                  <option>Plastionda 3 mm</option>
                  <option>Plastionda 4 mm</option>
                  <option>ACM 3 mm</option>
                  <option>Papelão 3 mm</option>
                  <option>Duplex 440 gramas</option>
                </select>
                <input type="text" class="inline-input" placeholder="Material do cliente">
              </div>
              <div class="produto-card">
                <div class="title">Acabamento:</div>
                <div class="options">
                  <label><input type="checkbox" checked> Corte Reto</label>
                  <label><input type="checkbox"> Dobra</label>
                  <label><input type="checkbox"> Recorte</label>
                  <label><input type="checkbox"> Dobra L</label>
                  <label><input type="checkbox"> Laminacao Fosca</label>
                  <label><input type="checkbox"> Laminacao Brilho</label>
                  <label><input type="checkbox"> Pe Americano</label>
                  <label><input type="checkbox"> Dupla face</label>
                  <label><input type="checkbox"> Adesivo Dupla face</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Tipo:</div>
                <div class="options">
                  <label><input type="radio" name="uv-rigida-tipo" checked> Placa</label>
                  <label><input type="radio" name="uv-rigida-tipo"> Display</label>
                  <label><input type="radio" name="uv-rigida-tipo"> Cubo</label>
                  <label><input type="radio" name="uv-rigida-tipo"> Totem</label>
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tamanho:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Largura (mm)">
                  <input type="text" class="inline-input" placeholder="Altura (mm)">
                  <input type="text" class="inline-input" placeholder="Profundidade (mm)">
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Cor:</div>
                <select class="inline-input">
                  <option>Cor</option>
                  <option>1x0 - Branco | Frente</option>
                  <option>2x0 - Branco + Verniz | Frente</option>
                  <option>1x1 - Branco | Frente x Verso</option>
                  <option>2x2 - Branco + Verniz | Frente x Verso</option>
                  <option>4x0 - CMYK | Frente</option>
                  <option>5x0 - CMYK + Verniz | Frente</option>
                  <option>0x1 - Branco | Verso</option>
                  <option>0x4 - CMYK | Verso</option>
                  <option>4x4 - CMYK | Frente x Verso</option>
                  <option>5x5 - CMYK + Verniz | Frente x Verso</option>
                  <option>5x0 - CMYK + Branco | Frente</option>
                  <option>6x0 - CMYK + Branco + Verniz | Frente</option>
                  <option>5x5 - CMYK + Branco | Frente x Verso</option>
                  <option>6x6 - CMYK + Branco + Verniz | Frente x Verso</option>
                  <option>0x5 - CMYK + Branco | Verso</option>
                </select>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card" style="grid-column:1 / -1;">
                <div class="title">Quantidade:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Preco (MT2)">
                  <input type="text" class="inline-input" placeholder="Preco (MT2)">
                  <input type="text" class="inline-input" placeholder="Preco Unitario">
                  <input type="text" class="inline-input" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card" style="grid-column:1 / -1;">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao"></textarea>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card" style="grid-column:1 / -1;">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao"></textarea>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-uv-flexivel">
            <div class="block-head">
              <h4>Impressao UV - Flexivel</h4>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Material:</div>
                <select class="inline-input">
                  <option>Material</option>
                  <option>Adesivo vinil branco fosco</option>
                  <option>Adesivo vinil branco brilho</option>
                  <option>Adesivo vinil transparente</option>
                  <option>Adesivo vinil metalizado prata</option>
                  <option>Adesivo vinil metalizado dourado</option>
                  <option>Adesivo vinil holográfico</option>
                  <option>Policarbonato liso 0.12 mm</option>
                  <option>Policarbonato liso 0.16 mm</option>
                  <option>Policarbonato liso 0.25 mm</option>
                  <option>Policarbonato liso 0.32 mm</option>
                  <option>Policarbonato texturizado 0.12 mm</option>
                  <option>Policarbonato texturizado 0.16 mm</option>
                  <option>Policarbonato texturizado 0.25 mm</option>
                  <option>Policarbonato texturizado 0.32 mm</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Cor:</div>
                <select class="inline-input">
                  <option>Cor</option>
                  <option>1x0 - Branco | Frente</option>
                  <option>2x0 - Branco + Verniz | Frente</option>
                  <option>1x1 - Branco | Frente x Verso</option>
                  <option>2x2 - Branco + Verniz | Frente x Verso</option>
                  <option>4x0 - CMYK | Frente</option>
                  <option>5x0 - CMYK + Verniz | Frente</option>
                  <option>0x1 - Branco | Verso</option>
                  <option>0x4 - CMYK | Verso</option>
                  <option>4x4 - CMYK | Frente x Verso</option>
                  <option>5x5 - CMYK + Verniz | Frente x Verso</option>
                  <option>5x0 - CMYK + Branco | Frente</option>
                  <option>6x0 - CMYK + Branco + Verniz | Frente</option>
                  <option>5x5 - CMYK + Branco | Frente x Verso</option>
                  <option>6x6 - CMYK + Branco + Verniz | Frente x Verso</option>
                  <option>0x5 - CMYK + Branco | Verso</option>
                </select>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Acabamento:</div>
                <div class="options">
                  <label><input type="radio" name="uv-acab" checked> Corte Reto</label>
                  <label><input type="radio" name="uv-acab"> Recorte</label>
                  <label><input type="checkbox"> Adesivo dupla face</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Tamanho:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Largura (mm)">
                  <input type="text" class="inline-input" placeholder="Altura (mm)">
                  <input type="text" class="inline-input" placeholder="Metro Quadrado">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Valores:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Preco (MT2)">
                  <input type="text" class="inline-input" placeholder="Preco Unitario">
                  <input type="text" class="inline-input" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao"></textarea>
              </div>
              <div class="produto-card">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao"></textarea>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-dtf">
            <div class="block-head">
              <h4>DTF Textil</h4>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Calculadora:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Largura (mm)">
                  <input type="text" class="inline-input" placeholder="Altura (mm)">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Metro Linear">
                </div>
                <div class="produto-actions-row">
                  <button class="ghost-btn" type="button">Proporcao</button>
                  <button class="primary-btn" type="button">Adicionar</button>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Tabela:</div>
                <div class="produto-table-like">
                  <table>
                    <thead>
                      <tr>
                        <th>Largura (mm)</th>
                        <th>Altura (mm)</th>
                        <th>Quantidade</th>
                        <th>Metro Linear</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </div>

          <div class="produto-block" id="form-comunicacao">
            <div class="block-head">
              <h4>Comunicacao Visual</h4>
              <div class="produto-form-actions">
                <button class="ghost-btn" type="button">Remover</button>
                <button class="primary-btn" type="button">Adicionar</button>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Tipo:</div>
                <select class="inline-input">
                  <option>Tipo</option>
                  <option>Adesivo</option>
                  <option>Película</option>
                  <option>Lona</option>
                  <option>Imã</option>
                  <option>Lona Canvas</option>
                  <option>Papel Fotográfico</option>
                  <option>Papel Outdoor</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Adesivo:</div>
                <select class="inline-input">
                  <option>Adesivo</option>
                  <option>Adesivo Vinil Branco Fosco</option>
                  <option>Adesivo Vinil Branco Brilho</option>
                  <option>Adesivo Vinil Transparente</option>
                  <option>Adesivo Vinil Perfurado</option>
                  <option>Adesivo Vinil Eletrostático</option>
                  <option>Adesivo Vinil Blackout Fosco</option>
                  <option>Adesivo Vinil Blackout Brilho</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Pelicula:</div>
                <select class="inline-input">
                  <option>Pelicula</option>
                  <option>Película G30</option>
                  <option>Película G20</option>
                  <option>Película G5</option>
                  <option>Película Espelhada Prata</option>
                  <option>Película Espelhada</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Lona:</div>
                <select class="inline-input">
                  <option>Lona</option>
                  <option>Corte Reto</option>
                  <option>Faixa</option>
                  <option>Banner</option>
                  <option>Solda na Imagem com Ilhós</option>
                  <option>Quadro de Madeira</option>
                </select>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Ima:</div>
                <select class="inline-input">
                  <option>Ima</option>
                  <option>0.40 mm</option>
                  <option>0.80 mm</option>
                  <option>Aplicado sob P.S 0.50 mm</option>
                  <option>Aplicado sob P.S 1.00 mm</option>
                  <option>Aplicado sob P.S 2.00 mm</option>
                  <option>Aplicado sob P.S 3.00 mm</option>
                  <option>Aplicado sob ACM 3.00 mm</option>
                </select>
              </div>
              <div class="produto-card">
                <div class="title">Tamanho:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Largura (mm)">
                  <input type="text" class="inline-input" placeholder="Altura (mm)">
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Cor:</div>
                <div class="options">
                  <label><input type="radio" name="cv-cor" checked> 4x0 (Frente)</label>
                  <label><input type="radio" name="cv-cor"> 4x4 (Frente x Verso)</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Acabamento Adesivo:</div>
                <div class="options">
                  <label><input type="radio" name="cv-acab" checked> Corte reto</label>
                  <label><input type="radio" name="cv-acab"> Recorte</label>
                  <label><input type="radio" name="cv-acab"> Resinado</label>
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Remocao:</div>
                <div class="options">
                  <label><input type="radio" name="cv-remocao" checked> Sim</label>
                  <label><input type="radio" name="cv-remocao"> Nao</label>
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Adesivo aplicado em:</div>
                <div class="inline-group">
                  <select class="inline-input">
                    <option>Aplicado em</option>
                    <option>P.S Branco 0.50 mm</option>
                    <option>P.S Branco 1.00 mm</option>
                    <option>P.S Branco 2.00 mm</option>
                    <option>P.S Branco 3.00 mm</option>
                    <option>PVC Branco 5.00 mm</option>
                    <option>PVC Branco 10 mm</option>
                    <option>PVC Branco 20 mm</option>
                    <option>Acrílico Cristal 2 mm</option>
                    <option>Acrílico Cristal 3 mm</option>
                    <option>Plastionda 2 mm</option>
                    <option>Plastionda 3 mm</option>
                    <option>Plastionda 4 mm</option>
                    <option>ACM 3 mm</option>
                    <option>Papelão 3 mm</option>
                    <option>Duplex 440 gramas</option>
                  </select>
                  <input type="text" class="inline-input" placeholder="Material do cliente">
                </div>
              </div>
              <div class="produto-card">
                <div class="title">Instalacao:</div>
                <select class="inline-input">
                  <option>Instalacao</option>
                  <option>Sem instalação</option>
                  <option>Criciúma</option>
                  <option>Içara</option>
                  <option>Balneário Rincão</option>
                  <option>Forquilhinha</option>
                  <option>Nova Veneza</option>
                  <option>Siderópolis</option>
                  <option>Cocal do Sul</option>
                  <option>Morro da Fumaça</option>
                  <option>Treviso</option>
                  <option>Lauro Muller</option>
                  <option>Morro Grande</option>
                  <option>Meleiro</option>
                  <option>Maracajá</option>
                  <option>Araranguá</option>
                  <option>Balneário Arroio do Silva</option>
                  <option>Balneário Gaivota</option>
                  <option>Sombrio</option>
                  <option>Ermo</option>
                  <option>Turvo</option>
                  <option>Timbé do Sul</option>
                  <option>Jacinto Machado</option>
                  <option>Santa Rosa do Sul</option>
                  <option>Passo de Torres</option>
                  <option>São João do Sul</option>
                  <option>Praia Grande</option>
                  <option>Jaguaruna</option>
                  <option>Sangão</option>
                  <option>Treze de Maio</option>
                  <option>Tubarão</option>
                  <option>Pedras Grandes</option>
                  <option>Capivari de Baixo</option>
                  <option>Laguna</option>
                  <option>Pescaria Brava</option>
                  <option>Gravatal</option>
                  <option>São Ludgero</option>
                  <option>Orleans</option>
                  <option>Imaruí</option>
                  <option>Imbituba</option>
                  <option>Armazém</option>
                  <option>Braço do Norte</option>
                  <option>Grão Pará</option>
                  <option>Rio Fortuna</option>
                  <option>São Martinho</option>
                </select>
              </div>
            </div>
            <div class="produto-card">
              <div class="title">Acabamento placa:</div>
              <div class="options">
                <label><input type="checkbox"> Laminacao Fosca</label>
                <label><input type="checkbox"> Laminacao Brilho</label>
                <label><input type="checkbox"> Dobra L</label>
                <label><input type="checkbox"> Dobra</label>
                <label><input type="checkbox"> Dupla face</label>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Valores:</div>
                <div class="inline-group">
                  <input type="text" class="inline-input" placeholder="Quantidade">
                  <input type="text" class="inline-input" placeholder="Preco (MT2)">
                  <input type="text" class="inline-input" placeholder="Preco Unitario">
                  <input type="text" class="inline-input" placeholder="Subtotal">
                </div>
              </div>
            </div>
            <div class="produto-row">
              <div class="produto-card">
                <div class="title">Observacao:</div>
                <textarea placeholder="Observacao"></textarea>
              </div>
              <div class="produto-card">
                <div class="title">Descricao:</div>
                <textarea placeholder="Descricao"></textarea>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- BUSCA CLIENTE -->
  <div class="modal-backdrop" id="cliente-search-modal">
    <div class="modal">
      <h3>Buscar cliente</h3>
      <div class="field">
        <label>Termo</label>
        <input type="text" id="cli-search-term" placeholder="Nome do cliente">
      </div>
      <div class="field">
        <label>Resultados</label>
        <div id="cli-search-results" class="list-card" style="max-height:220px; overflow:auto; padding:8px;"></div>
      </div>
      <div class="actions">
        <button class="ghost-btn" id="cli-search-cancel">Cancelar</button>
        <button class="primary-btn" id="cli-search-apply">Usar selecionado</button>
      </div>
      <div class="muted" id="cli-search-hint"></div>
    </div>
  </div>

  <!-- STATUS PEDIDO -->
  <div class="modal-backdrop" id="status-modal">
    <div class="modal">
      <h3>Alterar status</h3>
      <div class="actions" id="status-choices" style="justify-content:flex-start; gap:10px; flex-wrap:wrap;"></div>
      <div class="actions" style="justify-content:flex-end; margin-top:10px;">
        <button class="ghost-btn" id="status-cancel">Fechar</button>
      </div>
      <div class="muted" id="status-hint"></div>
    </div>
  </div>

  <!-- WHATS PREVIEW -->
  <div class="modal-backdrop" id="whats-modal">
    <div class="modal">
      <h3>Copiar orçamento para WhatsApp</h3>
      <pre id="whats-text" style="white-space:pre-wrap; background:#f7f7f7; padding:10px; border:1px solid var(--border); border-radius:8px; max-height:320px; overflow:auto; font-family: 'Segoe UI', monospace; font-size: 13px;"></pre>
      <div class="actions" style="justify-content:flex-end; margin-top:10px; gap:8px;">
        <button class="ghost-btn" id="whats-close">Fechar</button>
        <button class="primary-btn" id="whats-copy">Copiar</button>
      </div>
      <div class="muted" id="whats-hint"></div>
    </div>
  </div>

  <!-- BUSCA PEDIDO DE VENDA PARA OP -->
  <div class="modal-backdrop" id="pedido-ref-modal">
    <div class="modal">
      <h3>Selecionar Pedido de Venda</h3>
      <div class="field">
        <label>Buscar por número</label>
        <input type="text" id="pedido-ref-term" placeholder="Digite o número do pedido">
      </div>
      <div class="field">
        <label>Escolha um pedido</label>
        <div id="pedido-ref-results" class="list-card" style="max-height:240px; overflow:auto; padding:8px;"></div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="pedido-ref-cancel">Cancelar</button>
        <button class="primary-btn" id="pedido-ref-apply">Usar selecionado</button>
      </div>
      <div class="muted" id="pedido-ref-hint"></div>
    </div>
  </div>

  <!-- ITENS DO PEDIDO PARA VINCULAR -->
  <div class="modal-backdrop" id="pedido-items-modal">
    <div class="modal" style="max-width:620px;">
      <h3>Itens do Pedido</h3>
      <div class="field">
        <label>Pedido selecionado</label>
        <div id="pedido-items-info" class="small-muted"></div>
      </div>
      <div class="field">
        <label>Selecione os itens para emitir a OP</label>
        <div id="pedido-items-list" class="list-card" style="max-height:280px; overflow:auto; padding:8px;"></div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="pedido-items-cancel">Cancelar</button>
        <button class="primary-btn" id="pedido-items-apply">Aplicar itens</button>
      </div>
      <div class="muted" id="pedido-items-hint"></div>
    </div>
  </div>

  <!-- FINANCEIRO EXPORT -->
  <div class="modal-backdrop" id="fin-export-modal">
    <div class="modal">
      <h3>Exportar Contas a Receber</h3>
      <div class="field">
        <label>Data inicial</label>
        <input type="date" id="fin-exp-inicio">
      </div>
      <div class="field">
        <label>Data final</label>
        <input type="date" id="fin-exp-fim">
      </div>
      <div class="field">
        <label>Situacao</label>
        <select id="fin-exp-status">
          <option value="all">Todas</option>
          <option value="Liquidados">Liquidados</option>
          <option value="A vencer">A vencer</option>
          <option value="Vencidos">Vencidos</option>
          <option value="Bloqueados">Bloqueados</option>
        </select>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="fin-exp-cancel">Cancelar</button>
        <button class="primary-btn" id="fin-exp-apply">Exportar PDF</button>
      </div>
      <div class="muted" id="fin-exp-hint"></div>
    </div>
  </div>

  <!-- PAGAR EXPORT -->
  <div class="modal-backdrop" id="pay-export-modal">
    <div class="modal">
      <h3>Exportar Contas a Pagar</h3>
      <div class="field">
        <label>Filtro</label>
        <select id="pay-exp-mode">
          <option value="periodo">Periodo (data inicial/final)</option>
          <option value="mes">Mes</option>
          <option value="ano">Ano</option>
        </select>
      </div>
      <div class="field" id="pay-exp-periodo">
        <label>Intervalo</label>
        <div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
          <input type="date" id="pay-exp-inicio">
          <input type="date" id="pay-exp-fim">
        </div>
      </div>
      <div class="field" id="pay-exp-mes" style="display:none;">
        <label>Mes</label>
        <input type="month" id="pay-exp-month">
      </div>
      <div class="field" id="pay-exp-ano" style="display:none;">
        <label>Ano</label>
        <input type="number" id="pay-exp-year" min="2000" max="2100" placeholder="2026">
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="pay-exp-cancel">Cancelar</button>
        <button class="primary-btn" id="pay-exp-apply">Exportar PDF</button>
      </div>
      <div class="muted" id="pay-exp-hint"></div>
    </div>
  </div>

  <!-- AGENDA MODAL -->
  <div class="modal-backdrop" id="agenda-modal">
    <div class="modal">
      <h3>Agendamento</h3>
      <div class="field">
        <label>Titulo</label>
        <input type="text" id="agenda-title" placeholder="Ex: Visita tecnica">
      </div>
      <div class="form-grid" style="grid-template-columns: repeat(auto-fit, minmax(160px,1fr));">
        <div class="field">
          <label>Data</label>
          <input type="date" id="agenda-date">
        </div>
        <div class="field">
          <label>Inicio</label>
          <input type="time" id="agenda-start">
        </div>
        <div class="field">
          <label>Fim</label>
          <input type="time" id="agenda-end">
        </div>
      </div>
      <div class="field">
        <label>Tipo</label>
        <select id="agenda-type">
          <option value="interno">Interno</option>
          <option value="visita">Visita Técnica</option>
          <option value="instalacao">Instalação</option>
        </select>
      </div>
      <div class="agenda-visita-actions">
        <button class="ghost-btn" id="agenda-visita-open" style="display:none;">Formulario da Visita</button>
        <button class="ghost-btn" id="agenda-instalacao-open" style="display:none;">Formulario de Instalacao</button>
      </div>
      <div class="field">
        <label>Descricao / Local</label>
        <input type="text" id="agenda-desc" placeholder="Resumo, cliente ou local">
      </div>
      <input type="hidden" id="agenda-id">
      <div class="actions" style="justify-content: space-between;">
        <button class="ghost-btn" id="agenda-delete" style="display:none;">Excluir</button>
        <div style="display:flex; gap:8px; margin-left:auto;">
          <button class="ghost-btn" id="agenda-cancel">Cancelar</button>
          <button class="primary-btn" id="agenda-save">Salvar</button>
        </div>
      </div>
      <div class="muted" id="agenda-hint"></div>
    </div>
  </div>

  <!-- AGENDA VISITA TECNICA -->
  <div class="modal-backdrop" id="agenda-visita-modal">
    <div class="modal">
      <h3>Visita Tecnica</h3>
      <div class="form-grid" style="grid-template-columns: repeat(auto-fit, minmax(180px,1fr));">
        <div class="field">
          <label>Cliente</label>
          <input type="text" id="agenda-visita-cliente" class="upper-input" placeholder="NOME DO CLIENTE">
        </div>
        <div class="field">
          <label>Contato</label>
          <input type="text" id="agenda-visita-contato" class="upper-input" placeholder="NOME DO CONTATO">
        </div>
        <div class="field">
          <label>Telefone</label>
          <input type="tel" id="agenda-visita-telefone" placeholder="(00) 00000-0000">
        </div>
        <div class="field">
          <label>Endereco</label>
          <input type="text" id="agenda-visita-endereco" class="upper-input" placeholder="RUA, NUMERO, BAIRRO, CIDADE">
        </div>
      </div>
      <div class="field">
        <label>Anotacoes</label>
        <textarea id="agenda-visita-anotacoes" class="agenda-visita-textarea" maxlength="500" placeholder="Maximo 500 caracteres"></textarea>
      </div>
      <div class="field">
        <label>Anexar imagens</label>
        <input type="file" id="agenda-visita-files" accept="image/*" multiple>
        <div class="agenda-visita-note">Limite: 10 MB por imagem.</div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="agenda-visita-export">Exportar PDF</button>
        <button class="ghost-btn" id="agenda-visita-cancel">Cancelar</button>
        <button class="primary-btn" id="agenda-visita-save">Salvar</button>
      </div>
      <div class="muted" id="agenda-visita-hint"></div>
    </div>
  </div>

  <!-- AGENDA INSTALACAO -->
  <div class="modal-backdrop" id="agenda-instalacao-modal">
    <div class="modal">
      <h3>Instalacao</h3>
      <div class="form-grid" style="grid-template-columns: repeat(auto-fit, minmax(180px,1fr));">
        <div class="field">
          <label>Cliente</label>
          <input type="text" id="agenda-instalacao-cliente" class="upper-input" placeholder="NOME DO CLIENTE">
        </div>
        <div class="field">
          <label>Contato</label>
          <input type="text" id="agenda-instalacao-contato" class="upper-input" placeholder="NOME DO CONTATO">
        </div>
        <div class="field">
          <label>Telefone</label>
          <input type="tel" id="agenda-instalacao-telefone" placeholder="(00) 00000-0000">
        </div>
        <div class="field">
          <label>Numero de Pedido de Venda</label>
          <div style="display:flex; gap:8px;">
            <input type="text" id="agenda-instalacao-pedido" placeholder="Numero do pedido">
            <button class="ghost-btn" type="button" id="agenda-instalacao-buscar"><img src="static/icone_pesquisa.svg" alt="" height="16">Buscar</button>
          </div>
          <div class="small-muted" id="agenda-instalacao-pedido-hint"></div>
        </div>
        <div class="field">
          <label>Valor total</label>
          <input type="text" id="agenda-instalacao-total" readonly>
        </div>
        <div class="field">
          <label>Forma de Pagamento</label>
          <select id="agenda-instalacao-forma">
            <option value="">Selecione</option>
            <option>Dinheiro</option>
            <option>PIX</option>
            <option>Cartao de Debito</option>
            <option>Cartao de Credito</option>
            <option>Boleto Bancario</option>
          </select>
        </div>
        <div class="field">
          <label>Numero de OS ou NF</label>
          <input type="text" id="agenda-instalacao-osnf" placeholder="OS ou NF">
        </div>
        <div class="field">
          <label>Status</label>
          <select id="agenda-instalacao-status">
            <option value="A instalar">A instalar</option>
            <option value="Instalado">Instalado</option>
            <option value="Reprovado instalacao">Reprovado instalacao</option>
          </select>
        </div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="agenda-instalacao-cancel">Cancelar</button>
        <button class="primary-btn" id="agenda-instalacao-save">Salvar</button>
      </div>
      <div class="muted" id="agenda-instalacao-hint"></div>
    </div>
  </div>

  <!-- ORDEM DE PRODUCAO IMAGEM -->
  <div class="modal-backdrop" id="ordem-img-modal">
    <div class="modal" style="max-width:720px;">
      <h3>Imagem da Ordem de Produção</h3>
      <div class="list-card ordem-img-wrap" style="display:flex; justify-content:center; margin-top:10px;">
        <img id="ordem-img-preview" alt="Imagem da ordem" style="height:auto; border:1px solid var(--border); border-radius:8px; object-fit:contain;">
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="ordem-img-close">Fechar</button>
      </div>
    </div>
  </div>

    <!-- APP -->
  <section id="app-shell">
    <div class="shell">
      <aside class="sidebar">
        <h3>Menu</h3>
        <button class="side-btn" data-target="orcamento"><img src="static/icone_orcamento.svg" alt="">Orçamento</button>
        <button class="side-btn" data-target="pedido"><img src="static/icone_pedido_de_venda.svg" alt="">Pedido de Venda</button>
        <button class="side-btn" data-target="ordem"><img src="static/icone_ordem_de_producao.svg" alt="">Ordem de Produção</button>
        <button class="side-btn" data-target="chat"><img src="static/icone_chat.svg" alt="">Chat</button>
        <button class="side-btn" data-target="financeiro"><img src="static/icone_financeiro.svg" alt="">Financeiro</button>
        <button class="side-btn" data-target="relatorio"><img src="static/icone_relatorio.svg" alt="">Relatório</button>
        <button class="side-btn" data-target="dashboard"><img src="static/icone_dasboard.svg" alt="">Dashboard</button>
        <button class="side-btn" data-target="agenda"><img src="static/icone_agenda.svg" alt="">Agenda</button>
        <button class="side-btn" data-target="crm"><img src="static/icone_crm.svg" alt="">CRM</button>
        <button class="side-btn" data-target="arquivo"><img src="static/icone_arquivo.svg" alt="">Arquivo</button>
        <button class="side-btn" data-target="manutencao"><img src="static/icone_manutencao.svg" alt="">Manutenção</button>
        <button class="side-btn" data-target="config"><img src="static/icone_configuracoes.svg" alt="">Configurações</button>
        <button class="side-btn" id="btn-logout"><img src="static/icone_saida.svg" alt="">Sair</button>
      </aside>
      <main class="content" id="main-content"></main>
    </div>
  </section>

  <script>
  const loginScreen = document.getElementById("login-screen");
  const appShell = document.getElementById("app-shell");
  const mainContent = document.getElementById("main-content");
  const modal = document.getElementById("register-modal");
  const regError = document.getElementById("register-error");
  const regSuccess = document.getElementById("register-success");
  const loginError = document.getElementById("login-error");
  const MASTER_USER = { user: "Henrique", pass: "0642" };
  const MENU_ACTIONS = [
    { id: "orcamento", label: "Orçamento" },
    { id: "pedido", label: "Pedido de Venda" },
    { id: "ordem", label: "Ordem de Produção" },
    { id: "chat", label: "Chat" },
    { id: "financeiro", label: "Financeiro" },
    { id: "relatorio", label: "Relatorio" },
    { id: "dashboard", label: "Dashboard" },
    { id: "agenda", label: "Agenda" },
    { id: "crm", label: "CRM" },
    { id: "arquivo", label: "Arquivo" },
    { id: "manutencao", label: "Manutenção" },
    { id: "config", label: "Configurações" },
  ];
  const relIdx = MENU_ACTIONS.findIndex(a => a.id === "relatorio");
  if (relIdx >= 0) MENU_ACTIONS.splice(relIdx, 1);
  const fields = {
    name: document.getElementById("reg-name"),
    email: document.getElementById("reg-email"),
    user: document.getElementById("reg-user"),
    pass: document.getElementById("reg-pass"),
    role: document.getElementById("reg-role"),
  };



  const API_BASE = "api";
  const STORAGE_SYNC_DELAY = 400;
  let remoteEnabled = false;
  let storageTimer = null;
  const storagePending = new Map();
  const memoryStore = new Map();

  function buildApiUrl(path) {
    const base = API_BASE.replace(/\/$/, "");
    const suffix = path.replace(/^\//, "");
    return `${base}/${suffix}`;
  }

  async function apiFetch(path, options = {}) {
    const opts = { ...options };
    opts.headers = opts.headers ? { ...opts.headers } : {};
    if (!opts.headers["Content-Type"] && opts.body) {
      opts.headers["Content-Type"] = "application/json";
    }
    opts.credentials = "same-origin";
    const res = await fetch(buildApiUrl(path), opts);
    let data = null;
    try {
      data = await res.json();
    } catch (err) {
      data = null;
    }
    if (!res.ok) {
      const message = data && data.error ? data.error : "Erro ao comunicar com o servidor.";
      throw new Error(message);
    }
    return data;
  }

  async function refreshUsersFromApi() {
    try {
      const data = await apiFetch("users");
      if (!data || !Array.isArray(data.users)) return;
      const mapped = data.users.map(u => ({
        user: u.username || "",
        name: u.name || "",
        email: u.email || "",
        pass: "",
        role: u.role || "Atendimento",
      }));
      localStorage.setItem("printlab_users", JSON.stringify(mapped));
    } catch (err) {
      console.warn("Falha ao carregar usuarios", err);
    }
  }

  async function loadRemoteStorage() {
    remoteEnabled = false;
    const data = await apiFetch("storage");
    memoryStore.clear();
    if (data && data.items) {
      Object.entries(data.items).forEach(([key, value]) => {
        memoryStore.set(key, value);
      });
    }
    remoteEnabled = true;
  }

  function scheduleStorageSync(key, value) {
    if (!remoteEnabled) return;
    storagePending.set(key, value);
    if (storageTimer) return;
    storageTimer = setTimeout(async () => {
      const items = Array.from(storagePending.entries()).map(([k, v]) => ({ key: k, value: v }));
      storagePending.clear();
      storageTimer = null;
      try {
        await apiFetch("storage", {
          method: "PUT",
          body: JSON.stringify({ items }),
        });
      } catch (err) {
        console.warn("Falha ao sincronizar storage", err);
      }
    }, STORAGE_SYNC_DELAY);
  }

  localStorage.getItem = function(key) {
    if (!memoryStore.has(key)) return null;
    return memoryStore.get(key);
  };

  localStorage.setItem = function(key, value) {
    memoryStore.set(key, String(value));
    scheduleStorageSync(key, value);
  };

  localStorage.removeItem = function(key) {
    memoryStore.delete(key);
    if (!remoteEnabled) return;
    apiFetch(`storage/${encodeURIComponent(key)}`, { method: "DELETE" }).catch((err) => {
      console.warn("Falha ao remover chave remota", err);
    });
  };

  localStorage.clear = function() {
    memoryStore.clear();
    if (!remoteEnabled) return;
    apiFetch("storage/clear", { method: "POST" }).catch((err) => {
      console.warn("Falha ao limpar storage remoto", err);
    });
  };

  async function tryRestoreSession() {
    try {
      const data = await apiFetch("session");
      if (!data || !data.user) return;
      localStorage.setItem("printlab_current_user", data.user.username || data.user.user || "");
      await loadRemoteStorage();
      await refreshUsersFromApi();
      loginScreen.style.display = "none";
      appShell.style.display = "block";
      applyMenuPermissions();
      renderOrcamento();
      window.scrollTo(0,0);
    } catch (err) {
      memoryStore.clear();
    }
  }

  async function handleLogin() {
    const currentUser = document.getElementById("user").value.trim();
    const currentPass = document.getElementById("pass").value;
    if (!currentUser || !currentPass) {
      loginError.textContent = "Informe usuario e senha.";
      loginError.style.display = "block";
      return;
    }
    try {
      const data = await apiFetch("login", {
        method: "POST",
        body: JSON.stringify({ user: currentUser, pass: currentPass }),
      });
      localStorage.setItem("printlab_current_user", data.user.username || currentUser);
      await loadRemoteStorage();
      await refreshUsersFromApi();
      const online = new Set(JSON.parse(localStorage.getItem("printlab_online_users") || "[]"));
      online.add(data.user.username || currentUser);
      localStorage.setItem("printlab_online_users", JSON.stringify(Array.from(online)));
      loginError.style.display = "none";
      loginScreen.style.display = "none";
      appShell.style.display = "block";
      applyMenuPermissions();
      renderOrcamento();
      window.scrollTo(0,0);
    } catch (err) {
      loginError.textContent = err.message || "Usuario ou senha invalidos.";
      loginError.style.display = "block";
    }
  }


  const btnLogin = document.getElementById("btn-login");
  if (btnLogin) {
    btnLogin.onclick = handleLogin;
    btnLogin.addEventListener("click", handleLogin);
  }
  const userInput = document.getElementById("user");
  const passInput = document.getElementById("pass");
  if (userInput) {
    userInput.addEventListener("keydown", (ev) => {
      if (ev.key === "Enter") {
        handleLogin();
      }
    });
  }
  if (passInput) {
    passInput.addEventListener("keydown", (ev) => {
      if (ev.key === "Enter") {
        handleLogin();
      }
    });
  }
  const passToggle = document.getElementById("pass-toggle");
  const passToggleIcon = document.getElementById("pass-toggle-icon");
  if (passToggle && passInput && passToggleIcon) {
    const ICON_SHOW = "static/icone_mostrar_fundo_branco.svg";
    const ICON_HIDE = "static/icone_nao_mostrar_fundo_branco.svg";
    const updateIcon = () => {
      const showing = passInput.type === "text";
      passToggleIcon.src = showing ? ICON_HIDE : ICON_SHOW;
      passToggle.title = showing ? "Ocultar senha" : "Mostrar senha";
      passToggle.setAttribute("aria-label", passToggle.title);
    };
    updateIcon();
    passToggle.addEventListener("click", () => {
      passInput.type = passInput.type === "password" ? "text" : "password";
      updateIcon();
    });
  }
  const btnRegister = document.getElementById("btn-register");
  if (btnRegister) {
    // Remove self-registration from the login screen; user creation is handled internally.
    btnRegister.remove();
  }

  function openRegister() {
    regError.style.display = "none";
    regSuccess.style.display = "none";
    Object.values(fields).forEach(f => f.value = "");
    modal.style.display = "flex";
  }

  function closeRegister() {
    modal.style.display = "none";
  }

  function saveRegister() {
    regError.textContent = "Cadastro de usuarios desabilitado. Procure o administrador.";
    regError.style.display = "block";
    regSuccess.style.display = "none";
  }

  document.getElementById("reg-save").addEventListener("click", saveRegister);
  document.getElementById("reg-cancel").addEventListener("click", closeRegister);
  modal.addEventListener("click", (ev) => {
    if (ev.target === modal) closeRegister();
  });

  function renderOrcamento() {
    const stored = JSON.parse(localStorage.getItem("printlab_budgets") || "[]");
    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Orçamentos</h2><button class="icon-btn" id="btn-new-orc"><img src="static/icone_novo_emissor.svg" alt="" height="18">Novo Orçamento</button>';
    container.appendChild(header);

    const filterCard = document.createElement("div");
    filterCard.className = "list-card";
    filterCard.style.marginTop = "12px";
    filterCard.innerHTML = `
      <div style="display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap;">
        <h4 style="margin:0;">Filtro de pesquisa</h4>
        <div class="actions" style="margin-top:0;">
          <button class="icon-btn" id="orc-report-btn"><img src="static/icone_pdf.svg" alt="" height="16">Emitir relatório</button>
        </div>
      </div>
      <div class="form-grid" style="margin-top:10px;">
        <div class="field">
          <label>Número</label>
          <input type="text" id="orc-filtro-numero" class="inline-input" placeholder="Ex: 0001">
        </div>
        <div class="field">
          <label>Cliente</label>
          <input type="text" id="orc-filtro-cliente" class="inline-input" placeholder="Nome do cliente">
        </div>
        <div class="field">
          <label>Data de Emissão</label>
          <input type="date" id="orc-filtro-emissao" class="inline-input">
        </div>
        <div class="field">
          <label>Período</label>
          <div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
            <input type="date" id="orc-filtro-periodo-de" class="inline-input" placeholder="De">
            <input type="date" id="orc-filtro-periodo-ate" class="inline-input" placeholder="Até">
          </div>
        </div>
        <div class="field">
          <label>Status</label>
          <select id="orc-filtro-status" class="inline-input"></select>
        </div>
        <div class="field">
          <label>Emissor</label>
          <select id="orc-filtro-emissor" class="inline-input"></select>
        </div>
      </div>
      <div class="small-muted" id="orc-report-hint" style="margin-top:8px;"></div>
    `;
    container.appendChild(filterCard);

    const table = document.createElement("table");
    table.className = "table";
    table.style.marginTop = "12px";
    table.innerHTML = `
      <thead>
        <tr>
          <th>Número</th>
          <th>Cliente</th>
          <th>Emissor</th>
          <th>Data</th>
          <th>Total (R$)</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody id="orc-table-body"></tbody>
    `;
    container.appendChild(table);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    document.getElementById("btn-new-orc").addEventListener("click", () => {
      openPedidoModal(null, -1, "printlab_budgets", renderOrcamento);
    });

    const numeroInput = filterCard.querySelector("#orc-filtro-numero");
    const clienteInput = filterCard.querySelector("#orc-filtro-cliente");
    const emissaoInput = filterCard.querySelector("#orc-filtro-emissao");
    const periodoDeInput = filterCard.querySelector("#orc-filtro-periodo-de");
    const periodoAteInput = filterCard.querySelector("#orc-filtro-periodo-ate");
    const statusSelect = filterCard.querySelector("#orc-filtro-status");
    const emissorSelect = filterCard.querySelector("#orc-filtro-emissor");
    const reportBtn = filterCard.querySelector("#orc-report-btn");
    const reportHint = filterCard.querySelector("#orc-report-hint");
    const tbody = table.querySelector("#orc-table-body");
    const entries = stored.map((item, idx) => ({ item, idx }));
    let currentFiltered = entries.slice();

    function populateSelect(selectEl, values) {
      if (!selectEl) return;
      const current = selectEl.value;
      selectEl.innerHTML = "";
      const optAll = document.createElement("option");
      optAll.value = "";
      optAll.textContent = "Todos";
      selectEl.appendChild(optAll);
      values.forEach(v => {
        const opt = document.createElement("option");
        opt.value = v;
        opt.textContent = v;
        selectEl.appendChild(opt);
      });
      if (values.includes(current)) selectEl.value = current;
    }

    const statusBase = Array.isArray(STATUS_CHOICES.orcamento) ? STATUS_CHOICES.orcamento : [];
    const statusExtras = entries.map(r => (r.item.status || "").trim()).filter(Boolean);
    const statusValues = statusBase.concat(statusExtras.filter(s => !statusBase.includes(s)));
    const emissorValues = Array.from(new Set(entries.map(r => (r.item.emissor || "").trim()).filter(Boolean))).sort();
    populateSelect(statusSelect, statusValues);
    populateSelect(emissorSelect, emissorValues);

    function sameDay(a, b) {
      return a && b
        && a.getFullYear() === b.getFullYear()
        && a.getMonth() === b.getMonth()
        && a.getDate() === b.getDate();
    }

    function readFilters() {
      const numeroRaw = (numeroInput?.value || "").trim();
      const clienteRaw = (clienteInput?.value || "").trim();
      const emissorRaw = (emissorSelect?.value || "").trim();
      const statusRaw = (statusSelect?.value || "").trim();
      const emissao = emissaoInput?.value || "";
      const periodoDe = periodoDeInput?.value || "";
      const periodoAte = periodoAteInput?.value || "";
      return {
        numeroRaw,
        clienteRaw,
        emissorRaw,
        statusRaw,
        numero: numeroRaw.toLowerCase(),
        cliente: clienteRaw.toLowerCase(),
        emissor: emissorRaw.toLowerCase(),
        status: statusRaw.toLowerCase(),
        emissao,
        periodoDe,
        periodoAte,
      };
    }

    function filterEntries(filters) {
      const emissaoDate = filters.emissao ? parseLocalDate(filters.emissao) : null;
      const periodoDeDate = filters.periodoDe ? parseLocalDate(filters.periodoDe) : null;
      const periodoAteDate = filters.periodoAte ? parseLocalDate(filters.periodoAte) : null;
      const periodoAteEnd = periodoAteDate ? new Date(periodoAteDate.getFullYear(), periodoAteDate.getMonth(), periodoAteDate.getDate() + 1) : null;
      return entries.filter(({ item, idx }) => {
        const numero = (item.number || String(idx + 1).padStart(4, "0")).toString().toLowerCase();
        if (filters.numero && !numero.includes(filters.numero)) return false;
        const cliente = (item.client || item.cliente || "").toString().toLowerCase();
        if (filters.cliente && !cliente.includes(filters.cliente)) return false;
        const emissor = (item.emissor || "").toString().trim().toLowerCase();
        if (filters.emissor && !emissor.includes(filters.emissor)) return false;
        const status = (item.status || "").toString().trim().toLowerCase();
        if (filters.status && status !== filters.status) return false;
        const data = parseLocalDate(item.date || item.data || "");
        if (emissaoDate && (!data || !sameDay(data, emissaoDate))) return false;
        if (periodoDeDate && (!data || data < periodoDeDate)) return false;
        if (periodoAteEnd && (!data || data >= periodoAteEnd)) return false;
        return true;
      });
    }

    function renderRows(list) {
      if (!tbody) return;
      const rows = list.map(({ item, idx }) => {
        const color = getStatusColor(item.status);
        const textColor = getStatusTextColor(item.status) || "#000";
        const rowStyle = color ? ` style="background:${color}; color:${textColor};"` : "";
        const num = item.number || String(idx + 1).padStart(4, "0");
        const emissor = item.emissor || "";
        const data = item.date || item.data || "";
        const totalVal = typeof item.total === "number" ? item.total : moneyToNumber(item.total);
        return `<tr data-idx="${idx}"${rowStyle}>
          <td>${num}</td>
          <td>${item.client || item.cliente || ""}</td>
          <td>${emissor}</td>
          <td>${formatDateBR(data)}</td>
          <td>R$ ${numberToMoney(totalVal || 0)}</td>
          <td class="orc-status-cell" style="cursor:pointer;" title="Alterar status">${item.status || 'Definir'}</td>
        </tr>`;
      }).join("");
      tbody.innerHTML = rows || '<tr><td colspan="6" style="text-align:center; color:#777;">Nenhum orçamento encontrado.</td></tr>';
      Array.from(tbody.querySelectorAll("tr[data-idx]")).forEach(tr => {
        tr.style.cursor = "pointer";
        tr.addEventListener("dblclick", () => {
          const idx = parseInt(tr.dataset.idx, 10);
          openPedidoModal(stored[idx], idx, "printlab_budgets", renderOrcamento);
        });
        const statusTd = tr.querySelector(".orc-status-cell");
        if (statusTd) {
          statusTd.addEventListener("click", (ev) => {
            ev.stopPropagation();
            const idx = parseInt(tr.dataset.idx, 10);
            openStatusModal(idx, "orcamento");
          });
        }
      });
    }

    function applyFilters() {
      const filters = readFilters();
      currentFiltered = filterEntries(filters);
      renderRows(currentFiltered);
      if (reportHint) reportHint.textContent = "";
      return { filters, filtered: currentFiltered };
    }

    function buildFilterLabel(filters) {
      const parts = [];
      if (filters.numeroRaw) parts.push(`Número: ${filters.numeroRaw}`);
      if (filters.clienteRaw) parts.push(`Cliente: ${filters.clienteRaw}`);
      if (filters.emissao) parts.push(`Data de Emissão: ${formatDateBR(filters.emissao)}`);
      if (filters.periodoDe || filters.periodoAte) {
        const de = filters.periodoDe ? formatDateBR(filters.periodoDe) : "inicio";
        const ate = filters.periodoAte ? formatDateBR(filters.periodoAte) : "fim";
        parts.push(`Período: ${de} a ${ate}`);
      }
      if (filters.statusRaw) parts.push(`Status: ${filters.statusRaw}`);
      if (filters.emissorRaw) parts.push(`Emissor: ${filters.emissorRaw}`);
      return parts.join(" | ");
    }

    function emitirRelatorio() {
      const { filters, filtered } = applyFilters();
      if (!filtered.length) {
        if (reportHint) reportHint.textContent = "Nenhum orçamento encontrado para o filtro.";
        return;
      }
      if (reportHint) reportHint.textContent = "";
      const filtroLabel = buildFilterLabel(filters);
      const rows = filtered.map(({ item, idx }) => {
        const num = item.number || String(idx + 1).padStart(4, "0");
        const emissor = item.emissor || "";
        const data = item.date || item.data || "";
        const totalVal = typeof item.total === "number" ? item.total : moneyToNumber(item.total);
        return `
          <tr>
            <td>${num}</td>
            <td>${item.client || item.cliente || ""}</td>
            <td>${emissor}</td>
            <td>${formatDateBR(data)}</td>
            <td>R$ ${numberToMoney(totalVal || 0)}</td>
            <td>${item.status || ""}</td>
          </tr>
        `;
      }).join("");
      const html = `
        <html>
          <head>
            <title>Relatório de Orçamentos</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 16px; color: #111827; font-size: 10px; }
              h2 { margin: 0 0 6px 0; font-size: 14px; }
              .muted { color: #6b7280; font-size: 10px; margin-bottom: 10px; }
              table { width: 100%; border-collapse: collapse; font-size: 10px; }
              th, td { border: 1px solid #d1d5db; padding: 6px; text-align: left; vertical-align: top; }
              thead th { background: #f3f4f6; }
            </style>
          </head>
          <body>
            <h2>Relatório de Orçamentos</h2>
            <div class="muted">
              Emissão: ${new Date().toLocaleString("pt-BR")}${filtroLabel ? " | " + filtroLabel : ""}
            </div>
            <table>
              <thead>
                <tr>
                  <th>Número</th>
                  <th>Cliente</th>
                  <th>Emissor</th>
                  <th>Data</th>
                  <th>Total (R$)</th>
                  <th>Status</th>
                </tr>
              </thead>
              <tbody>${rows}</tbody>
            </table>
            <script>window.print();<\/script>
          </body>
        </html>
      `;
      const win = window.open("", "_blank");
      if (win) {
        win.document.write(html);
        win.document.close();
      }
    }

    if (numeroInput) numeroInput.addEventListener("input", applyFilters);
    if (clienteInput) clienteInput.addEventListener("input", applyFilters);
    if (emissaoInput) emissaoInput.addEventListener("change", applyFilters);
    if (periodoDeInput) periodoDeInput.addEventListener("change", applyFilters);
    if (periodoAteInput) periodoAteInput.addEventListener("change", applyFilters);
    if (statusSelect) statusSelect.addEventListener("change", applyFilters);
    if (emissorSelect) emissorSelect.addEventListener("change", applyFilters);
    if (reportBtn) reportBtn.addEventListener("click", emitirRelatorio);

    applyFilters();
  }
  function renderPedidosVenda() {
    const stored = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]");
    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Pedidos de Venda</h2><button class="icon-btn" id="btn-new-pedido"><img src="static/icone_novo_emissor.svg" alt="" height="18">Emitir Pedido de Venda</button>';
    container.appendChild(header);

    const filterCard = document.createElement("div");
    filterCard.className = "list-card";
    filterCard.style.marginTop = "12px";
    filterCard.innerHTML = `
      <div style="display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap;">
        <h4 style="margin:0;">Filtro de pesquisa</h4>
        <div class="actions" style="margin-top:0;">
          <button class="icon-btn" id="pv-report-btn"><img src="static/icone_pdf.svg" alt="" height="16">Emitir relatório</button>
        </div>
      </div>
      <div class="form-grid" style="margin-top:10px;">
        <div class="field">
          <label>Número</label>
          <input type="text" id="pv-filtro-numero" class="inline-input" placeholder="Ex: 0001">
        </div>
        <div class="field">
          <label>Cliente</label>
          <input type="text" id="pv-filtro-cliente" class="inline-input" placeholder="Nome do cliente">
        </div>
        <div class="field">
          <label>Data de Emissão</label>
          <input type="date" id="pv-filtro-emissao" class="inline-input">
        </div>
        <div class="field">
          <label>Período</label>
          <div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
            <input type="date" id="pv-filtro-periodo-de" class="inline-input" placeholder="De">
            <input type="date" id="pv-filtro-periodo-ate" class="inline-input" placeholder="Até">
          </div>
        </div>
        <div class="field">
          <label>Status</label>
          <select id="pv-filtro-status" class="inline-input"></select>
        </div>
        <div class="field">
          <label>Emissor</label>
          <select id="pv-filtro-emissor" class="inline-input"></select>
        </div>
        <div class="field">
          <label>Designer</label>
          <select id="pv-filtro-designer" class="inline-input"></select>
        </div>
      </div>
      <div class="small-muted" id="pv-report-hint" style="margin-top:8px;"></div>
    `;
    container.appendChild(filterCard);

    const table = document.createElement("table");
    table.className = "table";
    table.style.marginTop = "12px";
    table.innerHTML = `
      <thead>
        <tr>
          <th>Número Orçamento</th>
          <th>Número Pedido de Venda</th>
          <th>Cliente</th>
          <th>Emissor</th>
          <th>Designer</th>
          <th>Tipo</th>
          <th>Data</th>
          <th>Total (R$)</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody id="pv-table-body"></tbody>
    `;
    container.appendChild(table);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    document.getElementById("btn-new-pedido").addEventListener("click", () => {
      openPedidoModal();
    });

    const numeroInput = filterCard.querySelector("#pv-filtro-numero");
    const clienteInput = filterCard.querySelector("#pv-filtro-cliente");
    const emissaoInput = filterCard.querySelector("#pv-filtro-emissao");
    const periodoDeInput = filterCard.querySelector("#pv-filtro-periodo-de");
    const periodoAteInput = filterCard.querySelector("#pv-filtro-periodo-ate");
    const statusSelect = filterCard.querySelector("#pv-filtro-status");
    const emissorSelect = filterCard.querySelector("#pv-filtro-emissor");
    const designerSelect = filterCard.querySelector("#pv-filtro-designer");
    const reportBtn = filterCard.querySelector("#pv-report-btn");
    const reportHint = filterCard.querySelector("#pv-report-hint");
    const tbody = table.querySelector("#pv-table-body");
    const entries = stored.map((item, idx) => ({ item, idx }));
    let currentFiltered = entries.slice();

    function populateSelect(selectEl, values) {
      if (!selectEl) return;
      const current = selectEl.value;
      selectEl.innerHTML = "";
      const optAll = document.createElement("option");
      optAll.value = "";
      optAll.textContent = "Todos";
      selectEl.appendChild(optAll);
      values.forEach(v => {
        const opt = document.createElement("option");
        opt.value = v;
        opt.textContent = v;
        selectEl.appendChild(opt);
      });
      if (values.includes(current)) selectEl.value = current;
    }

    const statusBase = Array.isArray(STATUS_CHOICES.pedido) ? STATUS_CHOICES.pedido : [];
    const statusExtras = entries.map(r => (r.item.status || "").trim()).filter(Boolean);
    const statusValues = statusBase.concat(statusExtras.filter(s => !statusBase.includes(s)));
    const emissorValues = Array.from(new Set(entries.map(r => (r.item.emissor || "").trim()).filter(Boolean))).sort();
    const designerValues = Array.from(new Set(entries.map(r => (r.item.designer || "").trim()).filter(Boolean))).sort();
    populateSelect(statusSelect, statusValues);
    populateSelect(emissorSelect, emissorValues);
    populateSelect(designerSelect, designerValues);

    function sameDay(a, b) {
      return a && b
        && a.getFullYear() === b.getFullYear()
        && a.getMonth() === b.getMonth()
        && a.getDate() === b.getDate();
    }

    function readFilters() {
      const numeroRaw = (numeroInput?.value || "").trim();
      const clienteRaw = (clienteInput?.value || "").trim();
      const emissorRaw = (emissorSelect?.value || "").trim();
      const designerRaw = (designerSelect?.value || "").trim();
      const statusRaw = (statusSelect?.value || "").trim();
      const emissao = emissaoInput?.value || "";
      const periodoDe = periodoDeInput?.value || "";
      const periodoAte = periodoAteInput?.value || "";
      return {
        numeroRaw,
        clienteRaw,
        emissorRaw,
        designerRaw,
        statusRaw,
        numero: numeroRaw.toLowerCase(),
        cliente: clienteRaw.toLowerCase(),
        emissor: emissorRaw.toLowerCase(),
        designer: designerRaw.toLowerCase(),
        status: statusRaw.toLowerCase(),
        emissao,
        periodoDe,
        periodoAte,
      };
    }

    function filterEntries(filters) {
      const emissaoDate = filters.emissao ? parseLocalDate(filters.emissao) : null;
      const periodoDeDate = filters.periodoDe ? parseLocalDate(filters.periodoDe) : null;
      const periodoAteDate = filters.periodoAte ? parseLocalDate(filters.periodoAte) : null;
      const periodoAteEnd = periodoAteDate ? new Date(periodoAteDate.getFullYear(), periodoAteDate.getMonth(), periodoAteDate.getDate() + 1) : null;
      return entries.filter(({ item, idx }) => {
        const numero = (item.number || String(idx + 1).padStart(4, "0")).toString().toLowerCase();
        if (filters.numero && !numero.includes(filters.numero)) return false;
        const cliente = (item.cliente || item.client || "").toString().toLowerCase();
        if (filters.cliente && !cliente.includes(filters.cliente)) return false;
        const emissor = (item.emissor || "").toString().trim().toLowerCase();
        if (filters.emissor && !emissor.includes(filters.emissor)) return false;
        const designer = (item.designer || "").toString().trim().toLowerCase();
        if (filters.designer && !designer.includes(filters.designer)) return false;
        const status = (item.status || "").toString().trim().toLowerCase();
        if (filters.status && status !== filters.status) return false;
        const data = parseLocalDate(item.data || item.date || "");
        if (emissaoDate && (!data || !sameDay(data, emissaoDate))) return false;
        if (periodoDeDate && (!data || data < periodoDeDate)) return false;
        if (periodoAteEnd && (!data || data >= periodoAteEnd)) return false;
        return true;
      });
    }

    function renderRows(list) {
      if (!tbody) return;
      if (!list.length) {
        tbody.innerHTML = '<tr><td colspan="9" style="text-align:center; color:#777;">Nenhum pedido de venda cadastrado.</td></tr>';
        return;
      }
      const rows = list.map(({ item, idx }) => {
        const color = getStatusColor(item.status);
        const textColor = getStatusTextColor(item.status) || "#000";
        const rowStyle = color ? ` style="background:${color}; color:${textColor};"` : "";
        const num = item.number || String(idx + 1).padStart(4, "0");
        const numOrc = item.orcamentoRef || "";
        const emissor = item.emissor || "";
        const designer = item.designer || "";
        return `
          <tr data-idx="${idx}"${rowStyle}>
            <td>${numOrc || "-"}</td>
            <td>${num}</td>
            <td>${item.cliente || item.client || ""}</td>
            <td>${emissor}</td>
            <td>${designer}</td>
            <td>${item.tipo || "Pedido de Venda"}</td>
            <td>${item.data || ""}</td>
            <td>R$ ${numberToMoney(item.total || 0)}</td>
            <td class="pv-status-cell" style="cursor:pointer;" title="Alterar status">${item.status || "Salvo"}</td>
          </tr>
        `;
      }).join("");
      tbody.innerHTML = rows;

      Array.from(tbody.querySelectorAll("tr[data-idx]")).forEach(tr => {
        tr.addEventListener("dblclick", () => {
          const idx = parseInt(tr.dataset.idx, 10);
          openPedidoModal(stored[idx], idx, "printlab_pedidos_venda", renderPedidosVenda);
        });
        const statusTd = tr.querySelector(".pv-status-cell");
        if (statusTd) {
          statusTd.addEventListener("click", (ev) => {
            ev.stopPropagation();
            const idx = parseInt(tr.dataset.idx, 10);
            openStatusModal(idx);
          });
        }
      });
    }

    function applyFilters() {
      const filters = readFilters();
      currentFiltered = filterEntries(filters);
      renderRows(currentFiltered);
      if (reportHint) reportHint.textContent = "";
      return { filters, filtered: currentFiltered };
    }

    function buildFilterLabel(filters) {
      const parts = [];
      if (filters.numeroRaw) parts.push(`Número: ${filters.numeroRaw}`);
      if (filters.clienteRaw) parts.push(`Cliente: ${filters.clienteRaw}`);
      if (filters.emissao) parts.push(`Data de Emissão: ${formatDateBR(filters.emissao)}`);
      if (filters.periodoDe || filters.periodoAte) {
        const de = filters.periodoDe ? formatDateBR(filters.periodoDe) : "início";
        const ate = filters.periodoAte ? formatDateBR(filters.periodoAte) : "fim";
        parts.push(`Período: ${de} a ${ate}`);
      }
      if (filters.statusRaw) parts.push(`Status: ${filters.statusRaw}`);
      if (filters.emissorRaw) parts.push(`Emissor: ${filters.emissorRaw}`);
      if (filters.designerRaw) parts.push(`Designer: ${filters.designerRaw}`);
      return parts.join(" | ");
    }

    function emitirRelatorio() {
      const { filters, filtered } = applyFilters();
      if (!filtered.length) {
        if (reportHint) reportHint.textContent = "Nenhum pedido encontrado para o filtro.";
        return;
      }
      if (reportHint) reportHint.textContent = "";
      const filtroLabel = buildFilterLabel(filters);
      const rows = filtered.map(({ item, idx }) => {
        const num = item.number || String(idx + 1).padStart(4, "0");
        const numOrc = item.orcamentoRef || "";
        const emissor = item.emissor || "";
        const designer = item.designer || "";
        return `
          <tr>
            <td>${numOrc || "-"}</td>
            <td>${num}</td>
            <td>${item.cliente || item.client || ""}</td>
            <td>${emissor}</td>
            <td>${designer}</td>
            <td>${item.tipo || "Pedido de Venda"}</td>
            <td>${item.data || ""}</td>
            <td>R$ ${numberToMoney(item.total || 0)}</td>
            <td>${item.status || ""}</td>
          </tr>
        `;
      }).join("");
      const html = `
        <html>
          <head>
            <title>Relatório de Pedidos de Venda</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 16px; color: #111827; font-size: 10px; }
              h2 { margin: 0 0 6px 0; font-size: 14px; }
              .muted { color: #6b7280; font-size: 10px; margin-bottom: 10px; }
              table { width: 100%; border-collapse: collapse; font-size: 10px; }
              th, td { border: 1px solid #d1d5db; padding: 6px; text-align: left; vertical-align: top; }
              thead th { background: #f3f4f6; }
            </style>
          </head>
          <body>
            <h2>Relatório de Pedidos de Venda</h2>
            <div class="muted">
              Emissão: ${new Date().toLocaleString("pt-BR")}${filtroLabel ? " | " + filtroLabel : ""}
            </div>
            <table>
              <thead>
                <tr>
                  <th>Número Orçamento</th>
                  <th>Número Pedido de Venda</th>
                  <th>Cliente</th>
                  <th>Emissor</th>
                  <th>Designer</th>
                  <th>Tipo</th>
                  <th>Data</th>
                  <th>Total (R$)</th>
                  <th>Status</th>
                </tr>
              </thead>
              <tbody>${rows}</tbody>
            </table>
            <script>window.print();<\/script>
          </body>
        </html>
      `;
      const win = window.open("", "_blank");
      if (win) {
        win.document.write(html);
        win.document.close();
      }
    }

    if (numeroInput) numeroInput.addEventListener("input", applyFilters);
    if (clienteInput) clienteInput.addEventListener("input", applyFilters);
    if (emissaoInput) emissaoInput.addEventListener("change", applyFilters);
    if (periodoDeInput) periodoDeInput.addEventListener("change", applyFilters);
    if (periodoAteInput) periodoAteInput.addEventListener("change", applyFilters);
    if (statusSelect) statusSelect.addEventListener("change", applyFilters);
    if (emissorSelect) emissorSelect.addEventListener("change", applyFilters);
    if (designerSelect) designerSelect.addEventListener("change", applyFilters);
    if (reportBtn) reportBtn.addEventListener("click", emitirRelatorio);

    applyFilters();
  }
  function renderOrdensProducao() {
    const stored = JSON.parse(localStorage.getItem("printlab_ordens_producao") || "[]");
    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Ordens de Produção</h2><button class="icon-btn" id="btn-new-ordem"><img src="static/icone_novo_emissor.svg" alt="" height="18">Emitir Ordem de Produção</button>';
    container.appendChild(header);

    const table = document.createElement("table");
    table.className = "table";
    const pedidos = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]");
    const pedidoMap = new Map(pedidos.map(p => [String(p.number || "").trim(), p]));
    const rows = stored.map((o, idx) => {
      const pedidoNum = String(o.pedidoRef || "").trim();
      const pedido = pedidoNum ? pedidoMap.get(pedidoNum) : null;
      const emissorPedido = pedido ? (pedido.emissor || "") : (o.emissorPedido || o.emissor || "");
      const totalVal = typeof o.total === "number" ? o.total : moneyToNumber(o.total);
      const statusLabel = (o.status === "Produção" || o.status === "Producao") ? "Produção" : (o.status || "");
      const color = getStatusColor(statusLabel, "ordem");
      const textColor = getStatusTextColor(statusLabel, "ordem") || "#000";
      const rowStyle = color ? ` style="background:${color}; color:${textColor};"` : "";
      const itemImg = (o.items || []).find(it => it && it.imagem && it.imagem.trim());
      const imgSrc = (o.imagem && o.imagem.trim()) ? o.imagem : (itemImg ? itemImg.imagem : "");
      const imgCell = imgSrc
        ? `<button class="icon-btn op-image-btn" data-img="${encodeURIComponent(imgSrc)}" title="Ver imagem" style="padding:6px;"><img src="static/icone_mostrar.svg" alt="" height="16"></button>`
        : "";
      return `<tr data-idx="${idx}"${rowStyle}>`
        + `<td>${pedidoNum || "-"}</td>`
        + `<td>${o.cliente || o.client || ""}</td>`
        + `<td>${emissorPedido || "-"}</td>`
        + `<td>${o.designer || ""}</td>`
        + `<td>${o.tipo || "Ordem de Produção"}</td>`
        + `<td>${o.data || o.date || ""}</td>`
        + `<td>R$ ${numberToMoney(totalVal || 0)}</td>`
        + `<td class="op-status-cell" style="cursor:pointer;" title="Alterar status">${statusLabel}</td>`
        + `<td>${imgCell}</td>`
        + `</tr>`;
    }).join("");
    table.innerHTML = `
      <thead>
        <tr>
          <th>Número Pedido de Venda</th>
          <th>Cliente</th>
          <th>Emissor do Pedido de Venda</th>
          <th>Designer</th>
          <th>Tipo</th>
          <th>Data</th>
          <th>Total (R$)</th>
          <th>Status</th>
          <th>Imagem</th>
        </tr>
      </thead>
      <tbody>
        ${rows || '<tr><td colspan="9" style="text-align:center; color:#777;">Nenhuma ordem de produção cadastrada.</td></tr>'}
      </tbody>
    `;
    container.appendChild(table);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    document.getElementById("btn-new-ordem").addEventListener("click", () => {
      openPedidoModal(null, -1, "printlab_ordens_producao", renderOrdensProducao);
    });

    const tbody = table.querySelector("tbody");
    if (tbody) {
      tbody.addEventListener("click", (ev) => {
        const imgBtn = ev.target.closest(".op-image-btn");
        if (imgBtn) {
          ev.stopPropagation();
          const img = imgBtn.dataset.img ? decodeURIComponent(imgBtn.dataset.img) : "";
          if (img) openOrdemImageModal(img);
          return;
        }
        const statusTd = ev.target.closest(".op-status-cell");
        if (statusTd) {
          ev.stopPropagation();
          const tr = statusTd.closest("tr");
          const idx = tr ? parseInt(tr.dataset.idx, 10) : -1;
          if (idx >= 0) openStatusModal(idx, "ordem");
        }
      });
    }

    Array.from(table.querySelectorAll("tbody tr[data-idx]")).forEach(tr => {
      tr.style.cursor = "pointer";
      tr.addEventListener("dblclick", () => {
        const idx = parseInt(tr.dataset.idx, 10);
        openPedidoModal(stored[idx], idx, "printlab_ordens_producao", renderOrdensProducao);
      });
    });
  }
  // Pedido de Venda modal state/helpers
  let pedidoItems = [];
  let currentPedidoIndex = -1;
  let currentPedidoKey = "printlab_pedidos_venda";
  let currentPedidoRender = null;
  let pedidoImageData = "";
  const pedidoModal = document.getElementById("pedido-modal");
  const pedidoAlert = document.getElementById("pedido-alert");
  const pedidoImgInput = document.getElementById("pv-imagem");
  const pedidoImgPreview = document.getElementById("pv-img-preview");
  const pedidoImgHint = document.getElementById("pv-img-hint");
  const whatsModal = document.getElementById("whats-modal");
  const whatsText = document.getElementById("whats-text");
  const whatsHint = document.getElementById("whats-hint");

  function moneyToNumber(str) {
    if (!str) return 0;
    const cleaned = str.toString().replace(/\./g, "").replace(",", ".");
    const num = parseFloat(cleaned);
    return isNaN(num) ? 0 : num;
  }

  function numberToMoney(num) {
    const val = isNaN(num) ? 0 : num;
    return val.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  }

  function resetPedidoImage() {
    pedidoImageData = "";
    if (pedidoImgInput) pedidoImgInput.value = "";
    if (pedidoImgPreview) {
      pedidoImgPreview.src = "";
      pedidoImgPreview.style.display = "none";
    }
    if (pedidoImgHint) pedidoImgHint.textContent = "";
  }

  function setPedidoImage(dataUrl, hint = "") {
    pedidoImageData = dataUrl || "";
    if (pedidoImgPreview) {
      pedidoImgPreview.src = pedidoImageData;
      pedidoImgPreview.style.display = pedidoImageData ? "block" : "none";
    }
    if (pedidoImgHint) pedidoImgHint.textContent = hint || (pedidoImageData ? "Imagem carregada." : "");
  }

  if (pedidoImgInput) {
    pedidoImgInput.addEventListener("change", () => {
      const file = pedidoImgInput.files && pedidoImgInput.files[0];
      if (!file) {
        resetPedidoImage();
        return;
      }
      if (!(file.type && file.type.toLowerCase().includes("jpeg"))) {
        if (pedidoImgHint) pedidoImgHint.textContent = "Use apenas arquivo JPG.";
        pedidoImgInput.value = "";
        return;
      }
      if (file.size > 1048576) {
        if (pedidoImgHint) pedidoImgHint.textContent = "Tamanho maximo 1 MB.";
        pedidoImgInput.value = "";
        return;
      }
      const reader = new FileReader();
      reader.onload = () => {
        setPedidoImage(reader.result, "Imagem carregada.");
      };
      reader.readAsDataURL(file);
    });
  }

  // Financeiro helpers
  const RECEBER_KEY = "printlab_contas_receber";
  const PAGAR_KEY = "printlab_contas_pagar";
  const FLUXO_KEY = "printlab_fluxo_mensal";
  const RECEBER_STATUS_META = {
    "Liquidados": { color: "#5CA47A", cls: "liq" },
    "A vencer": { color: "#51A8B1", cls: "avencer" },
    "Vencidos": { color: "#F8AC92", cls: "vencido" },
    "Bloqueados": { color: "#C37377", cls: "bloq" },
  };

  function todayISO() {
    return new Date().toISOString().split("T")[0];
  }

  function parseLocalDate(dateStr) {
    if (!dateStr) return null;
    if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
      const [y, m, d] = dateStr.split("-").map(Number);
      return new Date(y, (m || 1) - 1, d || 1);
    }
    const d = new Date(dateStr);
    return isNaN(d.getTime()) ? null : d;
  }

  function formatDateBR(dateStr) {
    if (!dateStr) return "";
    const d = parseLocalDate(dateStr);
    return !d ? dateStr : d.toLocaleDateString("pt-BR");
  }

  function getXmlTextNfe(root, tag) {
    if (!root) return "";
    const el = root.getElementsByTagName(tag)[0] || root.getElementsByTagNameNS("*", tag)[0];
    return el ? (el.textContent || "").trim() : "";
  }

  function formatXmlDateNfe(value) {
    if (!value) return "";
    if (/^\d{4}-\d{2}-\d{2}/.test(value)) return value.slice(0, 10);
    if (/^\d{2}\/\d{2}\/\d{4}/.test(value)) {
      const [d, m, y] = value.split("/");
      return `${y}-${m}-${d}`;
    }
    return "";
  }

  function parseNfeXml(xmlText) {
    const parser = new DOMParser();
    const doc = parser.parseFromString(xmlText, "application/xml");
    if (doc.getElementsByTagName("parsererror").length) {
      return { error: "XML inválido." };
    }
    const infNFe = doc.getElementsByTagName("infNFe")[0] || doc.getElementsByTagNameNS("*", "infNFe")[0];
    const ide = doc.getElementsByTagName("ide")[0] || doc.getElementsByTagNameNS("*", "ide")[0];
    const emit = doc.getElementsByTagName("emit")[0] || doc.getElementsByTagNameNS("*", "emit")[0];
    const icmsTot = doc.getElementsByTagName("ICMSTot")[0] || doc.getElementsByTagNameNS("*", "ICMSTot")[0] || doc;
    const chave = infNFe ? (infNFe.getAttribute("Id") || "").replace(/^NFe/, "") : "";
    const numero = getXmlTextNfe(ide, "nNF");
    const serie = getXmlTextNfe(ide, "serie");
    const natOp = getXmlTextNfe(ide, "natOp");
    const emissaoRaw = getXmlTextNfe(ide, "dhEmi") || getXmlTextNfe(ide, "dEmi");
    const fornecedor = getXmlTextNfe(emit, "xNome");
    const cnpj = getXmlTextNfe(emit, "CNPJ") || getXmlTextNfe(emit, "CPF");
    const ie = getXmlTextNfe(emit, "IE");
    const total = getXmlTextNfe(icmsTot, "vNF");

    const dets = Array.from(doc.getElementsByTagName("det"));
    const detsNs = dets.length ? dets : Array.from(doc.getElementsByTagNameNS("*", "det"));
    const items = detsNs.map(det => {
      const prod = det.getElementsByTagName("prod")[0] || det.getElementsByTagNameNS("*", "prod")[0] || det;
      const nome = getXmlTextNfe(prod, "xProd");
      const qtd = getXmlTextNfe(prod, "qCom");
      const unidade = getXmlTextNfe(prod, "uCom");
      const preco = getXmlTextNfe(prod, "vUnCom");
      if (!nome) return "";
      const qtdLabel = qtd ? `${qtd}${unidade ? " " + unidade : ""}` : "";
      const precoLabel = preco ? ` (R$ ${preco})` : "";
      return `${nome}${qtdLabel ? " - " + qtdLabel : ""}${precoLabel}`;
    }).filter(Boolean);

    return {
      chave,
      numero,
      serie,
      natOp,
      emissaoRaw,
      fornecedor,
      cnpj,
      ie,
      total,
      items,
    };
  }

  function parseXmlNumberNfe(value) {
    if (!value) return 0;
    const cleaned = value.toString().replace(/[^\d.,-]/g, "");
    if (cleaned.includes(",") && !cleaned.includes(".")) {
      return parseFloat(cleaned.replace(".", "").replace(",", "."));
    }
    return parseFloat(cleaned);
  }

  function addMonths(dateStr, months) {
    const d = dateStr ? parseLocalDate(dateStr) : new Date();
    if (isNaN(d.getTime())) return dateStr;
    d.setMonth(d.getMonth() + months);
    return d.toISOString().split("T")[0];
  }

  function getReceberStatusMeta(status) {
    return RECEBER_STATUS_META[status] || { color: "", cls: "" };
  }

  function seedContasReceber() {
    if (localStorage.getItem(RECEBER_KEY)) return;
    const shift = (days) => {
      const d = new Date();
      d.setDate(d.getDate() + days);
      return d.toISOString().split("T")[0];
    };
    const sample = [
      {
        id: Date.now(),
        cliente: "Studio Horizonte",
        emissao: todayISO(),
        forma: "PIX",
        vencimentos: [{ data: todayISO(), valor: 850.5 }],
        total: 850.5,
        status: "Liquidados",
      },
      {
        id: Date.now() + 1,
        cliente: "Editora Sul",
        emissao: shift(-2),
        forma: "Boleto Bancario",
        vencimentos: [
          { data: shift(5), valor: 1200 },
          { data: shift(35), valor: 1200 },
          { data: shift(65), valor: 1200 },
        ],
        total: 3600,
        status: "A vencer",
      },
      {
        id: Date.now() + 2,
        cliente: "Mercado Central",
        emissao: shift(-18),
        forma: "Cheque",
        vencimentos: [
          { data: shift(-10), valor: 950 },
          { data: shift(-40), valor: 950 },
        ],
        total: 1900,
        status: "Vencidos",
      },
      {
        id: Date.now() + 3,
        cliente: "Agencia Atlas",
        emissao: shift(-4),
        forma: "Cartao de credito",
        vencimentos: [
          { data: shift(10), valor: 400 },
          { data: shift(40), valor: 400 },
        ],
        total: 800,
        status: "Bloqueados",
      },
    ];
    localStorage.setItem(RECEBER_KEY, JSON.stringify(sample));
  }

  function seedContasPagar() {
    if (localStorage.getItem(PAGAR_KEY)) return;
    const shift = (days) => {
      const d = new Date();
      d.setDate(d.getDate() + days);
      return d.toISOString().split("T")[0];
    };
    const sample = [
      {
        id: Date.now() + 100,
        fornecedor: "Papelaria Norte",
        material: "Papel couchê",
        tipo: "Materia-prima",
        forma: "Boleto Bancario",
        emissao: shift(-5),
        vencimentos: [{ data: shift(5), valor: 1800 }],
        total: 1800,
      },
      {
        id: Date.now() + 101,
        fornecedor: "Transportadora Leste",
        material: "Frete",
        tipo: "Servico",
        forma: "PIX",
        emissao: shift(-2),
        vencimentos: [{ data: shift(-1), valor: 450 }],
        total: 450,
      },
      {
        id: Date.now() + 102,
        fornecedor: "Fornecedor de Tinta",
        material: "Tinta UV",
        tipo: "Materia-prima",
        forma: "Cartao de credito",
        emissao: shift(-15),
        vencimentos: [
          { data: shift(-5), valor: 600 },
          { data: shift(25), valor: 600 },
        ],
        total: 1200,
      },
    ];
    localStorage.setItem(PAGAR_KEY, JSON.stringify(sample));
  }

  // Chat helpers
  const CHAT_KEY = "printlab_messages";
  function getChatMessages() {
    return JSON.parse(localStorage.getItem(CHAT_KEY) || "[]");
  }
  function saveChatMessages(arr) {
    localStorage.setItem(CHAT_KEY, JSON.stringify(arr));
  }
  function formatTime(ts) {
    const d = new Date(ts);
    if (isNaN(d.getTime())) return "";
    const hh = String(d.getHours()).padStart(2, "0");
    const mm = String(d.getMinutes()).padStart(2, "0");
    return `${hh}:${mm}`;
  }

  function getProdutosCatalog() {
    return JSON.parse(localStorage.getItem("printlab_produtos") || "[]");
  }

  function refreshProdutosDatalist() {
    const listId = "pv-produtos-options";
    let datalist = document.getElementById(listId);
    if (!datalist) {
      datalist = document.createElement("datalist");
      datalist.id = listId;
      document.body.appendChild(datalist);
    }
    const produtos = getProdutosCatalog();
    datalist.innerHTML = produtos.length
      ? produtos.map(p => {
          const label = `${(p.material || "").trim()} - ${(p.descricao || "").trim()}`.trim();
          return `<option value="${label}"></option>`;
        }).join("")
      : "";
    return listId;
  }

  function findProdutoByTerm(term) {
    if (!term) return null;
    const produtos = getProdutosCatalog();
    const normalized = term.toLowerCase().trim();
    return produtos.find(p => {
      const material = (p.material || "").toLowerCase();
      const descricao = (p.descricao || "").toLowerCase();
      const combined = `${p.material || ""} - ${p.descricao || ""}`.toLowerCase().trim();
      return material === normalized || descricao === normalized || combined === normalized;
    }) || null;
  }

  // Busca produto popup
  const produtoSearchModal = document.getElementById("produto-search-modal");
  let produtoSearchApply = null;
  let produtoSearchSelected = null;

  function renderProdutoSearch(term = "") {
    const results = document.getElementById("prod-search-results");
    const hint = document.getElementById("prod-search-hint");
    const produtos = getProdutosCatalog();
    const filtered = produtos.filter(p => {
      const t = term.toLowerCase();
      return !t || (p.material || "").toLowerCase().includes(t) || (p.descricao || "").toLowerCase().includes(t);
    });
    if (!filtered.length) {
      results.innerHTML = '<div style="color:#777;">Nenhum produto encontrado.</div>';
      hint.textContent = "";
      return;
    }
    results.innerHTML = filtered.map((p, idx) => `
      <label style="display:flex; gap:8px; align-items:center; padding:6px; border-bottom:1px solid #eef2fb; cursor:pointer;">
        <input type="radio" name="prod-search-opt" data-idx="${idx}">
        <div style="display:flex; flex-direction:column; gap:4px;">
          <strong>${p.material || ""}</strong>
          <span class="muted">${p.descricao || ""}</span>
          <span class="muted">Unidade: ${p.unidade || ""} | Preco: R$ ${numberToMoney(p.preco || 0)}</span>
        </div>
      </label>
    `).join("");
    Array.from(results.querySelectorAll('input[name="prod-search-opt"]')).forEach((radio, idx) => {
      radio.addEventListener("change", () => {
        const mapIdx = produtos.indexOf(filtered[idx]);
        produtoSearchSelected = mapIdx >= 0 ? produtos[mapIdx] : filtered[idx];
        hint.textContent = produtoSearchSelected ? "Produto selecionado." : "";
      });
    });
  }

  function openProdutoSearchModal(applyFn) {
    produtoSearchApply = applyFn;
    produtoSearchSelected = null;
    document.getElementById("prod-search-term").value = "";
    renderProdutoSearch("");
    produtoSearchModal.style.display = "flex";
  }

  function closeProdutoSearchModal() {
    produtoSearchModal.style.display = "none";
    produtoSearchApply = null;
    produtoSearchSelected = null;
  }

  document.getElementById("prod-search-term").addEventListener("input", (e) => {
    renderProdutoSearch(e.target.value);
  });
  document.getElementById("prod-search-cancel").addEventListener("click", closeProdutoSearchModal);
  document.getElementById("prod-search-apply").addEventListener("click", () => {
    if (produtoSearchApply && produtoSearchSelected) {
      produtoSearchApply(produtoSearchSelected);
      closeProdutoSearchModal();
    } else {
      document.getElementById("prod-search-hint").textContent = "Selecione um produto.";
    }
  });
  produtoSearchModal.addEventListener("click", (ev) => {
    if (ev.target === produtoSearchModal) closeProdutoSearchModal();
  });

  // Busca cliente popup
  const clienteSearchModal = document.getElementById("cliente-search-modal");
  let clienteSearchApply = null;
  let clienteSearchSelected = null;

  function renderClienteSearch(term = "") {
    const results = document.getElementById("cli-search-results");
    const hint = document.getElementById("cli-search-hint");
    const clientes = JSON.parse(localStorage.getItem("printlab_clients") || "[]");
    const filtered = clientes.filter(c => {
      const t = term.toLowerCase();
      return !t || (c.name || "").toLowerCase().includes(t);
    });
    if (!filtered.length) {
      results.innerHTML = '<div style="color:#777;">Nenhum cliente encontrado.</div>';
      hint.textContent = "";
      return;
    }
    results.innerHTML = filtered.map((c, idx) => `
      <label style="display:flex; gap:8px; align-items:center; padding:6px; border-bottom:1px solid #eef2fb; cursor:pointer;">
        <input type="radio" name="cli-search-opt" data-idx="${idx}">
        <div style="display:flex; flex-direction:column; gap:4px;">
          <strong>${c.name || ""}</strong>
          <span class="muted">${c.contato || ""} ${c.telefone ? " - " + c.telefone : ""}</span>
        </div>
      </label>
    `).join("");
    Array.from(results.querySelectorAll('input[name="cli-search-opt"]')).forEach((radio, idx) => {
      radio.addEventListener("change", () => {
        const mapIdx = clientes.indexOf(filtered[idx]);
        clienteSearchSelected = mapIdx >= 0 ? clientes[mapIdx] : filtered[idx];
        hint.textContent = clienteSearchSelected ? "Cliente selecionado." : "";
      });
    });
  }

  function openClienteSearchModal(applyFn) {
    clienteSearchApply = applyFn;
    clienteSearchSelected = null;
    document.getElementById("cli-search-term").value = "";
    renderClienteSearch("");
    clienteSearchModal.style.display = "flex";
  }

  function closeClienteSearchModal() {
    clienteSearchModal.style.display = "none";
    clienteSearchApply = null;
    clienteSearchSelected = null;
  }

  document.getElementById("cli-search-term").addEventListener("input", (e) => {
    renderClienteSearch(e.target.value);
  });
  document.getElementById("cli-search-cancel").addEventListener("click", closeClienteSearchModal);
  document.getElementById("cli-search-apply").addEventListener("click", () => {
    if (clienteSearchApply && clienteSearchSelected) {
      clienteSearchApply(clienteSearchSelected);
      closeClienteSearchModal();
    } else {
      document.getElementById("cli-search-hint").textContent = "Selecione um cliente.";
    }
  });
  clienteSearchModal.addEventListener("click", (ev) => {
    if (ev.target === clienteSearchModal) closeClienteSearchModal();
  });

  // Status helpers
  const statusModal = document.getElementById("status-modal");
  const statusChoicesWrap = document.getElementById("status-choices");
  let statusRowIndex = -1;
  let statusContext = "pedido"; // pedido | orcamento | ordem
  const STATUS_CHOICES = {
    pedido: ["Producao", "Pronto", "Entregue", "Cancelado"],
    orcamento: [
      "Enviado",
      "Aguardando aprovação",
      "Aprovado",
      "Não aprovado",
      "Sem retorno",
    ],
    ordem: ["Produ\u00E7\u00E3o", "Acabamento", "Pronto"],
  };
  const statusColors = {
    "Producao": "#57A695",
    "Pronto": "#7AC79D",
    "Entregue": "#4E5A62",
    "Cancelado": "#E87D75",
    "Enviado": "#5697AC",
    "Aguardando aprovação": "#DDDBA6",
    "Aprovado": "#9DD3AF",
    "Não aprovado": "#E8999B",
    "Sem retorno": "#E8AD81",
  };
  const statusColorsByContext = {
    ordem: {
      "Produ\u00E7\u00E3o": "#9DD3AF",
      "Producao": "#9DD3AF",
      "Acabamento": "#EDCAB0",
      "Pronto": "#48887B",
    },
  };
  function getStatusColor(status, context = "") {
    if (context && statusColorsByContext[context] && statusColorsByContext[context][status]) {
      return statusColorsByContext[context][status];
    }
    return statusColors[status] || "";
  }
  const statusTextColors = {
    "Entregue": "#FEFEFE",
  };
  function getStatusTextColor(status, context = "") {
    if (statusTextColors[status]) return statusTextColors[status];
    const color = getStatusColor(status, context);
    if (!color) return "";
    const hex = color.replace("#", "");
    if (hex.length === 6) {
      const r = parseInt(hex.substring(0,2), 16);
      const g = parseInt(hex.substring(2,4), 16);
      const b = parseInt(hex.substring(4,6), 16);
      const lum = 0.299*r + 0.587*g + 0.114*b;
      return lum > 170 ? "#000" : "#fff";
    }
    return "#000";
  }
  function budgetToPedidoSeed(budget) {
    if (!budget) return null;
    return {
      cliente: budget.cliente || budget.client || "",
      contato: budget.contato || "",
      telefone: budget.telefone || "",
      observacao: budget.observacao || "",
      entrega: budget.entrega || "Cliente",
      precoEntrega: budget.precoEntrega || 0,
      endereco: budget.endereco || "",
      forma: budget.forma || "",
      condicao: budget.condicao || "",
      prazo: budget.prazo || "",
      total: budget.total || 0,
      orcamentoRef: budget.number || "",
      items: (budget.items || []).map(it => ({
        produto: it.produto || "",
        material: it.material || "",
        descricao: it.descricao || "",
        unidade: it.unidade || "",
        arquivo: it.arquivo || "",
        quantidade: it.quantidade || 0,
        unitario: it.unitario || 0,
        subtotal: it.subtotal || 0,
        imagem: it.imagem || "",
      })),
    };
  }
  function buildStatusChoices(context) {
    if (!statusChoicesWrap) return;
    statusChoicesWrap.innerHTML = "";
    const list = STATUS_CHOICES[context] || [];
    list.forEach(st => {
      const btn = document.createElement("button");
      btn.className = "primary-btn";
      btn.dataset.statusChoice = st;
      btn.textContent = st;
      const color = getStatusColor(st, context);
      const textColor = getStatusTextColor(st, context) || "#000";
      if (color) {
        btn.style.background = color;
        btn.style.color = textColor;
        btn.style.borderColor = color;
      }
      btn.addEventListener("click", () => applyStatus(st));
      statusChoicesWrap.appendChild(btn);
    });
  }

  function generateNextNumber(storageKey, width = 4) {
    const list = JSON.parse(localStorage.getItem(storageKey) || "[]");
    const maxNum = list.reduce((max, item) => {
      const raw = (item && item.number) ? String(item.number) : "";
      const numeric = parseInt(raw.replace(/\D/g, ""), 10);
      if (isNaN(numeric)) return max;
      return Math.max(max, numeric);
    }, 0);
    return String(maxNum + 1).padStart(width, "0");
  }
  function openStatusModal(idx, context = "pedido") {
    statusRowIndex = idx;
    statusContext = context;
    document.getElementById("status-hint").textContent = "";
    buildStatusChoices(context);
    statusModal.style.display = "flex";
  }
  function closeStatusModal() {
    statusModal.style.display = "none";
    statusRowIndex = -1;
  }

  const ordemImgModal = document.getElementById("ordem-img-modal");
  const ordemImgPreview = document.getElementById("ordem-img-preview");
  function openOrdemImageModal(src) {
    if (!ordemImgModal || !ordemImgPreview) return;
    ordemImgPreview.src = src || "";
    ordemImgPreview.style.display = src ? "block" : "none";
    ordemImgModal.style.display = "flex";
  }
  function closeOrdemImageModal() {
    if (ordemImgModal) ordemImgModal.style.display = "none";
  }
  if (ordemImgModal && !ordemImgModal.dataset.bound) {
    ordemImgModal.addEventListener("click", (ev) => {
      if (ev.target === ordemImgModal) closeOrdemImageModal();
    });
    document.getElementById("ordem-img-close")?.addEventListener("click", closeOrdemImageModal);
    ordemImgModal.dataset.bound = "1";
  }
  statusModal.addEventListener("click", (ev) => {
    if (ev.target === statusModal) closeStatusModal();
  });
  document.getElementById("status-cancel").addEventListener("click", closeStatusModal);
  function applyStatus(status) {
    if (statusRowIndex < 0) return;
    const key = statusContext === "orcamento" ? "printlab_budgets" : statusContext === "ordem" ? "printlab_ordens_producao" : "printlab_pedidos_venda";
    const list = JSON.parse(localStorage.getItem(key) || "[]");
    if (!list[statusRowIndex]) return;
    list[statusRowIndex].status = status;
    localStorage.setItem(key, JSON.stringify(list));
    const selectedRecord = list[statusRowIndex];
    closeStatusModal();
    if (statusContext === "orcamento") {
      if (status === "Aprovado") {
        const proceed = window.confirm("Deseja emitir o pedido de venda a partir deste orçamento?");
        if (proceed) {
          const seed = budgetToPedidoSeed(selectedRecord);
          openPedidoModal(seed, -1, "printlab_pedidos_venda", renderPedidosVenda);
          return;
        }
      }
      renderOrcamento();
    } else if (statusContext === "ordem") {
      renderOrdensProducao();
    } else {
      renderPedidosVenda();
    }
  }

  function buildWhatsPreview() {
    const num = document.getElementById("pv-numero")?.value || "";
    const entrega = document.getElementById("pv-entrega")?.value || "";
    const prazo = document.getElementById("pv-prazo")?.value || document.getElementById("pv-prazo-select")?.value || "";
    const total = document.getElementById("pv-total")?.value || "0,00";
    if (currentPedidoKey === "printlab_pedidos_venda") {
      const lines = [];
      lines.push("*PEDIDO REALIZADO*");
      lines.push("");
      lines.push(`*PEDIDO DE VENDA:* ${num}`);
      lines.push("---------------------------------------------------------");
      pedidoItems.forEach((it, idx) => {
        const subtotal = it.subtotal || (moneyToNumber(it.quantidade) * moneyToNumber(it.unitario));
        const unidade = (it.unidade || "").trim();
        const quantidadeLabel = unidade ? `${it.quantidade || ""} ${unidade}` : (it.quantidade || "");
        const unitVal = numberToMoney(moneyToNumber(it.unitario));
        lines.push(`*ITEM:* ${idx + 1}`);
        lines.push(`*MATERIAL:* ${it.material || ""}`);
        lines.push(`*DESCRIÇÃO:* ${it.descricao || ""}`);
        lines.push(`*QUANTIDADE:* ${quantidadeLabel}`);
        lines.push(`*PREÇO UNITÁRIO:* R$ ${unitVal}`);
        lines.push(`*SUBTOTAL:* R$ ${numberToMoney(subtotal || 0)}`);
        lines.push("---------------------------------------------------------");
      });
      lines.push(`*ENTREGA:* ${entrega}`);
      lines.push(`*PRAZO DE ENTREGA:* ${prazo}`);
      lines.push("---------------------------------------------------------");
      lines.push(`*TOTAL:* R$ ${total}`);
      return lines.join("\n");
    }
    const lines = [];
    lines.push(`*NÚMERO ORÇAMENTO:* ${num}`);
    lines.push("---------------------------------------------------------");
    pedidoItems.forEach((it, idx) => {
      const subtotal = it.subtotal || (moneyToNumber(it.quantidade) * moneyToNumber(it.unitario));
      const unidade = (it.unidade || "").trim();
      const quantidadeLabel = unidade ? `${it.quantidade || ""} ${unidade}` : (it.quantidade || "");
      const unitVal = numberToMoney(moneyToNumber(it.unitario));
      lines.push(`*ITEM:* ${idx + 1}`);
      lines.push(`*MATERIAL:* ${it.material || ""}`);
      lines.push(`*DESCRIÇÃO:* ${it.descricao || ""}`);
      lines.push(`*QUANTIDADE:* ${quantidadeLabel}`);
      lines.push(`*PREÇO UNITÁRIO:* R$ ${unitVal}`);
      lines.push(`*SUBTOTAL:* R$ ${numberToMoney(subtotal || 0)}`);
      lines.push("---------------------------------------------------------");
    });
    lines.push(`*ENTREGA:* ${entrega}`);
    lines.push(`*PRAZO DE ENTREGA:* ${prazo}`);
    lines.push("---------------------------------------------------------");
    lines.push(`*TOTAL:* R$ ${total}`);
    return lines.join("\n");
  }
  function openWhatsModal() {
    const allow = ["printlab_ordens_producao", "printlab_budgets", "printlab_pedidos_venda"];
    if (!allow.includes(currentPedidoKey)) return;
    if (whatsText) {
      whatsText.textContent = buildWhatsPreview();
    }
    if (whatsHint) whatsHint.textContent = "";
    if (whatsModal) {
      const titleEl = whatsModal.querySelector("h3");
      if (titleEl) {
        titleEl.textContent = currentPedidoKey === "printlab_pedidos_venda"
          ? "Copiar pedido para WhatsApp"
          : "Copiar orçamento para WhatsApp";
      }
      whatsModal.style.display = "flex";
    }
  }
  function closeWhatsModal() {
    if (whatsModal) whatsModal.style.display = "none";
  }
  function copyWhatsText() {
    const content = whatsText?.textContent || "";
    if (!content) return;
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(content).then(() => {
        if (whatsHint) whatsHint.textContent = "Copiado para a área de transferência.";
      }).catch(() => {
        if (whatsHint) whatsHint.textContent = "Não foi possível copiar.";
      });
    } else {
      const ta = document.createElement("textarea");
      ta.value = content;
      document.body.appendChild(ta);
      ta.select();
      try {
        document.execCommand("copy");
        if (whatsHint) whatsHint.textContent = "Copiado para a área de transferência.";
      } catch (e) {
        if (whatsHint) whatsHint.textContent = "Não foi possível copiar.";
      }
      document.body.removeChild(ta);
    }
  }

  // Helpers: orçamento e pedido de venda
  function findBudgetByNumber(num) {
    const budgets = JSON.parse(localStorage.getItem("printlab_budgets") || "[]");
    return budgets.find(b => (b.number || "").toString() === num.toString());
  }
  function findPedidoByNumber(num) {
    const pedidos = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]");
    if (!num) return null;
    return pedidos.find(p => {
      const n = (p.number || "").toString().trim().toLowerCase();
      const term = num.toString().trim().toLowerCase();
      return n === term || n.endsWith(term) || term.endsWith(n);
    });
  }
  function mapItemsFromPayload(srcItems) {
    return srcItems && srcItems.length ? srcItems.map(it => ({
      produto: it.produto || it.material || "",
      material: it.material || "",
      descricao: it.descricao || "",
      unidade: it.unidade || "",
      arquivo: it.arquivo || "",
      quantidade: numberToMoney(it.quantidade || 0),
      unitario: numberToMoney(it.unitario || 0),
      subtotal: it.subtotal || 0,
      imagem: it.imagem || "",
    })) : [{ produto: "", material: "", descricao: "", unidade: "", arquivo: "", quantidade: "1", unitario: "0,00", subtotal: 0, imagem: "" }];
  }
  function applyBudgetToPedido(budget) {
    if (!budget) return;
    document.getElementById("pv-orc-ref").value = budget.number || "";
    document.getElementById("pv-orc-hint").textContent = "Orçamento aplicado.";
    document.getElementById("pv-cliente").value = budget.cliente || budget.client || "";
    document.getElementById("pv-contato").value = budget.contato || "";
    document.getElementById("pv-telefone").value = budget.telefone || "";
    document.getElementById("pv-observacao").value = budget.observacao || "";
    document.getElementById("pv-entrega").value = budget.entrega || "Cliente";
    document.getElementById("pv-preco-entrega").value = numberToMoney(budget.precoEntrega || 0);
    document.getElementById("pv-endereco").value = budget.endereco || "";
    document.getElementById("pv-forma").value = budget.forma || "";
    updateCondicoesByForma();
    document.getElementById("pv-condicao").value = budget.condicao || "";
    const prazoInput = document.getElementById("pv-prazo");
    if (prazoInput) prazoInput.value = budget.prazo || "";
    pedidoItems = mapItemsFromPayload(budget.items);
    renderPedidoItems();
    updateEntregaFields();
    updatePedidoTotal();
  }
  function applyPedidoToOrdem(pedido) {
    if (!pedido) return;
    document.getElementById("pv-pedido-ref").value = pedido.number || "";
    document.getElementById("pv-pedido-hint").textContent = "Pedido vinculado.";
    document.getElementById("pv-cliente").value = pedido.cliente || pedido.client || "";
    document.getElementById("pv-contato").value = pedido.contato || "";
    document.getElementById("pv-telefone").value = pedido.telefone || "";
    document.getElementById("pv-observacao").value = pedido.observacao || "";
    document.getElementById("pv-entrega").value = pedido.entrega || "Cliente";
    document.getElementById("pv-preco-entrega").value = numberToMoney(pedido.precoEntrega || 0);
    document.getElementById("pv-endereco").value = pedido.endereco || "";
    document.getElementById("pv-forma").value = pedido.forma || "";
    updateCondicoesByForma();
    document.getElementById("pv-condicao").value = pedido.condicao || "";
    const prazoInput = document.getElementById("pv-prazo");
    if (prazoInput) prazoInput.value = pedido.prazo || "";
    pedidoItems = mapItemsFromPayload(pedido.items);
    renderPedidoItems();
    updateEntregaFields();
    updatePedidoTotal();
  }

  // Pedido ref search modal
  const pedidoRefModal = document.getElementById("pedido-ref-modal");
  const pedidoRefResults = document.getElementById("pedido-ref-results");
  const pedidoRefHint = document.getElementById("pedido-ref-hint");
  const pedidoRefTerm = document.getElementById("pedido-ref-term");
  const pedidoItemsModal = document.getElementById("pedido-items-modal");
  const pedidoItemsList = document.getElementById("pedido-items-list");
  const pedidoItemsInfo = document.getElementById("pedido-items-info");
  const pedidoItemsHint = document.getElementById("pedido-items-hint");
  let pedidoRefSelected = null;
  let pedidoItemsSelected = [];

  function renderPedidoRefList(term = "") {
    const pedidos = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]")
      .filter(p => {
        if (!term) return true;
        const n = (p.number || "").toString().toLowerCase();
        return n.includes(term.toLowerCase());
      });
    if (!pedidoRefResults) return;
    if (!pedidos.length) {
      pedidoRefResults.innerHTML = '<div style="color:#777;">Nenhum pedido de venda cadastrado.</div>';
      return;
    }
    pedidoRefResults.innerHTML = pedidos.map((p, idx) => `
      <label style="display:flex; gap:8px; align-items:flex-start; padding:6px; border:1px solid var(--border); border-radius:8px; margin-bottom:6px; cursor:pointer;">
        <input type="radio" name="pedido-ref-radio" value="${idx}">
        <div>
          <div style="font-weight:600;">${p.number || ""}</div>
          <div style="font-size:13px; color:#555;">${p.cliente || p.client || ""} • ${p.data || ""}</div>
          <div style="font-size:12px; color:#777;">Total: ${numberToMoney(p.total || 0)}</div>
        </div>
      </label>
    `).join("");
    pedidoRefResults.querySelectorAll('input[name="pedido-ref-radio"]').forEach(r => {
      r.addEventListener("change", () => {
        const idx = parseInt(r.value, 10);
        const arr = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]").filter(p => {
          if (!term) return true;
          const n = (p.number || "").toString().toLowerCase();
          return n.includes(term.toLowerCase());
        });
        pedidoRefSelected = arr[idx] || null;
        if (pedidoRefHint) pedidoRefHint.textContent = pedidoRefSelected ? "Pedido selecionado." : "";
      });
      r.addEventListener("dblclick", () => {
        const idx = parseInt(r.value, 10);
        const arr = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]").filter(p => {
          if (!term) return true;
          const n = (p.number || "").toString().toLowerCase();
          return n.includes(term.toLowerCase());
        });
        pedidoRefSelected = arr[idx] || null;
        if (pedidoRefSelected) {
          openPedidoItemsModal(pedidoRefSelected);
        }
      });
    });
  }
  function openPedidoRefModal() {
    pedidoRefSelected = null;
    if (pedidoRefHint) pedidoRefHint.textContent = "";
    if (pedidoRefTerm) pedidoRefTerm.value = "";
    renderPedidoRefList("");
    if (pedidoRefModal) pedidoRefModal.style.display = "flex";
  }
  function closePedidoRefModal() {
    pedidoRefSelected = null;
    if (pedidoRefModal) pedidoRefModal.style.display = "none";
  }
  if (pedidoRefModal) {
    pedidoRefModal.addEventListener("click", (ev) => {
      if (ev.target === pedidoRefModal) closePedidoRefModal();
    });
  }
  const pedidoRefCancel = document.getElementById("pedido-ref-cancel");
  const pedidoRefApply = document.getElementById("pedido-ref-apply");
  if (pedidoRefCancel) pedidoRefCancel.addEventListener("click", closePedidoRefModal);
  if (pedidoRefApply) {
    pedidoRefApply.addEventListener("click", () => {
      if (!pedidoRefSelected) {
        if (pedidoRefHint) pedidoRefHint.textContent = "Selecione um pedido.";
        return;
      }
      openPedidoItemsModal(pedidoRefSelected);
    });
  }
  if (pedidoRefTerm) {
    pedidoRefTerm.addEventListener("input", () => renderPedidoRefList(pedidoRefTerm.value.trim()));
  }

  function openPedidoItemsModal(pedido) {
    if (!pedido) return;
    pedidoItemsSelected = (pedido.items || []).map((_, idx) => idx); // default all
    if (pedidoItemsInfo) {
      pedidoItemsInfo.textContent = `${pedido.number || ""} • ${pedido.cliente || pedido.client || ""} • ${pedido.data || ""}`;
    }
    if (pedidoItemsList) {
      const items = pedido.items || [];
      if (!items.length) {
        pedidoItemsList.innerHTML = '<div style="color:#777;">Pedido não possui itens.</div>';
      } else {
        pedidoItemsList.innerHTML = items.map((it, idx) => `
          <label style="display:flex; gap:10px; padding:6px; border:1px solid var(--border); border-radius:8px; margin-bottom:6px; cursor:pointer;">
            <input type="checkbox" data-pedido-item-idx="${idx}" checked>
            <div>
              <div style="font-weight:600;">${it.produto || it.material || "Item " + (idx+1)}</div>
              <div style="font-size:13px; color:#555;">Qtd: ${it.quantidade || 0} • Unit: ${numberToMoney(it.unitario || 0)} • Subtotal: ${numberToMoney(it.subtotal || 0)}</div>
              <div style="font-size:12px; color:#777;">${it.descricao || ""}</div>
            </div>
          </label>
        `).join("");
        pedidoItemsList.querySelectorAll('input[data-pedido-item-idx]').forEach(cb => {
          cb.addEventListener("change", () => {
            const idx = parseInt(cb.dataset.pedidoItemIdx, 10);
            if (cb.checked) {
              if (!pedidoItemsSelected.includes(idx)) pedidoItemsSelected.push(idx);
            } else {
              pedidoItemsSelected = pedidoItemsSelected.filter(i => i !== idx);
            }
          });
        });
      }
    }
    if (pedidoItemsHint) pedidoItemsHint.textContent = "";
    closePedidoRefModal();
    if (pedidoItemsModal) pedidoItemsModal.style.display = "flex";
    // store selection in closure
    pedidoRefSelected = pedido;
  }
  function closePedidoItemsModal() {
    if (pedidoItemsModal) pedidoItemsModal.style.display = "none";
  }
  const pedidoItemsCancel = document.getElementById("pedido-items-cancel");
  const pedidoItemsApply = document.getElementById("pedido-items-apply");
  if (pedidoItemsCancel) pedidoItemsCancel.addEventListener("click", closePedidoItemsModal);
  if (pedidoItemsApply) {
    pedidoItemsApply.addEventListener("click", () => {
      if (!pedidoRefSelected) {
        if (pedidoItemsHint) pedidoItemsHint.textContent = "Nenhum pedido selecionado.";
        return;
      }
      const srcItems = pedidoRefSelected.items || [];
      const subset = pedidoItemsSelected.length ? pedidoItemsSelected.map(i => srcItems[i]).filter(Boolean) : srcItems;
      const pedidoClone = { ...pedidoRefSelected, items: subset };
      applyPedidoToOrdem(pedidoClone);
      closePedidoItemsModal();
    });
  }

  // Produto form popup
  const produtoFormModal = document.getElementById("produto-form-modal");
  const produtoFormClose = document.getElementById("produto-form-close");
  const produtoFormApply = document.getElementById("produto-form-apply");
  let produtoFormTargetIndex = -1;
  function openProdutoFormModal(targetIndex = -1) {
    produtoFormTargetIndex = targetIndex;
    if (produtoFormModal) produtoFormModal.style.display = "flex";
  }
  function closeProdutoFormModal() {
    produtoFormTargetIndex = -1;
    if (produtoFormModal) produtoFormModal.style.display = "none";
  }
  function collectProdutoFormData() {
    const getVal = (id) => {
      const el = document.getElementById(id);
      return el ? el.value.trim() : "";
    };
    const tamanho = (() => {
      const checked = document.querySelector('input[name="imp-tam"]:checked');
      return checked ? checked.value : "";
    })();
    const acabamentos = Array.from(document.querySelectorAll('#pf-acabamentos input[type="checkbox"]:checked')).map(c => c.value);
    return {
      tipo: getVal("pf-tipo"),
      cor: getVal("pf-cor"),
      papel: getVal("pf-papel"),
      encad: getVal("pf-encad"),
      largura: getVal("pf-largura"),
      altura: getVal("pf-altura"),
      tamanho,
      acabamentos: acabamentos.join(", "),
      quantidade: getVal("pf-quantidade"),
      precoPagina: getVal("pf-preco-pagina"),
      precoUnit: getVal("pf-preco-unit"),
      subtotal: getVal("pf-subtotal"),
      observacao: getVal("pf-observacao"),
      descricao: getVal("pf-descricao"),
    };
  }
  function applyProdutoFormToItem() {
    if (produtoFormTargetIndex < 0 || produtoFormTargetIndex >= pedidoItems.length) {
      pedidoAlert.textContent = "Selecione um item para aplicar.";
      return;
    }
    const data = collectProdutoFormData();
    const idx = produtoFormTargetIndex;
    const item = pedidoItems[idx];
    const labelParts = [data.tipo, data.papel].filter(Boolean);
    item.produto = labelParts.join(" - ") || data.tipo || data.papel || "Produto";
    item.material = data.papel || item.material;
    const descParts = [
      data.descricao,
      data.cor ? `Cor: ${data.cor}` : "",
      data.encad ? `Encadernacao: ${data.encad}` : "",
      data.tamanho ? `Tam: ${data.tamanho}` : "",
      data.largura || data.altura ? `Medidas: ${data.largura}x${data.altura} mm` : "",
      data.acabamentos ? `Acab: ${data.acabamentos}` : "",
    ].filter(Boolean);
    item.descricao = descParts.join(" | ");
    if (data.quantidade) item.quantidade = data.quantidade.replace(/[^\d.,]/g, "");
    if (data.precoUnit) item.unitario = data.precoUnit.replace(/[^\d.,]/g, "");
    const tbody = document.getElementById("pv-items-body");
    const row = tbody ? tbody.children[idx] : null;
    if (row) {
      const setVal = (field, val) => {
        const input = row.querySelector(`input[data-field="${field}"]`);
        if (input) input.value = val;
      };
      setVal("produto", item.produto);
      setVal("material", item.material);
      setVal("descricao", item.descricao);
      setVal("quantidade", item.quantidade);
      setVal("unitario", item.unitario);
    }
    updateItemSubtotal(idx);
    pedidoAlert.textContent = "Produto aplicado ao item.";
    closeProdutoFormModal();
  }
  if (produtoFormClose) produtoFormClose.addEventListener("click", closeProdutoFormModal);
  if (produtoFormModal) {
    produtoFormModal.addEventListener("click", (ev) => {
      if (ev.target === produtoFormModal) closeProdutoFormModal();
    });
  }
  if (produtoFormApply) {
    produtoFormApply.addEventListener("click", applyProdutoFormToItem);
  }

  function buildItemRow(item, index, produtoListId) {
    const tr = document.createElement("tr");
    const fileInput = document.createElement("input");
    fileInput.type = "file";
    fileInput.style.display = "none";
    const folderInput = document.createElement("input");
    folderInput.type = "file";
    folderInput.style.display = "none";
    folderInput.setAttribute("webkitdirectory", "true");
    folderInput.setAttribute("directory", "true");
    const isBudget = currentPedidoKey === "printlab_budgets";
    const unidadeValue = item.unidade || "";
    const unidadeOptions = ["UNIDADE(S)", "CONJUNTO(S)"];
    let unidadeOptionsHtml = '<option value="">Selecione</option>'
      + unidadeOptions.map(opt => `<option${unidadeValue === opt ? " selected" : ""}>${opt}</option>`).join("");
    if (unidadeValue && !unidadeOptions.includes(unidadeValue)) {
      unidadeOptionsHtml += `<option selected>${unidadeValue}</option>`;
    }
    const unidadeFieldHtml = isBudget
      ? `<select class="inline-input" data-field="unidade">${unidadeOptionsHtml}</select>`
      : `<input class="inline-input" data-field="unidade" value="${unidadeValue}" placeholder="Unidade">`;

    tr.innerHTML = `
      <td data-label="ITEM">${index + 1}</td>
      <td data-label="Produto">
        <div style="display:flex; gap:6px; align-items:center;">
          <input class="inline-input" style="flex:1;" list="${produtoListId}" data-field="produto" value="${item.produto || ""}" placeholder="Buscar produto">
          <button class="ghost-btn" data-action="busca-produto" title="Pesquisar produto"><img src="static/icone_pesquisa.svg" alt="" height="14"></button>
        </div>
      </td>
      <td data-label="MATERIAL"><input class="inline-input" data-field="material" value="${item.material || ""}" placeholder="Material"></td>
      <td data-label="DESCRIÇÃO"><input class="inline-input" data-field="descricao" value="${item.descricao || ""}" placeholder="Descricao"></td>
      <td data-label="Unidade">${unidadeFieldHtml}</td>
      <td data-label="Arquivo">
        <div style="display:flex; gap:6px; align-items:center;">
          <input class="inline-input" style="flex:1;" data-field="arquivo" value="${item.arquivo || ""}" placeholder="Caminho do arquivo/pasta">
          <button class="ghost-btn" data-action="file" title="Escolher arquivo"><img src="static/icone_arquivo.svg" alt="" height="14"></button>
          <button class="ghost-btn" data-action="folder" title="Escolher pasta"><img src="static/icone_arquivo.svg" alt="" height="14"></button>
        </div>
      </td>
      <td data-label="Imagem (JPG, max 1 MB)">
        <div style="display:flex; flex-direction:column; gap:6px; width:100%;">
          <input type="file" accept="image/jpeg" data-action="img-upload">
          <img data-preview="item-img" alt="Preview" style="max-width:140px; max-height:100px; object-fit:contain; border:1px solid var(--border); border-radius:6px; ${item.imagem ? "" : "display:none;"}" src="${item.imagem || ""}">
          <button class="ghost-btn" data-action="img-clear" style="width:max-content;">Remover imagem</button>
          <span class="small-muted" data-hint="img-hint"></span>
        </div>
      </td>
      <td data-label="QUANTIDADE"><input class="inline-input" data-field="quantidade" value="${item.quantidade || ""}" placeholder="0,00"></td>
      <td data-label="PREÇO UNITÁRIO (R$)"><input class="inline-input" data-field="unitario" value="${item.unitario || ""}" placeholder="0,00"></td>
      <td data-label="SUBTOTAL" data-field="subtotal">${numberToMoney(item.subtotal || 0)}</td>
    `;
    const ensureUnidadeOption = (selectEl, value) => {
      if (!selectEl || !value) return;
      const exists = Array.from(selectEl.options).some(opt => opt.value === value);
      if (exists) return;
      const option = document.createElement("option");
      option.value = value;
      option.textContent = value;
      selectEl.appendChild(option);
    };
    const setFieldValue = (field, value) => {
      const control = tr.querySelector(`[data-field="${field}"]`);
      if (!control) return;
      if (control.tagName.toLowerCase() === "select") {
        ensureUnidadeOption(control, value);
      }
      control.value = value;
    };
    const applyProduto = (produto) => {
      if (!produto) {
        pedidoAlert.textContent = "Produto nao encontrado.";
        return;
      }
      const material = (produto.material || "").toUpperCase();
      const descricao = (produto.descricao || "").toUpperCase();
      const label = `${material} - ${descricao}`.trim();
      pedidoItems[index].produto = label || material;
      pedidoItems[index].material = material;
      pedidoItems[index].descricao = descricao;
      pedidoItems[index].unidade = produto.unidade || "";
      pedidoItems[index].unitario = numberToMoney(produto.preco || 0);
      setFieldValue("produto", pedidoItems[index].produto);
      setFieldValue("material", pedidoItems[index].material);
      setFieldValue("descricao", pedidoItems[index].descricao);
      setFieldValue("unidade", pedidoItems[index].unidade);
      setFieldValue("unitario", pedidoItems[index].unitario);
      updateItemSubtotal(index);
      pedidoAlert.textContent = "Produto preenchido.";
    };

    tr.querySelectorAll("[data-field]").forEach(el => {
      const handler = () => {
        const field = el.dataset.field;
        if (!field) return;
        let val = el.value;
        if (field === "material" || field === "descricao") {
          const upper = val.toUpperCase();
          if (val !== upper) {
            val = upper;
            el.value = upper;
          }
        }
        if (field === "quantidade" || field === "unitario") {
          val = val.replace(/[^\d.,]/g, "");
          if (el.value !== val) el.value = val;
        }
        pedidoItems[index][field] = val;
        if (field === "produto") {
          const found = findProdutoByTerm(val);
          if (found) applyProduto(found);
        }
        updateItemSubtotal(index);
      };
      const evt = el.tagName.toLowerCase() === "select" ? "change" : "input";
      el.addEventListener(evt, handler);
    });

    tr.querySelectorAll("button[data-action]").forEach(btn => {
      const action = btn.dataset.action;
      if (action === "file") {
        btn.addEventListener("click", () => fileInput.click());
        fileInput.addEventListener("change", () => {
          const chosen = fileInput.files && fileInput.files[0];
          if (chosen) {
            const path = fileInput.value || chosen.name;
            pedidoItems[index].arquivo = path;
            tr.querySelector('input[data-field="arquivo"]').value = path;
          }
        });
      } else if (action === "folder") {
        btn.addEventListener("click", () => folderInput.click());
        folderInput.addEventListener("change", () => {
          const chosen = folderInput.files && folderInput.files[0];
          if (chosen) {
            const path = folderInput.value || chosen.webkitRelativePath || chosen.name;
            pedidoItems[index].arquivo = path;
            tr.querySelector('input[data-field="arquivo"]').value = pedidoItems[index].arquivo;
          }
        });
      } else if (action === "busca-produto") {
        btn.addEventListener("click", () => {
          openProdutoFormModal(index);
        });
      } else if (action === "img-clear") {
        btn.addEventListener("click", () => {
          pedidoItems[index].imagem = "";
          const preview = tr.querySelector('[data-preview="item-img"]');
          if (preview) {
            preview.src = "";
            preview.style.display = "none";
          }
          const hint = tr.querySelector('[data-hint="img-hint"]');
          if (hint) hint.textContent = "Imagem removida.";
        });
      }
    });
    const imgUpload = tr.querySelector('input[data-action="img-upload"]');
    if (imgUpload) {
      imgUpload.addEventListener("change", () => {
        const file = imgUpload.files && imgUpload.files[0];
        const hint = tr.querySelector('[data-hint="img-hint"]');
        const preview = tr.querySelector('[data-preview="item-img"]');
        if (!file) {
          pedidoItems[index].imagem = "";
          if (preview) {
            preview.src = "";
            preview.style.display = "none";
          }
          if (hint) hint.textContent = "";
          return;
        }
        if (!(file.type && file.type.toLowerCase().includes("jpeg"))) {
          if (hint) hint.textContent = "Use JPG.";
          imgUpload.value = "";
          return;
        }
        if (file.size > 1048576) {
          if (hint) hint.textContent = "Maximo 1 MB.";
          imgUpload.value = "";
          return;
        }
        const reader = new FileReader();
        reader.onload = () => {
          pedidoItems[index].imagem = reader.result || "";
          if (preview) {
            preview.src = pedidoItems[index].imagem;
            preview.style.display = pedidoItems[index].imagem ? "block" : "none";
          }
          if (hint) hint.textContent = "Imagem carregada.";
        };
        reader.readAsDataURL(file);
      });
    }
    tr.appendChild(fileInput);
    tr.appendChild(folderInput);
    return tr;
  }

  function updateItemSubtotal(idx) {
    const item = pedidoItems[idx];
    const qty = moneyToNumber(item.quantidade);
    const unit = moneyToNumber(item.unitario);
    const subtotal = qty * unit;
    item.subtotal = subtotal;
    const tbody = document.getElementById("pv-items-body");
    const row = tbody.children[idx];
    if (row) {
      const td = row.querySelector('td[data-field="subtotal"]');
      if (td) td.textContent = numberToMoney(subtotal);
    }
    updatePedidoTotal();
  }

  function renderPedidoItems() {
    const tbody = document.getElementById("pv-items-body");
    const listId = refreshProdutosDatalist();
    if (!pedidoItems.length) {
      pedidoItems.push({ produto: "", material: "", descricao: "", unidade: "", arquivo: "", quantidade: "1", unitario: "0,00", subtotal: 0, imagem: "" });
    }
    tbody.innerHTML = "";
    pedidoItems.forEach((item, idx) => {
      const row = buildItemRow(item, idx, listId);
      if (currentPedidoKey === "printlab_budgets") {
        const arq = row.querySelector('td[data-label="Arquivo"]');
        if (arq) arq.style.display = "none";
      }
      tbody.appendChild(row);
    });
    updatePedidoTotal();
  }

  function updateCondicoesByForma() {
    const forma = document.getElementById("pv-forma").value;
    const condicao = document.getElementById("pv-condicao");
    const map = {
      "A vista - PIX": ["A vista - PIX"],
      "A vista - Dinheiro": ["A vista - Dinheiro"],
      "A vista - Cartao de Debito": ["A vista - Cartao de Debito"],
      "Cartao de Credito": ["1x", "2x", "3x", "4x"],
      "Boleto bancario": ["Boleto bancario"],
    };
    condicao.innerHTML = '<option value="">Selecione</option>';
    (map[forma] || []).forEach(opt => {
      const option = document.createElement("option");
      option.value = opt;
      option.textContent = opt;
      condicao.appendChild(option);
    });
  }

  function updateEntregaFields() {
    const entrega = document.getElementById("pv-entrega").value;
    const preco = document.getElementById("pv-preco-entrega");
    const endereco = document.getElementById("pv-endereco");
    const enabled = entrega === "Cliente";
    preco.disabled = !enabled;
    endereco.disabled = !enabled;
    if (!enabled) {
      preco.value = "";
      endereco.value = "";
    }
    updatePedidoTotal();
  }

  function updatePedidoTotal() {
    const totalItems = pedidoItems.reduce((sum, it) => sum + (it.subtotal || 0), 0);
    const entregaVal = document.getElementById("pv-entrega").value === "Cliente"
      ? moneyToNumber(document.getElementById("pv-preco-entrega").value)
      : 0;
    const total = totalItems + entregaVal;
    document.getElementById("pv-total").value = numberToMoney(total);
  }

  function fillClienteFromCadastro(name) {
    const clientes = JSON.parse(localStorage.getItem("printlab_clients") || "[]");
    const found = clientes.find(c => (c.name || "").toLowerCase() === name.toLowerCase());
    if (found) fillClienteFields(found);
    else pedidoAlert.textContent = "Cliente nao encontrado no cadastro.";
  }

  function fillClienteFields(cliente) {
    if (!cliente) return;
    document.getElementById("pv-cliente").value = cliente.name || "";
    document.getElementById("pv-contato").value = cliente.contato || "";
    document.getElementById("pv-telefone").value = cliente.telefone || "";
    pedidoAlert.textContent = "Dados do cliente preenchidos.";
  }

  function openPedidoModal(existing, idx = -1, storageKey = "printlab_pedidos_venda", renderCb = renderPedidosVenda) {
    currentPedidoIndex = idx;
    currentPedidoKey = storageKey || "printlab_pedidos_venda";
    currentPedidoRender = typeof renderCb === "function" ? renderCb : renderPedidosVenda;
    const pedidos = JSON.parse(localStorage.getItem(currentPedidoKey) || "[]");
    const numero = existing ? existing.number : generateNextNumber(currentPedidoKey, 4);
    const emissor = existing ? existing.emissor : (localStorage.getItem("printlab_current_user") || "Usuario atual");
    const titleEl = document.querySelector(".pedido-head h2");
    const mapTitle = {
      "printlab_pedidos_venda": "Emitir Pedido de Venda",
      "printlab_budgets": "Emitir Orçamento",
      "printlab_ordens_producao": "Emitir Ordem de Produção",
    };
    if (titleEl) titleEl.textContent = mapTitle[currentPedidoKey] || "Emitir Pedido";
    // Ajusta campos conforme tipo
    const isBudget = currentPedidoKey === "printlab_budgets";
    const isOrdem = currentPedidoKey === "printlab_ordens_producao";
    const isPedido = currentPedidoKey === "printlab_pedidos_venda";
    const numLabel = document.querySelector('label[for="pv-numero"]') || document.querySelector('#pv-numero')?.parentElement?.querySelector('label');
    if (numLabel) numLabel.textContent = isBudget ? "NÚMERO ORÇAMENTO" : (isOrdem ? "Número de Ordem de Produção" : "Número Pedido de Venda");
    const orcField = document.getElementById("pv-orc-field");
    if (orcField) orcField.style.display = currentPedidoKey === "printlab_pedidos_venda" ? "block" : "none";
    const pedidoRefField = document.getElementById("pv-pedido-ref-field");
    if (pedidoRefField) pedidoRefField.style.display = isOrdem ? "block" : "none";
    const designerField = document.getElementById("pv-designer")?.closest(".field");
    if (designerField) designerField.style.display = isBudget ? "none" : "block";
    const tipoField = document.getElementById("pv-tipo-field");
    if (tipoField) tipoField.style.display = (isOrdem || isPedido) ? "block" : "none";
    const formaField = document.getElementById("pv-forma")?.closest(".field");
    if (formaField) formaField.style.display = isBudget ? "none" : "block";
    const condicaoField = document.getElementById("pv-condicao")?.closest(".field");
    if (condicaoField) condicaoField.style.display = isBudget ? "none" : "block";
    const prazoField = document.getElementById("pv-prazo")?.closest(".field");
    if (prazoField) {
      let prazoSelect = document.getElementById("pv-prazo-select");
      if (!prazoSelect) {
        prazoSelect = document.createElement("select");
        prazoSelect.id = "pv-prazo-select";
        prazoSelect.className = "inline-input";
        prazoSelect.innerHTML = `
          <option value="">Selecione</option>
          <option>1 dia util</option>
          <option>1 a 2 dias uteis</option>
          <option>1 a 3 dias uteis</option>
          <option>3 a 5 dias uteis</option>
          <option>1 a 5 dias uteis</option>
        `;
        prazoField.appendChild(prazoSelect);
      }
      const prazoInput = document.getElementById("pv-prazo");
      if (isBudget) {
        prazoInput.style.display = "none";
        prazoSelect.style.display = "block";
      } else {
        prazoInput.style.display = "block";
        prazoSelect.style.display = "none";
      }
    }
    document.getElementById("pv-numero").value = numero;
    document.getElementById("pv-emissor").value = emissor;
    document.getElementById("pv-data").value = existing ? (existing.data || "") : new Date().toLocaleString("pt-BR");
    document.getElementById("pv-designer").value = existing ? (existing.designer || "") : "";
    const tipoSelect = document.getElementById("pv-tipo");
    if (tipoSelect) {
      const tipoOptions = isOrdem
        ? ["Ordem de Produção", "Amostra", "Doação", "Reposição", "Interno"]
        : ["Pedido de Venda", "Amostra", "Doação", "Reposição", "Interno"];
      tipoSelect.innerHTML = tipoOptions.map(opt => `<option>${opt}</option>`).join("");
      const defaultTipo = isOrdem ? "Ordem de Produção" : "Pedido de Venda";
      let desiredTipo = existing ? (existing.tipo || defaultTipo) : defaultTipo;
      if (!tipoOptions.includes(desiredTipo)) desiredTipo = defaultTipo;
      tipoSelect.value = desiredTipo;
    }
    document.getElementById("pv-cliente").value = existing ? (existing.cliente || "") : "";
    document.getElementById("pv-contato").value = existing ? (existing.contato || "") : "";
    document.getElementById("pv-telefone").value = existing ? (existing.telefone || "") : "";
    document.getElementById("pv-observacao").value = existing ? (existing.observacao || "") : "";
    const orcRef = document.getElementById("pv-orc-ref");
    if (orcRef) orcRef.value = existing ? (existing.orcamentoRef || "") : "";
    const pedRef = document.getElementById("pv-pedido-ref");
    if (pedRef) pedRef.value = existing ? (existing.pedidoRef || "") : "";
    const orcHint = document.getElementById("pv-orc-hint");
    if (orcHint) orcHint.textContent = "";
    const pedidoHint = document.getElementById("pv-pedido-hint");
    if (pedidoHint) pedidoHint.textContent = "";
    document.getElementById("pv-entrega").value = existing ? (existing.entrega || "Cliente") : (isBudget ? "Balcão" : "Cliente");
    document.getElementById("pv-preco-entrega").value = existing ? numberToMoney(existing.precoEntrega || 0) : "";
    document.getElementById("pv-endereco").value = existing ? (existing.endereco || "") : "";
    document.getElementById("pv-forma").value = existing ? (existing.forma || "") : "";
    updateCondicoesByForma();
    document.getElementById("pv-condicao").value = existing ? (existing.condicao || "") : "";
    const prazoInput = document.getElementById("pv-prazo");
    const prazoSelect = document.getElementById("pv-prazo-select");
    if (prazoInput) prazoInput.value = existing ? (existing.prazo || "") : "";
    if (prazoSelect) prazoSelect.value = isBudget ? (existing ? (existing.prazo || "") : "") : "";
    resetPedidoImage();
    if (existing && existing.imagem) {
      setPedidoImage(existing.imagem, "Imagem carregada.");
    }
    pedidoItems = existing && existing.items ? existing.items.map(it => ({
      produto: it.produto || it.material || "",
      material: it.material || "",
      descricao: it.descricao || "",
      unidade: it.unidade || "",
      arquivo: it.arquivo || "",
      quantidade: numberToMoney(it.quantidade || 0),
      unitario: numberToMoney(it.unitario || 0),
      subtotal: it.subtotal || 0,
      imagem: it.imagem || "",
    })) : [{ produto: "", material: "", descricao: "", unidade: "", arquivo: "", quantidade: "1", unitario: "0,00", subtotal: 0, imagem: "" }];
    renderPedidoItems();
    updateEntregaFields();
    pedidoAlert.textContent = "Pagina 1 de 1";
    pedidoModal.style.display = "flex";
  }

  function closePedidoModal() {
    pedidoModal.style.display = "none";
  }

  function normalizeTelefone(value) {
    return (value || "").toString().replace(/\D/g, "").slice(0, 11);
  }

  function formatTelefone(value) {
    const digits = normalizeTelefone(value);
    if (!digits) return "";
    if (digits.length <= 2) return `(${digits}`;
    const ddd = digits.slice(0, 2);
    if (digits.length <= 6) {
      return `(${ddd}) ${digits.slice(2)}`;
    }
    if (digits.length <= 10) {
      const part1 = digits.slice(2, 6);
      const part2 = digits.slice(6, 10);
      return `(${ddd}) ${part1}${part2 ? "-" + part2 : ""}`;
    }
    const part1 = digits.slice(2, 7);
    const part2 = digits.slice(7, 11);
    return `(${ddd}) ${part1}-${part2}`;
  }

  function validateTelefoneInput() {
    const input = document.getElementById("pv-telefone");
    if (!input) return true;
    input.value = formatTelefone(input.value);
    const digits = normalizeTelefone(input.value);
    if (digits && digits.length !== 10 && digits.length !== 11) {
      if (pedidoAlert) {
        pedidoAlert.textContent = "Telefone inválido. Use (xx) xxxx-xxxx ou (xx) xxxxx-xxxx.";
      }
      input.focus();
      return false;
    }
    return true;
  }

  function applyUppercaseInput(input) {
    if (!input) return;
    input.value = input.value.toUpperCase();
    input.addEventListener("input", () => {
      const upper = input.value.toUpperCase();
      if (input.value !== upper) {
        const start = input.selectionStart;
        const end = input.selectionEnd;
        input.value = upper;
        if (start !== null && end !== null) {
          input.setSelectionRange(start, end);
        }
      }
    });
  }

  function applyTelefoneMask(input) {
    if (!input) return;
    input.value = formatTelefone(input.value);
    input.addEventListener("input", () => {
      input.value = formatTelefone(input.value);
    });
    input.addEventListener("blur", () => {
      input.value = formatTelefone(input.value);
    });
  }

  function buildPedidoPayload(includeStatus = false) {
    const cliente = document.getElementById("pv-cliente").value.trim().toUpperCase();
    if (!cliente) return null;
    const numInput = document.getElementById("pv-numero");
    const numeroVal = (numInput?.value || "").trim() || generateNextNumber(currentPedidoKey, 4);
    if (numInput && !numInput.value) numInput.value = numeroVal;
    const total = moneyToNumber(document.getElementById("pv-total").value);
    const dataEmissao = document.getElementById("pv-data").value || new Date().toLocaleString("pt-BR");
    const prazoInput = document.getElementById("pv-prazo");
    const prazoSelect = document.getElementById("pv-prazo-select");
    const prazoValor = currentPedidoKey === "printlab_budgets"
      ? (prazoSelect ? prazoSelect.value : "")
      : (prazoInput ? prazoInput.value : "");
    const isOrdem = currentPedidoKey === "printlab_ordens_producao";
    const isPedido = currentPedidoKey === "printlab_pedidos_venda";
    const tipoValor = (isOrdem || isPedido)
      ? (document.getElementById("pv-tipo")?.value || (isOrdem ? "Ordem de Produção" : "Pedido de Venda"))
      : "";
    const telefoneInput = document.getElementById("pv-telefone");
    const telefone = formatTelefone(telefoneInput ? telefoneInput.value : "");
    if (telefoneInput) telefoneInput.value = telefone;
    return {
      number: numeroVal,
      emissor: document.getElementById("pv-emissor").value,
      data: dataEmissao,
      designer: document.getElementById("pv-designer").value,
      tipo: tipoValor,
      cliente,
      contato: document.getElementById("pv-contato").value.trim().toUpperCase(),
      telefone,
      orcamentoRef: document.getElementById("pv-orc-ref")?.value.trim() || "",
      pedidoRef: document.getElementById("pv-pedido-ref")?.value.trim() || "",
      observacao: document.getElementById("pv-observacao").value.trim(),
      entrega: document.getElementById("pv-entrega").value,
      precoEntrega: moneyToNumber(document.getElementById("pv-preco-entrega").value),
      endereco: document.getElementById("pv-endereco").value.trim().toUpperCase(),
      forma: document.getElementById("pv-forma").value,
      condicao: document.getElementById("pv-condicao").value,
      prazo: prazoValor,
      total,
      status: includeStatus ? (() => {
        const list = JSON.parse(localStorage.getItem(currentPedidoKey) || "[]");
        const existingStatus = (currentPedidoIndex >= 0 && list[currentPedidoIndex]) ? (list[currentPedidoIndex].status || "") : "";
        if (existingStatus) return existingStatus;
        return currentPedidoKey === "printlab_budgets" ? "Aguardando aprovação" : "Salvo";
      })() : "",
      imagem: pedidoImageData,
      items: pedidoItems.map((it, idx) => ({
        item: idx + 1,
        produto: it.produto || "",
        material: it.material,
        descricao: it.descricao,
        unidade: it.unidade || "",
        arquivo: it.arquivo,
        quantidade: moneyToNumber(it.quantidade),
        unitario: moneyToNumber(it.unitario),
        subtotal: it.subtotal || 0,
        imagem: it.imagem || "",
      })),
    };
  }

  function savePedidoVenda() {
    const clienteInput = document.getElementById("pv-cliente");
    if (!clienteInput || !clienteInput.value.trim()) {
      pedidoAlert.textContent = "Informe o cliente.";
      return;
    }
    if (!validateTelefoneInput()) return;
    const payload = buildPedidoPayload(true);
    if (!payload) {
      pedidoAlert.textContent = "Informe o cliente.";
      return;
    }
    const cliente = payload.cliente;
    const key = currentPedidoKey || "printlab_pedidos_venda";
    const pedidos = JSON.parse(localStorage.getItem(key) || "[]");
    if (currentPedidoIndex >= 0 && currentPedidoIndex < pedidos.length) {
      pedidos[currentPedidoIndex] = payload;
    } else {
      pedidos.push(payload);
    }
    localStorage.setItem(key, JSON.stringify(pedidos));

    // Se veio de um orcamento, marca-o como Aprovado
    if (key === "printlab_pedidos_venda" && payload.orcamentoRef) {
      const budgets = JSON.parse(localStorage.getItem("printlab_budgets") || "[]");
      const bIdx = budgets.findIndex(b => String(b.number || "").trim() === String(payload.orcamentoRef || "").trim());
      if (bIdx >= 0) {
        budgets[bIdx].status = "Aprovado";
        localStorage.setItem("printlab_budgets", JSON.stringify(budgets));
      }
    }

    const clientes = JSON.parse(localStorage.getItem("printlab_clients") || "[]");
    const exists = clientes.find(c => (c.name || "").toLowerCase() === cliente.toLowerCase());
    if (!exists) {
      clientes.push({ name: cliente, contato: payload.contato, telefone: payload.telefone });
      localStorage.setItem("printlab_clients", JSON.stringify(clientes));
    }
    pedidoAlert.textContent = "Pedido salvo localmente (mock).";
    if (typeof currentPedidoRender === "function") {
      currentPedidoRender();
    } else {
      renderPedidosVenda();
    }
    closePedidoModal();
  }

  async function exportPedidoPdf() {
    const clienteInput = document.getElementById("pv-cliente");
    if (!clienteInput || !clienteInput.value.trim()) {
      pedidoAlert.textContent = "Informe o cliente antes de exportar.";
      return;
    }
    if (!validateTelefoneInput()) return;
    const payload = buildPedidoPayload();
    if (!payload) {
      pedidoAlert.textContent = "Informe o cliente antes de exportar.";
      return;
    }
    const base = new URL(window.location.href);
    const fallbackPrint = new URL("static/PrintLab-Logo.svg", base).href;
    const fallbackMulti = new URL("static/Multicopias-Logo.svg", base).href;
    const svgToDataUrl = (txt) => "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(txt)));
    const loadLogo = async (path, fallback) => {
      try {
        const res = await fetch(path);
        if (!res.ok) throw new Error("logo fetch");
        const txt = await res.text();
        return svgToDataUrl(txt);
      } catch (e) {
        return fallback;
      }
    };
    const logoMulti = await loadLogo("static/Multicopias-Logo.svg", fallbackMulti);
    const logoPrint = await loadLogo("static/PrintLab-Logo.svg", fallbackPrint);
    const formatPrazo = (val) => {
      if (!val) return "";
      const dt = new Date(val);
      if (isNaN(dt.getTime())) return val;
      const dd = String(dt.getDate()).padStart(2, "0");
      const mm = String(dt.getMonth() + 1).padStart(2, "0");
      const hh = String(dt.getHours()).padStart(2, "0");
      const mi = String(dt.getMinutes()).padStart(2, "0");
      return `${dd}-${mm} - ${hh}:${mi}`;
    };
    const prazoFmt = formatPrazo(payload.prazo);
    const win = window.open("", "_blank");
    const isBudget = currentPedidoKey === "printlab_budgets";
    const itens = payload.items.map(it => {
      const imgRow = it.imagem ? `<div class="row"><span class="label">Imagem</span><span class="value"><img src="${it.imagem}" alt="Item" style="width:300px; height:300px; object-fit:contain; border:1px solid #cdd3e1; border-radius:6px;"></span></div>` : "";
      const arquivoRow = isBudget ? "" : `<div class="row"><span class="label">Arquivo</span><span class="value">${it.arquivo || ""}</span></div>`;
      return `
      <div class="item-block">
        <div class="row"><span class="label">Item</span><span class="value">${it.item}</span></div>
        <div class="row"><span class="label">Produto</span><span class="value">${it.produto || ""}</span></div>
        <div class="row"><span class="label">Material</span><span class="value">${it.material || ""}</span></div>
        <div class="row"><span class="label">Descricao</span><span class="value">${it.descricao || ""}</span></div>
        <div class="row"><span class="label">Unidade</span><span class="value">${it.unidade || ""}</span></div>
        ${arquivoRow}
        <div class="row"><span class="label">Quantidade</span><span class="value">${numberToMoney(it.quantidade || 0)}</span></div>
        <div class="row"><span class="label">Preco Unit</span><span class="value">R$ ${numberToMoney(it.unitario || 0)}</span></div>
        <div class="row"><span class="label">Subtotal</span><span class="value">R$ ${numberToMoney(it.subtotal || 0)}</span></div>
        ${imgRow}
      </div>
    `;
    }).join("");
    const entregaExtra = payload.entrega === "Cliente" ? numberToMoney(payload.precoEntrega || 0) : "0,00";
    const imageBlock = payload.imagem ? `
      <div style="margin:12px 0; text-align:left;">
        <div class="label">Imagem</div>
        <div style="margin-top:6px;">
          <img src="${payload.imagem}" alt="Imagem do pedido" style="width:300px; height:300px; border:1px solid #cdd3e1; border-radius:6px; object-fit:contain;">
        </div>
      </div>
    ` : "";
    const html = `
      <html>
      <head>
        <meta charset="UTF-8">
        <title>Pedido de Venda ${payload.number}</title>
        <style>
          body { font-family: Arial, sans-serif; padding: 28px; color:#0f1831; }
          h1,h2,h3,h4 { margin:0; }
          .topbar { display:flex; justify-content:space-between; align-items:center; margin-bottom:16px; }
          .logo-left { display:flex; align-items:center; }
          .logo-right { display:flex; align-items:center; }
          .logos { display:flex; gap:16px; align-items:center; }
          .doc-title { text-align:center; font-size:20px; font-weight:700; margin-bottom:10px; letter-spacing:0.5px; }
          .meta { display:grid; grid-template-columns: repeat(auto-fit,minmax(220px,1fr)); gap:10px; margin-bottom:12px; }
          .box { border:1px solid #cdd3e1; padding:10px; border-radius:6px; background:#f8f9fb; }
          .label { font-weight:700; font-size:12px; text-transform:uppercase; color:#30406c; }
          .value { font-size:13px; margin-top:4px; }
          table { width:100%; border-collapse: collapse; margin-top:12px; }
          th, td { border:1px solid #cdd3e1; padding:6px; font-size:12px; text-align:left; }
          th { background:#eef2fb; color:#1b2b52; }
          .obs { margin-top:12px; border:1px solid #cdd3e1; padding:10px; border-radius:6px; background:#f8f9fb; }
          .footer { margin-top:12px; display:flex; justify-content:space-between; font-weight:700; }
          .page { font-size:12px; }
          .items-grid { display:grid; gap:10px; margin-top:12px; }
          .item-block { border:1px solid #cdd3e1; padding:8px; border-radius:8px; background:#f8f9fb; display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:6px 12px; break-inside: avoid; page-break-inside: avoid; }
          .item-block .row { display:flex; flex-direction:column; gap:2px; }
          .item-block .label { font-weight:700; font-size:11px; color:#30406c; text-transform:uppercase; }
          .item-block .value { font-size:12px; color:#111827; }
        </style>
      </head>
      <body>
        <div class="topbar">
          <div class="logo-left"><img src="${logoMulti}" alt="" height="50"></div>
          <div class="logo-right"><img src="${logoPrint}" alt="" height="50"></div>
        </div>
        <div class="doc-title">Pedido de Venda ${payload.number}</div>
        <div style="display:flex; justify-content:flex-end; gap:18px; margin-bottom:8px;">
          <div style="text-align:right;">
            <div class="label">Data de Emissao</div>
            <div class="value">${payload.data}</div>
          </div>
          <div style="text-align:right;">
            <div class="label">Emissor</div>
            <div class="value">${payload.emissor}</div>
          </div>
          <div style="text-align:right;">
            <div class="label">Designer</div>
            <div class="value">${payload.designer || ""}</div>
          </div>
        </div>

        <div class="meta">
          <div class="box"><div class="label">Cliente</div><div class="value">${payload.cliente}</div></div>
          <div class="box"><div class="label">Contato</div><div class="value">${payload.contato}</div></div>
          <div class="box"><div class="label">Telefone</div><div class="value">${payload.telefone}</div></div>
          <div class="box"><div class="label">Entrega</div><div class="value">${payload.entrega}</div></div>
          <div class="box"><div class="label">Preco entrega</div><div class="value">R$ ${entregaExtra}</div></div>
          <div class="box"><div class="label">Endereco</div><div class="value">${payload.endereco || ""}</div></div>
          <div class="box"><div class="label">Forma de Pagamento</div><div class="value">${payload.forma || ""}</div></div>
          <div class="box"><div class="label">Condicao de Pagamento</div><div class="value">${payload.condicao || ""}</div></div>
          <div class="box"><div class="label">Prazo de Entrega</div><div class="value">${prazoFmt}</div></div>
        </div>
        ${imageBlock}

        <div class="items-grid">
          ${itens}
        </div>

        <div class="obs"><div class="label">Observacao</div><div class="value">${payload.observacao || ""}</div></div>

        <div class="footer">
          <div class="page">Pagina 1 de 1</div>
          <div>Total: R$ ${numberToMoney(payload.total || 0)}</div>
        </div>
        <script>window.print();<\/script>
      </body>
      </html>
    `;
    win.document.write(html);
    win.document.close();
  }

  function renderChat() {
    const storedUsers = JSON.parse(localStorage.getItem("printlab_users") || "[]");
    const onlineList = new Set(JSON.parse(localStorage.getItem("printlab_online_users") || "[]"));
    const currentUser = localStorage.getItem("printlab_current_user");
    if (currentUser) onlineList.add(currentUser);

    const allNames = storedUsers.map(u => u.user || u.name || "Sem nome");
    const otherUsers = allNames.filter(n => n !== currentUser);
    let selectedUser = localStorage.getItem("printlab_chat_selected") || (otherUsers[0] || "");

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Chat</h2><span class="pill">Usuarios online: ' + (Array.from(onlineList).length) + '</span>';
    container.appendChild(header);

    const layout = document.createElement("div");
    layout.className = "chat-layout";

    const listAll = document.createElement("div");
    listAll.className = "list-card";
    listAll.innerHTML = '<h4>Usuarios</h4>';
    const listBody = document.createElement("div");
    listBody.style.display = "flex";
    listBody.style.flexDirection = "column";
    listBody.style.gap = "6px";
    if (!otherUsers.length) {
      listBody.innerHTML = '<div style="color:#6b7280; font-size:13px;">Cadastre outros usuarios para conversar.</div>';
    } else {
      otherUsers.forEach(name => {
        const row = document.createElement("div");
        row.className = "user-row";
        row.style.cursor = "pointer";
        row.innerHTML = `
          <div class="user-meta">
            <span class="status-dot ${onlineList.has(name) ? 'online' : ''}"></span>
            <span>${name}</span>
          </div>
          <span style="font-size:12px; color:${onlineList.has(name) ? '#1b864c' : '#6b7280'};">
            ${onlineList.has(name) ? 'Online' : 'Offline'}
          </span>
        `;
        if (name === selectedUser) row.style.background = "#eef2fb";
        row.addEventListener("click", () => {
          selectedUser = name;
          localStorage.setItem("printlab_chat_selected", selectedUser);
          renderMessages();
          Array.from(listBody.children).forEach(r => r.style.background = "");
          row.style.background = "#eef2fb";
        });
        listBody.appendChild(row);
      });
    }
    listAll.appendChild(listBody);

    const chatPane = document.createElement("div");
    chatPane.className = "list-card";
    chatPane.style.display = "flex";
    chatPane.style.flexDirection = "column";
    chatPane.style.gap = "10px";
    chatPane.innerHTML = `<h4>Conversa</h4>`;
    const chatWindow = document.createElement("div");
    chatWindow.className = "chat-window";
    const msgList = document.createElement("div");
    msgList.className = "chat-messages";
    const inputArea = document.createElement("div");
    inputArea.className = "chat-input";
    const textarea = document.createElement("textarea");
    textarea.placeholder = "Digite sua mensagem";
    const sendBtn = document.createElement("button");
    sendBtn.className = "primary-btn";
    sendBtn.textContent = "Enviar";
    inputArea.appendChild(textarea);
    inputArea.appendChild(sendBtn);
    chatWindow.appendChild(msgList);
    chatWindow.appendChild(inputArea);
    chatPane.appendChild(chatWindow);

    function renderMessages() {
      msgList.innerHTML = "";
      if (!currentUser) {
        msgList.innerHTML = '<div style="color:#777;">Realize login para usar o chat.</div>';
        textarea.disabled = true;
        sendBtn.disabled = true;
        return;
      }
      if (!selectedUser) {
        msgList.innerHTML = '<div style="color:#777;">Selecione um usuario para conversar.</div>';
        textarea.disabled = true;
        sendBtn.disabled = true;
        return;
      }
      textarea.disabled = false;
      sendBtn.disabled = false;
      const msgs = getChatMessages().filter(m =>
        (m.from === currentUser && m.to === selectedUser) ||
        (m.from === selectedUser && m.to === currentUser)
      ).sort((a,b) => (a.at || 0) - (b.at || 0));
      if (!msgs.length) {
        msgList.innerHTML = '<div style="color:#777;">Nenhuma mensagem ainda.</div>';
      } else {
        msgs.forEach(m => {
          const div = document.createElement("div");
          div.className = "bubble" + (m.from === currentUser ? " me" : "");
          div.innerHTML = `
            <div>${m.text || ""}</div>
            <div class="meta">${m.from} · ${formatTime(m.at)}</div>
          `;
          msgList.appendChild(div);
        });
        msgList.scrollTop = msgList.scrollHeight;
      }
    }

    function sendMessage() {
      const text = textarea.value.trim();
      if (!text || !currentUser || !selectedUser) return;
      const msgs = getChatMessages();
      msgs.push({ from: currentUser, to: selectedUser, text, at: Date.now() });
      saveChatMessages(msgs);
      textarea.value = "";
      renderMessages();
    }

    sendBtn.addEventListener("click", sendMessage);
    textarea.addEventListener("keydown", (ev) => {
      if (ev.key === "Enter" && !ev.shiftKey) {
        ev.preventDefault();
        sendMessage();
      }
    });

    layout.appendChild(listAll);
    layout.appendChild(chatPane);
    container.appendChild(layout);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);
    renderMessages();
  }

  function renderDashboard() {
    const orcamentos = JSON.parse(localStorage.getItem("printlab_budgets") || "[]");
    const pedidos = JSON.parse(localStorage.getItem("printlab_pedidos_venda") || "[]");
    const currentUser = localStorage.getItem("printlab_current_user") || "";
    const restrictedDesigners = ["Karoline", "Gregori", "Adriana", "Beatriz"];
    const isRestricted = restrictedDesigners.includes(currentUser);
    const isMaster = currentUser === MASTER_USER.user;

    // Helpers de filtro
    const parseDateStr = (str) => {
      if (!str) return null;
      const d = new Date(str);
      return isNaN(d.getTime()) ? null : d;
    };

    // Base de dados conforme restricao
    const basePedidos = isRestricted && !isMaster
      ? pedidos.filter(p => (p.designer || "").toLowerCase() === currentUser.toLowerCase())
      : pedidos;
    const baseOrcamentos = orcamentos;

    // Filtros (apenas master)
    const filtros = {
      orcEmissor: "",
      orcDe: "",
      orcAte: "",
      pedEmissor: "",
      pedDesigner: "",
      pedDe: "",
      pedAte: "",
    };

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Dashboard</h2>';
    container.appendChild(header);

    if (!isRestricted) {
      const summary = document.createElement("div");
      summary.className = "summary";
      summary.innerHTML = `
        <div class="list-card">
          <h4>Orçamentos Emitidos</h4>
          <div id="sum-orc-count" style="font-size:24px; font-weight:700; color:var(--primary);">${orcamentos.length}</div>
          <div class="muted">Total R$ <span id="sum-orc-total">${numberToMoney(orcamentos.reduce((sum, o) => sum + moneyToNumber(o.total), 0))}</span></div>
        </div>
        <div class="list-card">
          <h4>Pedidos de Venda</h4>
          <div id="sum-ped-count" style="font-size:24px; font-weight:700; color:var(--primary);">${pedidos.length}</div>
          <div class="muted">Total R$ <span id="sum-ped-total">${numberToMoney(pedidos.reduce((sum, p) => sum + moneyToNumber(p.total), 0))}</span></div>
        </div>
      `;
      container.appendChild(summary);
    }

    const tablesWrap = document.createElement("div");
    tablesWrap.style.display = "grid";
    tablesWrap.style.gridTemplateColumns = isRestricted ? "1fr" : "1fr 1fr";
    tablesWrap.style.gap = "16px";
    tablesWrap.style.marginTop = "12px";

    if (!isRestricted) {
      const orcTable = document.createElement("div");
      orcTable.className = "list-card";
      orcTable.innerHTML = `
        <h4 style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
          <span>Orçamentos emitidos</span>
          ${isMaster ? '<span class="small-muted">Filtros ativos</span>' : ""}
        </h4>
        ${isMaster ? `
        <div style="display:grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap:8px; margin-bottom:10px;">
          <select id="flt-orc-emissor" class="inline-input"></select>
          <input id="flt-orc-de" class="inline-input" type="date" placeholder="De">
          <input id="flt-orc-ate" class="inline-input" type="date" placeholder="Até">
        </div>
        ` : ""}
        <table class="table">
          <thead>
            <tr><th>Numero</th><th>Emissor</th><th>Cliente</th><th>Data</th><th>Total</th></tr>
          </thead>
          <tbody id="tbl-orc-body"></tbody>
        </table>
      `;
      tablesWrap.appendChild(orcTable);
    }

    const pedTable = document.createElement("div");
    pedTable.className = "list-card";
    pedTable.innerHTML = `
      <h4 style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
        <span>Pedidos de venda${isRestricted ? " (meus)" : ""}</span>
        ${isMaster ? '<span class="small-muted">Filtros ativos</span>' : ""}
      </h4>
      ${isMaster ? `
        <div style="display:grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap:8px; margin-bottom:10px;">
          <select id="flt-ped-emissor" class="inline-input"></select>
          <select id="flt-ped-designer" class="inline-input"></select>
          <input id="flt-ped-de" class="inline-input" type="date" placeholder="De">
          <input id="flt-ped-ate" class="inline-input" type="date" placeholder="Até">
        </div>
      ` : ""}
      <table class="table">
        <thead>
          <tr><th>Numero</th><th>Emissor</th><th>Designer</th><th>Cliente</th><th>Data</th><th>Total</th><th>Status</th></tr>
        </thead>
        <tbody id="tbl-ped-body"></tbody>
      </table>
    `;

    tablesWrap.appendChild(pedTable);
    container.appendChild(tablesWrap);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    // Render rows with filters
    const orcBody = document.getElementById("tbl-orc-body");
    const pedBody = document.getElementById("tbl-ped-body");
    const sumOrcCount = document.getElementById("sum-orc-count");
    const sumOrcTotal = document.getElementById("sum-orc-total");
    const sumPedCount = document.getElementById("sum-ped-count");
    const sumPedTotal = document.getElementById("sum-ped-total");
    const selOrcEmissor = document.getElementById("flt-orc-emissor");
    const selPedEmissor = document.getElementById("flt-ped-emissor");
    const selPedDesigner = document.getElementById("flt-ped-designer");

    function populateSelect(selectEl, values) {
      if (!selectEl) return;
      const current = selectEl.value;
      selectEl.innerHTML = "";
      const optAll = document.createElement("option");
      optAll.value = "";
      optAll.textContent = "Todos";
      selectEl.appendChild(optAll);
      values.forEach(v => {
        const opt = document.createElement("option");
        opt.value = v;
        opt.textContent = v;
        selectEl.appendChild(opt);
      });
      if (values.includes(current)) selectEl.value = current;
    }

    if (isMaster) {
      const orcEmissores = Array.from(new Set(baseOrcamentos.map(o => (o.emissor || "").trim()).filter(Boolean))).sort();
      const pedEmissores = Array.from(new Set(basePedidos.map(p => (p.emissor || "").trim()).filter(Boolean))).sort();
      const pedDesigners = Array.from(new Set(basePedidos.map(p => (p.designer || "").trim()).filter(Boolean))).sort();
      populateSelect(selOrcEmissor, orcEmissores);
      populateSelect(selPedEmissor, pedEmissores);
      populateSelect(selPedDesigner, pedDesigners);
    }

    function applyFilters() {
      // read filters
      if (isMaster) {
        filtros.orcEmissor = document.getElementById("flt-orc-emissor")?.value.trim().toLowerCase() || "";
        filtros.orcDe = document.getElementById("flt-orc-de")?.value || "";
        filtros.orcAte = document.getElementById("flt-orc-ate")?.value || "";
        filtros.pedEmissor = document.getElementById("flt-ped-emissor")?.value.trim().toLowerCase() || "";
        filtros.pedDesigner = document.getElementById("flt-ped-designer")?.value.trim().toLowerCase() || "";
        filtros.pedDe = document.getElementById("flt-ped-de")?.value || "";
        filtros.pedAte = document.getElementById("flt-ped-ate")?.value || "";
      }

      let orcList = baseOrcamentos;
      if (isMaster) {
        const de = filtros.orcDe ? new Date(filtros.orcDe) : null;
        const ate = filtros.orcAte ? new Date(filtros.orcAte) : null;
        orcList = orcList.filter(o => {
          const emissor = (o.emissor || "").toLowerCase();
          if (filtros.orcEmissor && !emissor.includes(filtros.orcEmissor)) return false;
          const dt = parseDateStr(o.data || o.date);
          if (de && (!dt || dt < de)) return false;
          if (ate && (!dt || dt > new Date(ate.getTime() + 24*60*60*1000))) return false; // inclui o dia fim
          return true;
        });
      }

      let pedList = basePedidos;
      if (isMaster) {
        const de = filtros.pedDe ? new Date(filtros.pedDe) : null;
        const ate = filtros.pedAte ? new Date(filtros.pedAte) : null;
        pedList = pedList.filter(p => {
          const emissor = (p.emissor || "").toLowerCase();
          const designer = (p.designer || "").toLowerCase();
          if (filtros.pedEmissor && !emissor.includes(filtros.pedEmissor)) return false;
          if (filtros.pedDesigner && !designer.includes(filtros.pedDesigner)) return false;
          const dt = parseDateStr(p.data || "");
          if (de && (!dt || dt < de)) return false;
          if (ate && (!dt || dt > new Date(ate.getTime() + 24*60*60*1000))) return false;
          return true;
        });
      }

      if (orcBody) {
        orcBody.innerHTML = orcList.map(o => `
          <tr>
            <td>${o.number || ""}</td>
            <td>${o.emissor || ""}</td>
            <td>${o.client || o.cliente || ""}</td>
            <td>${o.date || o.data || ""}</td>
            <td>${numberToMoney(moneyToNumber(o.total))}</td>
          </tr>
        `).join('') || '<tr><td colspan="5" style="color:#777;">Nenhum orçamento.</td></tr>';
      }

      if (pedBody) {
        pedBody.innerHTML = pedList.map(p => {
          const color = getStatusColor(p.status);
          const textColor = getStatusTextColor(p.status) || "#000";
          const rowStyle = color ? ` style="background:${color}; color:${textColor};"` : "";
          return `
            <tr${rowStyle}>
              <td>${p.number || ""}</td>
              <td>${p.emissor || ""}</td>
              <td>${p.designer || ""}</td>
              <td>${p.cliente || p.client || ""}</td>
              <td>${p.data || ""}</td>
              <td>${numberToMoney(moneyToNumber(p.total))}</td>
              <td>${p.status || ""}</td>
            </tr>
          `;
        }).join('') || '<tr><td colspan="7" style="color:#777;">Nenhum pedido.</td></tr>';
      }

      if (!isRestricted && isMaster) {
        if (sumOrcCount) sumOrcCount.textContent = orcList.length;
        if (sumOrcTotal) sumOrcTotal.textContent = numberToMoney(orcList.reduce((s,o)=>s+moneyToNumber(o.total),0));
        if (sumPedCount) sumPedCount.textContent = pedList.length;
        if (sumPedTotal) sumPedTotal.textContent = numberToMoney(pedList.reduce((s,p)=>s+moneyToNumber(p.total),0));
      }
    }

    if (isMaster) {
      ["flt-orc-emissor","flt-orc-de","flt-orc-ate","flt-ped-emissor","flt-ped-designer","flt-ped-de","flt-ped-ate"]
        .forEach(id => {
          const el = document.getElementById(id);
          if (!el) return;
          const evt = el.tagName === "SELECT" ? "change" : (el.type === "date" ? "change" : "input");
          el.addEventListener(evt, applyFilters);
        });
    }

    applyFilters();
  }

  function renderAgenda() {
    const KEY = "printlab_agenda_items";
    const palette = {
      interno: "#f0a202",
      visita: "#2e4cb2",
      instalacao: "#1b8f62",
    };
    const agendaModal = document.getElementById("agenda-modal");
    const agendaId = document.getElementById("agenda-id");
    const agendaTitle = document.getElementById("agenda-title");
    const agendaDate = document.getElementById("agenda-date");
    const agendaStart = document.getElementById("agenda-start");
    const agendaEnd = document.getElementById("agenda-end");
    const agendaType = document.getElementById("agenda-type");
    const agendaDesc = document.getElementById("agenda-desc");
    const agendaHint = document.getElementById("agenda-hint");
    const agendaSave = document.getElementById("agenda-save");
    const agendaCancel = document.getElementById("agenda-cancel");
    const agendaDelete = document.getElementById("agenda-delete");
    const agendaVisitaOpen = document.getElementById("agenda-visita-open");
    const agendaInstalacaoOpen = document.getElementById("agenda-instalacao-open");
    const agendaVisitaModal = document.getElementById("agenda-visita-modal");
    const agendaVisitaCliente = document.getElementById("agenda-visita-cliente");
    const agendaVisitaContato = document.getElementById("agenda-visita-contato");
    const agendaVisitaTelefone = document.getElementById("agenda-visita-telefone");
    const agendaVisitaEndereco = document.getElementById("agenda-visita-endereco");
    const agendaVisitaAnotacoes = document.getElementById("agenda-visita-anotacoes");
    const agendaVisitaFiles = document.getElementById("agenda-visita-files");
    const agendaVisitaHint = document.getElementById("agenda-visita-hint");
    const agendaVisitaExport = document.getElementById("agenda-visita-export");
    const agendaVisitaSave = document.getElementById("agenda-visita-save");
    const agendaVisitaCancel = document.getElementById("agenda-visita-cancel");
    let visitaDraft = null;
    const agendaInstalacaoModal = document.getElementById("agenda-instalacao-modal");
    const agendaInstalacaoCliente = document.getElementById("agenda-instalacao-cliente");
    const agendaInstalacaoContato = document.getElementById("agenda-instalacao-contato");
    const agendaInstalacaoTelefone = document.getElementById("agenda-instalacao-telefone");
    const agendaInstalacaoPedido = document.getElementById("agenda-instalacao-pedido");
    const agendaInstalacaoBuscar = document.getElementById("agenda-instalacao-buscar");
    const agendaInstalacaoPedidoHint = document.getElementById("agenda-instalacao-pedido-hint");
    const agendaInstalacaoTotal = document.getElementById("agenda-instalacao-total");
    const agendaInstalacaoForma = document.getElementById("agenda-instalacao-forma");
    const agendaInstalacaoOsnf = document.getElementById("agenda-instalacao-osnf");
    const agendaInstalacaoStatus = document.getElementById("agenda-instalacao-status");
    const agendaInstalacaoHint = document.getElementById("agenda-instalacao-hint");
    const agendaInstalacaoSave = document.getElementById("agenda-instalacao-save");
    const agendaInstalacaoCancel = document.getElementById("agenda-instalacao-cancel");
    let instalacaoDraft = null;

    function formatDateKey(dateObj) {
      const d = new Date(dateObj);
      const y = d.getFullYear();
      const m = String(d.getMonth() + 1).padStart(2, "0");
      const da = String(d.getDate()).padStart(2, "0");
      return `${y}-${m}-${da}`;
    }
    function formatDateLabel(dateStr) {
      const d = new Date(dateStr);
      const day = String(d.getDate()).padStart(2, "0");
      const month = String(d.getMonth() + 1).padStart(2, "0");
      return `${day}.${month}.${d.getFullYear()}`;
    }
    function getMonthName(dateObj) {
      return dateObj.toLocaleDateString("pt-BR", { month: "long" });
    }
    function getEvents() {
      const list = JSON.parse(localStorage.getItem(KEY) || "[]");
      return list
        .map(ev => ({ ...ev, date: ev.date || ev.data }))
        .sort((a, b) => (a.date || "").localeCompare(b.date || "") || (a.start || "").localeCompare(b.start || ""));
    }
    function saveEvents(list) {
      localStorage.setItem(KEY, JSON.stringify(list));
    }
    function startOfWeek(dateStr) {
      const d = new Date(dateStr);
      const day = d.getDay(); // domingo = 0
      const sunday = new Date(d);
      sunday.setDate(d.getDate() - day);
      const saturday = new Date(sunday);
      saturday.setDate(sunday.getDate() + 6);
      return { start: sunday, end: saturday };
    }

    const savedView = localStorage.getItem("printlab_agenda_view");
    let viewDate = savedView ? new Date(savedView) : new Date();

    function closeModal() {
      if (agendaModal) agendaModal.style.display = "none";
    }

    function formatPhone(value) {
      const digits = (value || "").replace(/\D/g, "").slice(0, 11);
      if (!digits) return "";
      if (digits.length <= 10) {
        const d = digits.padEnd(10, "_");
        return `(${d.slice(0, 2)}) ${d.slice(2, 6)}-${d.slice(6, 10)}`.replace(/[_]/g, "").trim();
      }
      const d = digits.padEnd(11, "_");
      return `(${d.slice(0, 2)}) ${d.slice(2, 7)}-${d.slice(7, 11)}`.replace(/[_]/g, "").trim();
    }
    function isValidPhone(value) {
      return /^\(\d{2}\)\s\d{4}-\d{4}$/.test(value) || /^\(\d{2}\)\s\d{5}-\d{4}$/.test(value);
    }
    function fillVisitaForm(data) {
      if (agendaVisitaCliente) agendaVisitaCliente.value = (data && data.cliente) || "";
      if (agendaVisitaContato) agendaVisitaContato.value = (data && data.contato) || "";
      if (agendaVisitaTelefone) agendaVisitaTelefone.value = (data && data.telefone) || "";
      if (agendaVisitaEndereco) agendaVisitaEndereco.value = (data && data.endereco) || "";
      if (agendaVisitaAnotacoes) agendaVisitaAnotacoes.value = (data && data.anotacoes) || "";
      if (agendaVisitaFiles) agendaVisitaFiles.value = "";
      if (agendaVisitaHint) agendaVisitaHint.textContent = "";
    }
    function readFilesAsDataUrls(files) {
      const list = Array.from(files || []);
      return Promise.all(list.map(file => new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = () => resolve({ name: file.name, dataUrl: reader.result || "" });
        reader.onerror = () => resolve({ name: file.name, dataUrl: "" });
        reader.readAsDataURL(file);
      })));
    }
    async function collectVisitaData(includeFiles) {
      const cliente = (agendaVisitaCliente ? agendaVisitaCliente.value : "").trim().toUpperCase();
      const contato = (agendaVisitaContato ? agendaVisitaContato.value : "").trim().toUpperCase();
      const telefone = (agendaVisitaTelefone ? agendaVisitaTelefone.value : "").trim();
      const endereco = (agendaVisitaEndereco ? agendaVisitaEndereco.value : "").trim().toUpperCase();
      const anotacoes = (agendaVisitaAnotacoes ? agendaVisitaAnotacoes.value : "").trim();
      let imagens = (visitaDraft && visitaDraft.imagens) ? visitaDraft.imagens : [];
      if (includeFiles && agendaVisitaFiles && agendaVisitaFiles.files && agendaVisitaFiles.files.length) {
        const loaded = await readFilesAsDataUrls(agendaVisitaFiles.files);
        imagens = loaded.filter(img => img.dataUrl);
      }
      return { cliente, contato, telefone, endereco, anotacoes, imagens };
    }
    function exportVisitaPdf(data) {
      const imgs = (data.imagens || []).map(img => img.dataUrl ? `<img src="${img.dataUrl}" alt="">` : "").join("");
      const imagesBlock = imgs ? `<div class="images">${imgs}</div>` : `<div class="muted">Sem imagens anexadas.</div>`;
      const html = `
        <html>
          <head>
            <title>Relatorio de Visita Tecnica</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 16px; color: #111827; }
              h2 { margin: 0 0 12px 0; }
              .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; margin-bottom: 14px; }
              .field { font-size: 12px; }
              .label { color: #6b7280; font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; }
              .value { margin-top: 4px; font-size: 13px; }
              .notes { white-space: pre-wrap; min-height: 120px; border: 1px solid #d1d5db; padding: 8px; border-radius: 6px; }
              .images { display: grid; grid-template-columns: repeat(auto-fit, 200px); gap: 10px; }
              .images img { width: 200px; height: 200px; object-fit: cover; border: 1px solid #d1d5db; border-radius: 6px; }
              .muted { color: #6b7280; font-size: 12px; }
            </style>
          </head>
          <body>
            <h2>Relatorio de Visita Tecnica</h2>
            <div class="grid">
              <div class="field"><div class="label">Cliente</div><div class="value">${data.cliente || "-"}</div></div>
              <div class="field"><div class="label">Contato</div><div class="value">${data.contato || "-"}</div></div>
              <div class="field"><div class="label">Telefone</div><div class="value">${data.telefone || "-"}</div></div>
              <div class="field"><div class="label">Endereco</div><div class="value">${data.endereco || "-"}</div></div>
            </div>
            <div class="field" style="margin-bottom:12px;">
              <div class="label">Anotacoes</div>
              <div class="notes">${data.anotacoes || ""}</div>
            </div>
            ${imagesBlock}
            <script>window.print();<\/script>
          </body>
        </html>
      `;
      const win = window.open("", "_blank");
      if (win) {
        win.document.write(html);
        win.document.close();
      }
    }
    function openVisitaModal() {
      if (!agendaVisitaModal) return;
      fillVisitaForm(visitaDraft || {});
      agendaVisitaModal.style.display = "flex";
    }
    function closeVisitaModal() {
      if (agendaVisitaModal) agendaVisitaModal.style.display = "none";
    }
    function toggleVisitaButton() {
      if (!agendaVisitaOpen) return;
      const isVisita = agendaType && agendaType.value === "visita";
      agendaVisitaOpen.style.display = isVisita ? "inline-flex" : "none";
      if (!isVisita) closeVisitaModal();
    }
    function fillInstalacaoForm(data) {
      if (agendaInstalacaoCliente) agendaInstalacaoCliente.value = (data && data.cliente) || "";
      if (agendaInstalacaoContato) agendaInstalacaoContato.value = (data && data.contato) || "";
      if (agendaInstalacaoTelefone) agendaInstalacaoTelefone.value = (data && data.telefone) || "";
      if (agendaInstalacaoPedido) agendaInstalacaoPedido.value = (data && data.pedido) || "";
      if (agendaInstalacaoTotal) {
        const totalVal = data && data.total != null ? data.total : "";
        agendaInstalacaoTotal.value = totalVal !== "" ? numberToMoney(moneyToNumber(totalVal)) : "";
      }
      if (agendaInstalacaoForma) agendaInstalacaoForma.value = (data && data.forma) || "";
      if (agendaInstalacaoOsnf) agendaInstalacaoOsnf.value = (data && data.osnf) || "";
      if (agendaInstalacaoStatus) agendaInstalacaoStatus.value = (data && data.status) || "A instalar";
      if (agendaInstalacaoPedidoHint) agendaInstalacaoPedidoHint.textContent = "";
      if (agendaInstalacaoHint) agendaInstalacaoHint.textContent = "";
    }
    function openInstalacaoModal() {
      if (!agendaInstalacaoModal) return;
      fillInstalacaoForm(instalacaoDraft || {});
      agendaInstalacaoModal.style.display = "flex";
    }
    function closeInstalacaoModal() {
      if (agendaInstalacaoModal) agendaInstalacaoModal.style.display = "none";
    }
    function toggleInstalacaoButton() {
      if (!agendaInstalacaoOpen) return;
      const isInstalacao = agendaType && agendaType.value === "instalacao";
      agendaInstalacaoOpen.style.display = isInstalacao ? "inline-flex" : "none";
      if (!isInstalacao) closeInstalacaoModal();
    }

    function openModal(ev = null, dateKey = null) {
      if (!agendaModal) return;
      agendaId.value = ev && ev.id ? ev.id : "";
      agendaTitle.value = (ev && ev.title) || "";
      agendaDate.value = (ev && ev.date) || dateKey || formatDateKey(viewDate);
      agendaStart.value = (ev && ev.start) || "";
      agendaEnd.value = (ev && ev.end) || "";
      agendaType.value = (ev && ev.type) || "interno";
      agendaDesc.value = (ev && ev.desc) || "";
      visitaDraft = ev && ev.visita ? { ...ev.visita } : null;
      instalacaoDraft = ev && ev.instalacao ? { ...ev.instalacao } : null;
      agendaHint.textContent = "Dica: duplo clique em um card para editar rapidamente.";
      agendaDelete.style.display = ev && ev.id ? "inline-flex" : "none";
      agendaModal.style.display = "flex";
      toggleVisitaButton();
      toggleInstalacaoButton();
    }

    if (agendaSave) {
      agendaSave.onclick = () => {
        const title = agendaTitle.value.trim();
        const date = agendaDate.value;
        const start = agendaStart.value;
        const end = agendaEnd.value;
        const type = agendaType.value;
        const desc = agendaDesc.value.trim();
        if (!title || !date) {
          agendaHint.textContent = "Preencha titulo e data.";
          return;
        }
        const events = getEvents();
        if (agendaId.value) {
          const idx = events.findIndex(e => e.id && e.id.toString() === agendaId.value);
          if (idx >= 0) {
            const visita = type === "visita" ? (visitaDraft || null) : null;
            const instalacao = type === "instalacao" ? (instalacaoDraft || null) : null;
            events[idx] = { ...events[idx], title, date, start, end, type, desc, visita, instalacao };
          }
        } else {
          const visita = type === "visita" ? (visitaDraft || null) : null;
          const instalacao = type === "instalacao" ? (instalacaoDraft || null) : null;
          events.push({ id: Date.now(), title, date, start, end, type, desc, visita, instalacao });
        }
        saveEvents(events);
        agendaHint.textContent = "Agendamento salvo.";
        closeModal();
        renderAgenda();
      };
    }
    if (agendaCancel) {
      agendaCancel.onclick = closeModal;
    }
    if (agendaModal) {
      agendaModal.onclick = (ev) => {
        if (ev.target === agendaModal) closeModal();
      };
    }
    if (agendaDelete) {
      agendaDelete.onclick = () => {
        const id = agendaId.value;
        if (!id) {
          closeModal();
          return;
        }
        const filtered = getEvents().filter(e => (e.id ? e.id.toString() : "") !== id);
        saveEvents(filtered);
        agendaHint.textContent = "Agendamento removido.";
        closeModal();
        renderAgenda();
      };
    }
    if (agendaType) {
      agendaType.onchange = () => {
        toggleVisitaButton();
        toggleInstalacaoButton();
      };
    }
    if (agendaVisitaOpen) {
      agendaVisitaOpen.onclick = openVisitaModal;
    }
    if (agendaInstalacaoOpen) {
      agendaInstalacaoOpen.onclick = openInstalacaoModal;
    }
    if (agendaVisitaCancel) {
      agendaVisitaCancel.onclick = closeVisitaModal;
    }
    if (agendaVisitaModal) {
      agendaVisitaModal.onclick = (ev) => {
        if (ev.target === agendaVisitaModal) closeVisitaModal();
      };
    }
    if (agendaVisitaTelefone) {
      agendaVisitaTelefone.oninput = () => {
        agendaVisitaTelefone.value = formatPhone(agendaVisitaTelefone.value);
      };
    }
    if (agendaVisitaFiles) {
      agendaVisitaFiles.onchange = () => {
        if (!agendaVisitaFiles.files) return;
        const maxSize = 10 * 1024 * 1024;
        const tooLarge = Array.from(agendaVisitaFiles.files).filter(f => f.size > maxSize);
        if (tooLarge.length) {
          if (agendaVisitaHint) agendaVisitaHint.textContent = "Uma ou mais imagens excedem 10 MB.";
          agendaVisitaFiles.value = "";
        } else if (agendaVisitaHint) {
          agendaVisitaHint.textContent = "";
        }
      };
    }
    if (agendaVisitaExport) {
      agendaVisitaExport.onclick = async () => {
        if (agendaVisitaHint) agendaVisitaHint.textContent = "";
        const data = await collectVisitaData(true);
        if (data.telefone && !isValidPhone(data.telefone)) {
          if (agendaVisitaHint) agendaVisitaHint.textContent = "Telefone invalido. Use (00) 0000-0000 ou (00) 00000-0000.";
          return;
        }
        if (data.anotacoes.length > 500) {
          if (agendaVisitaHint) agendaVisitaHint.textContent = "Anotacoes excedem 500 caracteres.";
          return;
        }
        exportVisitaPdf(data);
      };
    }
    if (agendaVisitaSave) {
      agendaVisitaSave.onclick = async () => {
        const data = await collectVisitaData(true);
        if (data.telefone && !isValidPhone(data.telefone)) {
          if (agendaVisitaHint) agendaVisitaHint.textContent = "Telefone invalido. Use (00) 0000-0000 ou (00) 00000-0000.";
          return;
        }
        if (data.anotacoes.length > 500) {
          if (agendaVisitaHint) agendaVisitaHint.textContent = "Anotacoes excedem 500 caracteres.";
          return;
        }
        visitaDraft = data;
        closeVisitaModal();
      };
    }
    if (agendaInstalacaoCancel) {
      agendaInstalacaoCancel.onclick = closeInstalacaoModal;
    }
    if (agendaInstalacaoModal) {
      agendaInstalacaoModal.onclick = (ev) => {
        if (ev.target === agendaInstalacaoModal) closeInstalacaoModal();
      };
    }
    if (agendaInstalacaoTelefone) {
      agendaInstalacaoTelefone.oninput = () => {
        agendaInstalacaoTelefone.value = formatPhone(agendaInstalacaoTelefone.value);
      };
    }
    if (agendaInstalacaoBuscar) {
      agendaInstalacaoBuscar.onclick = () => {
        if (!agendaInstalacaoPedido) return;
        const num = agendaInstalacaoPedido.value.trim();
        const pedido = findPedidoByNumber(num);
        if (pedido) {
          const totalVal = moneyToNumber(pedido.total || pedido.totalValue || 0);
          if (agendaInstalacaoTotal) agendaInstalacaoTotal.value = numberToMoney(totalVal);
          if (agendaInstalacaoPedidoHint) agendaInstalacaoPedidoHint.textContent = "Pedido encontrado.";
        } else if (agendaInstalacaoPedidoHint) {
          agendaInstalacaoPedidoHint.textContent = "Pedido nao encontrado.";
          if (agendaInstalacaoTotal) agendaInstalacaoTotal.value = "";
        }
      };
    }
    if (agendaInstalacaoSave) {
      agendaInstalacaoSave.onclick = () => {
        const cliente = (agendaInstalacaoCliente ? agendaInstalacaoCliente.value : "").trim().toUpperCase();
        const contato = (agendaInstalacaoContato ? agendaInstalacaoContato.value : "").trim().toUpperCase();
        const telefone = (agendaInstalacaoTelefone ? agendaInstalacaoTelefone.value : "").trim();
        const pedido = (agendaInstalacaoPedido ? agendaInstalacaoPedido.value : "").trim();
        const total = agendaInstalacaoTotal ? moneyToNumber(agendaInstalacaoTotal.value) : 0;
        const forma = agendaInstalacaoForma ? agendaInstalacaoForma.value : "";
        const osnf = (agendaInstalacaoOsnf ? agendaInstalacaoOsnf.value : "").trim();
        const status = agendaInstalacaoStatus ? agendaInstalacaoStatus.value : "A instalar";
        if (telefone && !isValidPhone(telefone)) {
          if (agendaInstalacaoHint) agendaInstalacaoHint.textContent = "Telefone invalido. Use (00) 0000-0000 ou (00) 00000-0000.";
          return;
        }
        instalacaoDraft = { cliente, contato, telefone, pedido, total, forma, osnf, status };
        closeInstalacaoModal();
      };
    }

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.className = "agenda-header";
    const monthCtrl = document.createElement("div");
    monthCtrl.className = "agenda-month";
    const prevBtn = document.createElement("button");
    prevBtn.textContent = "<";
    prevBtn.className = "prev-btn";
    const nextBtn = document.createElement("button");
    nextBtn.textContent = ">";
    nextBtn.className = "next-btn";
    const title = document.createElement("div");
    title.style.textAlign = "center";
    title.style.width = "100%";
    title.innerHTML = `<div style="font-size:14px; color:#6b7280;">${viewDate.getFullYear()}</div><div style="font-size:20px; text-transform:capitalize;">${getMonthName(viewDate)}</div>`;
    monthCtrl.appendChild(prevBtn);
    monthCtrl.appendChild(title);
    monthCtrl.appendChild(nextBtn);
    const actions = document.createElement("div");
    actions.className = "agenda-legend";
    actions.innerHTML = `
      <button class="primary-btn" id="agenda-new-btn">Agendar</button>
      <span><span class="agenda-dot" style="background:${palette.interno};"></span>Interno</span>
      <span><span class="agenda-dot" style="background:${palette.visita};"></span>Visita Tecnica</span>
      <span><span class="agenda-dot" style="background:${palette.instalacao};"></span>Instalacao</span>
    `;
    header.appendChild(monthCtrl);
    header.appendChild(actions);

    const layout = document.createElement("div");
    layout.className = "agenda-shell";

    const calendarWrap = document.createElement("div");
    calendarWrap.className = "agenda-grid";
    const daysWrap = document.createElement("div");
    daysWrap.className = "agenda-days";
    calendarWrap.appendChild(daysWrap);

    const weekListWrap = document.createElement("div");
    weekListWrap.className = "agenda-weeklist";

    layout.appendChild(calendarWrap);
    layout.appendChild(weekListWrap);

    container.appendChild(header);
    container.appendChild(layout);
    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    function renderWeeks(events) {
      weekListWrap.innerHTML = "";
      const grouped = {};
      events.forEach(ev => {
        const range = startOfWeek(ev.date);
        const key = formatDateKey(range.start);
        if (!grouped[key]) {
          grouped[key] = { start: range.start, end: range.end, items: [] };
        }
        grouped[key].items.push(ev);
      });
      const keys = Object.keys(grouped).sort();
      if (!keys.length) {
        const empty = document.createElement("div");
        empty.className = "agenda-empty";
        empty.textContent = "Sem agendamentos para este mes.";
        weekListWrap.appendChild(empty);
        return;
      }
      keys.forEach((key, idx) => {
        const group = grouped[key];
        const card = document.createElement("div");
        card.className = "agenda-week-card";
        const start = group.start;
        const end = group.end;
        const title = `Semana ${idx + 1} - ${formatDateLabel(start)} a ${formatDateLabel(end)}`;
        card.innerHTML = `<h4>${title}</h4>`;
        const ul = document.createElement("ul");
        group.items.sort((a,b) => (a.date || "").localeCompare(b.date || "") || (a.start || "").localeCompare(b.start || "")).forEach(ev => {
          const li = document.createElement("li");
          const hour = ev.start ? `${ev.start}` : "—";
          li.innerHTML = `<span style="display:inline-flex; align-items:center; gap:6px;"><span class="agenda-dot" style="background:${palette[ev.type] || palette.interno};"></span>${ev.date ? formatDateLabel(ev.date) : ""} ${hour} - ${ev.title || ""}</span>`;
          ul.appendChild(li);
        });
        card.appendChild(ul);
        weekListWrap.appendChild(card);
      });
    }

    function renderGrid() {
      const events = getEvents();
      daysWrap.innerHTML = "";
      const year = viewDate.getFullYear();
      const month = viewDate.getMonth();
      const first = new Date(year, month, 1);
      const startWeekday = first.getDay(); // 0 domingo
      const daysInMonth = new Date(year, month + 1, 0).getDate();
      const prevMonthDays = new Date(year, month, 0).getDate();
      const totalCells = 42;
      const todayKey = formatDateKey(new Date());

      for (let i = 0; i < totalCells; i++) {
        const dayNumber = i - startWeekday + 1;
        let inMonth = dayNumber >= 1 && dayNumber <= daysInMonth;
        let displayNumber = dayNumber;
        let dateKey;
        if (!inMonth && dayNumber < 1) {
          displayNumber = prevMonthDays + dayNumber;
          dateKey = formatDateKey(new Date(year, month - 1, displayNumber));
        } else if (!inMonth) {
          displayNumber = dayNumber - daysInMonth;
          dateKey = formatDateKey(new Date(year, month + 1, displayNumber));
        } else {
          dateKey = formatDateKey(new Date(year, month, displayNumber));
        }
        const dayEl = document.createElement("div");
        dayEl.className = "agenda-day" + (inMonth ? "" : " muted");
        if (dateKey === todayKey && inMonth) {
          dayEl.style.outline = "2px solid #4d63ff";
        }
        const dateLabel = document.createElement("div");
        dateLabel.className = "agenda-date";
        dateLabel.textContent = String(displayNumber).padStart(2, "0");
        const eventWrap = document.createElement("div");
        eventWrap.className = "agenda-events";
        const dayEvents = events.filter(ev => ev.date === dateKey);
        if (dayEvents.length) {
          dayEvents.forEach(ev => {
            const block = document.createElement("div");
            block.className = "agenda-event";
            block.innerHTML = `
              <span class="agenda-dot" style="background:${palette[ev.type] || palette.interno};"></span>
              <div style="display:flex; flex-direction:column; gap:2px;">
                <strong>${ev.title || ""}</strong>
                <span style="font-size:11px; color:#d5dcff;">${ev.start || "--:--"} ${ev.desc ? " • " + ev.desc : ""}</span>
              </div>
            `;
            block.addEventListener("dblclick", (e) => {
              e.stopPropagation();
              openModal(ev, dateKey);
            });
            eventWrap.appendChild(block);
          });
        }
        dayEl.appendChild(dateLabel);
        dayEl.appendChild(eventWrap);
        dayEl.addEventListener("dblclick", () => {
          if (dayEvents.length) {
            openModal(dayEvents[0], dateKey);
          } else {
            openModal(null, dateKey);
          }
        });
        daysWrap.appendChild(dayEl);
      }
      renderWeeks(events.filter(ev => {
        const d = new Date(ev.date);
        return d.getMonth() === viewDate.getMonth() && d.getFullYear() === viewDate.getFullYear();
      }));
    }

    prevBtn.addEventListener("click", () => {
      viewDate.setMonth(viewDate.getMonth() - 1);
      localStorage.setItem("printlab_agenda_view", viewDate.toISOString());
      title.innerHTML = `<div style="font-size:14px; color:#6b7280;">${viewDate.getFullYear()}</div><div style="font-size:20px; text-transform:capitalize;">${getMonthName(viewDate)}</div>`;
      renderGrid();
    });
    nextBtn.addEventListener("click", () => {
      viewDate.setMonth(viewDate.getMonth() + 1);
      localStorage.setItem("printlab_agenda_view", viewDate.toISOString());
      title.innerHTML = `<div style="font-size:14px; color:#6b7280;">${viewDate.getFullYear()}</div><div style="font-size:20px; text-transform:capitalize;">${getMonthName(viewDate)}</div>`;
      renderGrid();
    });
    const newBtn = actions.querySelector("#agenda-new-btn");
    if (newBtn) {
      newBtn.addEventListener("click", () => openModal(null, formatDateKey(viewDate)));
    }

    renderGrid();
  }

  function renderCRM() {
    const KEY = "printlab_crm_leads";
    const STAGES = ["Prospecao", "Contato", "Proposta", "Negociacao", "Fechamento"];
    const stageColors = {
      "Prospecao": "#8b5cf6",
      "Contato": "#2563eb",
      "Proposta": "#0ea5e9",
      "Negociacao": "#f97316",
      "Fechamento": "#16a34a",
    };
    function loadLeads() {
      return JSON.parse(localStorage.getItem(KEY) || "[]");
    }
    function saveLeads(list) {
      localStorage.setItem(KEY, JSON.stringify(list));
    }
    let leads = loadLeads();

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    const title = document.createElement("h2");
    title.textContent = "CRM / Funil de vendas";
    title.style.margin = "0";
    title.style.color = "var(--primary)";
    const headerActions = document.createElement("div");
    headerActions.className = "crm-actions";
    const importInput = document.createElement("input");
    importInput.type = "file";
    importInput.accept = ".csv,text/csv";
    importInput.style.display = "none";
    const importBtn = document.createElement("button");
    importBtn.className = "icon-btn";
    importBtn.textContent = "Importar CSV";
    importBtn.addEventListener("click", () => importInput.click());
    importInput.addEventListener("change", (ev) => {
      const file = ev.target.files && ev.target.files[0];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = (e) => {
        const text = e.target?.result || "";
        const parsed = parseCsvLeads(text.toString());
        if (parsed.length) {
          leads = loadLeads().concat(parsed.map(p => ({ ...p, id: Date.now() + Math.floor(Math.random() * 100000) })));
          saveLeads(leads);
          renderTable();
          crmHint.textContent = `${parsed.length} leads importados.`;
        } else {
          crmHint.textContent = "Nenhum lead encontrado no arquivo.";
        }
      };
      reader.readAsText(file, "UTF-8");
      ev.target.value = "";
    });
    const newBtn = document.createElement("button");
    newBtn.className = "primary-btn";
    newBtn.textContent = "Novo lead";
    headerActions.appendChild(importBtn);
    headerActions.appendChild(importInput);
    headerActions.appendChild(newBtn);
    header.appendChild(title);
    header.appendChild(headerActions);

    const layout = document.createElement("div");
    layout.className = "crm-layout";

    const formCard = document.createElement("div");
    formCard.className = "list-card";
    formCard.innerHTML = `
      <h3 style="margin:0 0 10px 0; color:var(--primary);">Cadastro de lead</h3>
      <input type="hidden" id="crm-id">
      <div class="form-grid">
        <div class="field"><label>Nome/Contato</label><input id="crm-nome" class="inline-input" type="text" placeholder="Nome do lead"></div>
        <div class="field"><label>Empresa</label><input id="crm-empresa" class="inline-input" type="text" placeholder="Empresa"></div>
        <div class="field"><label>Email</label><input id="crm-email" class="inline-input" type="email" placeholder="email@exemplo.com"></div>
        <div class="field"><label>Telefone</label><input id="crm-telefone" class="inline-input" type="text" placeholder="(xx) xxxx-xxxx"></div>
        <div class="field"><label>Valor (R$)</label><input id="crm-valor" class="inline-input" type="text" placeholder="0,00"></div>
        <div class="field"><label>Etapa do funil</label>
          <select id="crm-etapa" class="inline-input">
            ${STAGES.map(s => `<option value="${s}">${s}</option>`).join("")}
          </select>
        </div>
        <div class="field"><label>Probabilidade (%)</label><input id="crm-prob" class="inline-input" type="number" min="0" max="100" placeholder="50"></div>
        <div class="field"><label>Proximo passo</label><input id="crm-next" class="inline-input" type="text" placeholder="Reuniao, apresentacao..."></div>
        <div class="field"><label>Data proximo passo</label><input id="crm-next-date" class="inline-input" type="date"></div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="crm-delete" style="display:none;">Excluir</button>
        <button class="ghost-btn" id="crm-clear">Limpar</button>
        <button class="primary-btn" id="crm-save">Salvar</button>
      </div>
      <div class="muted" id="crm-hint"></div>
    `;

    const boardCard = document.createElement("div");
    boardCard.className = "list-card";
    boardCard.innerHTML = `<h3 style="margin:0 0 10px 0; color:var(--primary);">Relatorio de funil</h3>`;
    const board = document.createElement("div");
    board.className = "crm-board";
    boardCard.appendChild(board);

    const tableCard = document.createElement("div");
    tableCard.className = "list-card";
    tableCard.innerHTML = `
      <h3 style="margin:0 0 8px 0; color:var(--primary);">Potenciais clientes</h3>
      <div style="font-size:12px; color:#6b7280;">Duplo clique para editar um lead.</div>
      <table class="crm-table">
        <thead>
          <tr>
            <th>Nome</th>
            <th>Empresa</th>
            <th>Etapa</th>
            <th>Valor</th>
            <th>Prob (%)</th>
            <th>Proximo passo</th>
          </tr>
        </thead>
        <tbody id="crm-tbody"></tbody>
      </table>
    `;

    layout.appendChild(formCard);
    const rightCol = document.createElement("div");
    rightCol.style.display = "grid";
    rightCol.style.gridTemplateRows = "auto 1fr";
    rightCol.style.gap = "12px";
    rightCol.appendChild(boardCard);
    rightCol.appendChild(tableCard);
    layout.appendChild(rightCol);

    container.appendChild(header);
    container.appendChild(layout);
    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    const crmFields = {
      id: formCard.querySelector("#crm-id"),
      nome: formCard.querySelector("#crm-nome"),
      empresa: formCard.querySelector("#crm-empresa"),
      email: formCard.querySelector("#crm-email"),
      telefone: formCard.querySelector("#crm-telefone"),
      valor: formCard.querySelector("#crm-valor"),
      etapa: formCard.querySelector("#crm-etapa"),
      prob: formCard.querySelector("#crm-prob"),
      next: formCard.querySelector("#crm-next"),
      nextDate: formCard.querySelector("#crm-next-date"),
    };
    const crmHint = formCard.querySelector("#crm-hint");
    const crmSave = formCard.querySelector("#crm-save");
    const crmClear = formCard.querySelector("#crm-clear");
    const crmDelete = formCard.querySelector("#crm-delete");
    const crmBody = tableCard.querySelector("#crm-tbody");

    crmFields.valor.addEventListener("input", () => {
      crmFields.valor.value = crmFields.valor.value.replace(/[^\d.,]/g, "");
    });

    function clearForm() {
      Object.values(crmFields).forEach(f => { if (f && f.tagName !== "SELECT") f.value = ""; });
      crmFields.etapa.value = STAGES[0];
      crmFields.id.value = "";
      crmHint.textContent = "";
      crmDelete.style.display = "none";
    }

    function fillForm(lead) {
      crmFields.id.value = lead.id || "";
      crmFields.nome.value = lead.nome || "";
      crmFields.empresa.value = lead.empresa || "";
      crmFields.email.value = lead.email || "";
      crmFields.telefone.value = lead.telefone || "";
      crmFields.valor.value = lead.valor || "";
      crmFields.etapa.value = lead.etapa || STAGES[0];
      crmFields.prob.value = lead.prob || "";
      crmFields.next.value = lead.next || "";
      crmFields.nextDate.value = lead.nextDate || "";
      crmDelete.style.display = lead.id ? "inline-flex" : "none";
      crmHint.textContent = lead.id ? "Editando lead" : "";
    }

    function getTotals() {
      const totals = {};
      STAGES.forEach(s => totals[s] = { count: 0, value: 0 });
      leads.forEach(l => {
        const stage = STAGES.includes(l.etapa) ? l.etapa : STAGES[0];
        totals[stage].count += 1;
        totals[stage].value += moneyToNumber(l.valor || l.value || 0);
      });
      return totals;
    }

    function renderBoard() {
      board.innerHTML = "";
      const totals = getTotals();
      STAGES.forEach(stage => {
        const card = document.createElement("div");
        card.className = "crm-card";
        const totalValue = totals[stage].value || 0;
        const color = stageColors[stage] || "#24325f";
        card.innerHTML = `
          <h4>${stage}</h4>
          <div style="display:flex; justify-content:space-between; align-items:center;">
            <div style="font-size:26px; font-weight:800; color:${color};">${totals[stage].count}</div>
            <div style="text-align:right; font-size:13px; color:#4b5563;">
              <div>Pipeline</div>
              <strong>R$ ${numberToMoney(totalValue)}</strong>
            </div>
          </div>
        `;
        board.appendChild(card);
      });
    }

    function renderTable() {
      crmBody.innerHTML = "";
      if (!leads.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = '<td colspan="6" style="color:#777;">Nenhum lead cadastrado.</td>';
        crmBody.appendChild(tr);
        renderBoard();
        return;
      }
      leads.sort((a, b) => {
        const orderA = STAGES.indexOf(a.etapa);
        const orderB = STAGES.indexOf(b.etapa);
        return (orderA - orderB) || (b.prob || 0) - (a.prob || 0);
      });
      leads.forEach(l => {
        const tr = document.createElement("tr");
        tr.style.cursor = "pointer";
        tr.innerHTML = `
          <td>${l.nome || ""}</td>
          <td>${l.empresa || ""}</td>
          <td><span style="padding:4px 8px; border-radius:12px; background:${(stageColors[l.etapa] || "#eef2fb")}; color:#fff; font-size:12px;">${l.etapa || ""}</span></td>
          <td>${l.valor ? numberToMoney(moneyToNumber(l.valor)) : "0,00"}</td>
          <td>${l.prob || ""}</td>
          <td>${l.next || ""} ${l.nextDate ? " (" + l.nextDate + ")" : ""}</td>
        `;
        tr.addEventListener("dblclick", () => {
          fillForm(l);
        });
        crmBody.appendChild(tr);
      });
      renderBoard();
    }

    function saveLead() {
      const lead = {
        id: crmFields.id.value || Date.now(),
        nome: crmFields.nome.value.trim(),
        empresa: crmFields.empresa.value.trim(),
        email: crmFields.email.value.trim(),
        telefone: crmFields.telefone.value.trim(),
        valor: crmFields.valor.value.trim(),
        etapa: crmFields.etapa.value,
        prob: parseInt(crmFields.prob.value || "0", 10),
        next: crmFields.next.value.trim(),
        nextDate: crmFields.nextDate.value,
      };
      if (!lead.nome) {
        crmHint.textContent = "Informe o nome ou contato.";
        return;
      }
      const idx = leads.findIndex(l => (l.id || "").toString() === (crmFields.id.value || "").toString());
      if (idx >= 0) {
        leads[idx] = { ...leads[idx], ...lead };
        crmHint.textContent = "Lead atualizado.";
      } else {
        leads.push(lead);
        crmHint.textContent = "Lead criado.";
      }
      saveLeads(leads);
      renderTable();
      clearForm();
    }

    function deleteLead() {
      const id = crmFields.id.value;
      if (!id) return;
      leads = leads.filter(l => (l.id || "").toString() !== id.toString());
      saveLeads(leads);
      renderTable();
      clearForm();
      crmHint.textContent = "Lead removido.";
    }

    function parseCsvLeads(text) {
      const lines = text.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
      if (!lines.length) return [];
      const headers = lines.shift().split(";").map(h => h.trim().toLowerCase()).map(h => h || "col");
      const items = [];
      lines.forEach(line => {
        const parts = line.includes(";") ? line.split(";") : line.split(",");
        const obj = {};
        parts.forEach((val, idx) => obj[headers[idx] || `col${idx}`] = val.trim());
        items.push({
          nome: obj.nome || obj.contato || obj.cliente || "",
          empresa: obj.empresa || "",
          valor: obj.valor || obj.pipeline || "",
          etapa: obj.etapa || obj.stage || STAGES[0],
          email: obj.email || "",
          telefone: obj.telefone || "",
          prob: obj.probabilidade || obj.prob || "",
          next: obj.proximo || obj.next || "",
          nextDate: obj.data || obj["data proximo passo"] || "",
        });
      });
      return items.filter(i => i.nome || i.empresa);
    }

    crmSave.addEventListener("click", saveLead);
    crmClear.addEventListener("click", clearForm);
    crmDelete.addEventListener("click", deleteLead);
    newBtn.addEventListener("click", () => {
      clearForm();
      crmFields.nome.focus();
    });

    renderBoard();
    renderTable();
  }

    function renderFinanceiro(initialTab = "receber") {
    seedContasReceber();
    const tabs = [
      { id: "receber", label: "Contas a receber", icon: "static/icone_contas_receber.svg" },
      { id: "pagar", label: "Contas a pagar", icon: "static/icone_contas_pagar.svg" },
      { id: "fluxo", label: "Fluxo Mensal Financeiro", icon: "static/icone_fluxo_financeiro_mensal.svg" },
      { id: "extrato", label: "Extrato diario", icon: "static/icone_extrato.svg" },
    ];
    let activeTab = initialTab || "receber";
    let editingId = null;
    let editingIndex = -1; // fallback to keep track of the row position during edicao

    // Export modal refs
    const exportModal = document.getElementById("fin-export-modal");
    const expInicio = exportModal ? exportModal.querySelector("#fin-exp-inicio") : null;
    const expFim = exportModal ? exportModal.querySelector("#fin-exp-fim") : null;
    const expStatus = exportModal ? exportModal.querySelector("#fin-exp-status") : null;
    const expHint = exportModal ? exportModal.querySelector("#fin-exp-hint") : null;
    const payExportModal = document.getElementById("pay-export-modal");
    const payMode = payExportModal ? payExportModal.querySelector("#pay-exp-mode") : null;
    const payInicio = payExportModal ? payExportModal.querySelector("#pay-exp-inicio") : null;
    const payFim = payExportModal ? payExportModal.querySelector("#pay-exp-fim") : null;
    const payMonth = payExportModal ? payExportModal.querySelector("#pay-exp-month") : null;
    const payYear = payExportModal ? payExportModal.querySelector("#pay-exp-year") : null;
    const payHint = payExportModal ? payExportModal.querySelector("#pay-exp-hint") : null;
    const payPeriodoWrap = payExportModal ? payExportModal.querySelector("#pay-exp-periodo") : null;
    const payMesWrap = payExportModal ? payExportModal.querySelector("#pay-exp-mes") : null;
    const payAnoWrap = payExportModal ? payExportModal.querySelector("#pay-exp-ano") : null;

    function openExportModal() {
      if (!exportModal) return;
      expHint.textContent = "";
      expInicio.value = "";
      expFim.value = "";
      expStatus.value = "all";
      exportModal.style.display = "flex";
    }

    function closeExportModal() {
      if (!exportModal) return;
      exportModal.style.display = "none";
    }

    function exportRelatorioPDF() {
      if (!exportModal) return;
      const registros = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");
      const start = expInicio.value ? new Date(expInicio.value) : null;
      const end = expFim.value ? new Date(expFim.value) : null;
      const statusFilter = expStatus.value;
      expHint.textContent = "";

      const filtered = registros.filter(r => {
        const rawDate = r.emissao || r.dataEmissao || r.date || r.data || "";
        const d = new Date(rawDate);
        const valid = !isNaN(d.getTime());
        if (start && (!valid || d < start)) return false;
        if (end && (!valid || d > end)) return false;
        if (statusFilter && statusFilter !== "all" && r.status !== statusFilter) return false;
        return true;
      }).sort((a, b) => {
        const da = new Date(a.emissao || 0).getTime() || 0;
        const db = new Date(b.emissao || 0).getTime() || 0;
        return da - db;
      });

      if (!filtered.length) {
        expHint.textContent = "Nenhum lancamento encontrado para o filtro.";
        return;
      }

      const statusOrder = Object.keys(RECEBER_STATUS_META).filter(s => statusFilter === "all" || s === statusFilter);
      const sections = statusOrder.map((status, idx) => {
        const regs = filtered.filter(r => r.status === status);
        if (!regs.length) return "";
        const rows = regs.map(r => {
          const vencimentos = (r.vencimentos && r.vencimentos.length) ? r.vencimentos : [{ data: r.vencimento || r.dataVencimento || "", valor: r.total }];
          const vencStr = vencimentos.map(v => `${formatDateBR(v.data)} - R$ ${numberToMoney(moneyToNumber(v.valor))}`).join(", ");
          const totalVal = typeof r.total === "number" ? r.total : moneyToNumber(r.total);
          return `
            <tr>
              <td>${r.cliente || ""}</td>
              <td>${formatDateBR(r.emissao)}</td>
              <td>${vencStr}</td>
              <td>R$ ${numberToMoney(totalVal)}</td>
              <td>${r.status || ""}</td>
            </tr>
          `;
        }).join("");
        const meta = getReceberStatusMeta(status);
        return `
          <div style="page-break-before:${idx === 0 ? "auto" : "always"};">
            <h3 style="margin:12px 0 8px 0; color:#1f2937;">${status}</h3>
            <table>
              <thead>
                <tr>
                  <th>Cliente</th>
                  <th>Emissao</th>
                  <th>Vencimentos</th>
                  <th>Valor</th>
                  <th>Situacao</th>
                </tr>
              </thead>
              <tbody>
                ${rows}
              </tbody>
            </table>
            <div style="height:6px; background:${meta.color || "#e5e7eb"}; margin:8px 0 4px 0;"></div>
          </div>
        `;
      }).filter(Boolean).join("");

      const html = `
        <html>
          <head>
            <title>Contas a receber</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 16px; color: #111827; font-size: 10px; }
              h2 { margin: 0 0 6px 0; font-size: 14px; }
              h3 { font-size: 12px; }
              .muted { color: #6b7280; font-size: 10px; margin-bottom: 12px; }
              table { width: 100%; border-collapse: collapse; font-size: 10px; }
              th, td { border: 1px solid #d1d5db; padding: 6px; text-align: left; vertical-align: top; }
              thead th { background: #f3f4f6; }
            </style>
          </head>
          <body>
            <h2>Contas a Receber</h2>
            <div class="muted">
              Emissao: ${new Date().toLocaleString("pt-BR")}
              ${start ? " | De " + formatDateBR(start) : ""}
              ${end ? " ate " + formatDateBR(end) : ""}
              ${statusFilter && statusFilter !== "all" ? " | Situacao: " + statusFilter : ""}
            </div>
            ${sections}
            <script>window.print();<\/script>
          </body>
        </html>
      `;
      const win = window.open("", "_blank");
      if (win) {
        win.document.write(html);
        win.document.close();
      }
      closeExportModal();
    }

    function togglePayExportMode() {
      if (!payMode) return;
      const mode = payMode.value;
      if (payPeriodoWrap) payPeriodoWrap.style.display = mode === "periodo" ? "block" : "none";
      if (payMesWrap) payMesWrap.style.display = mode === "mes" ? "block" : "none";
      if (payAnoWrap) payAnoWrap.style.display = mode === "ano" ? "block" : "none";
    }

    function openPayExportModal() {
      if (!payExportModal) return;
      if (payHint) payHint.textContent = "";
      if (payMode) payMode.value = "periodo";
      if (payInicio) payInicio.value = "";
      if (payFim) payFim.value = "";
      if (payMonth) payMonth.value = "";
      if (payYear) payYear.value = new Date().getFullYear();
      togglePayExportMode();
      payExportModal.style.display = "flex";
    }

    function closePayExportModal() {
      if (!payExportModal) return;
      payExportModal.style.display = "none";
    }

    function exportPagarPDF() {
      if (!payExportModal) return;
      if (payHint) payHint.textContent = "";
      const registros = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");
      const mode = payMode ? payMode.value : "periodo";
      const primaryDate = (reg) => {
        const first = (reg.vencimentos && reg.vencimentos[0]) ? reg.vencimentos[0].data : null;
        return first || reg.vencimento || reg.dataVencimento || reg.emissao || "";
      };

      const parseDate = (val) => {
        const d = new Date(val);
        return isNaN(d.getTime()) ? null : d;
      };

      const applyFilter = (reg) => {
        const raw = primaryDate(reg);
        const d = parseDate(raw);
        if (!mode || mode === "periodo") {
          const start = payInicio && payInicio.value ? parseDate(payInicio.value) : null;
          const end = payFim && payFim.value ? parseDate(payFim.value) : null;
          if (!start && !end) return true;
          if (!d) return false;
          if (start && d < start) return false;
          if (end && d > end) return false;
          return true;
        }
        if (mode === "mes") {
          if (!payMonth || !payMonth.value) return false;
          const [y, m] = payMonth.value.split("-").map(Number);
          if (!y || !m) return false;
          if (!d) return false;
          return d.getFullYear() === y && (d.getMonth() + 1) === m;
        }
        if (mode === "ano") {
          const y = payYear ? parseInt(payYear.value, 10) : NaN;
          if (isNaN(y)) return false;
          if (!d) return false;
          return d.getFullYear() === y;
        }
        return true;
      };

      const filtered = registros.filter(applyFilter).sort((a, b) => {
        const da = parseDate(primaryDate(a)) || new Date(0);
        const db = parseDate(primaryDate(b)) || new Date(0);
        return da - db;
      });

      if (!filtered.length) {
        if (payHint) payHint.textContent = "Nenhum lancamento encontrado para o filtro.";
        return;
      }

      const rows = filtered.map(r => {
        const vencimentos = (r.vencimentos && r.vencimentos.length) ? r.vencimentos : [{ data: r.vencimento || "", valor: r.total }];
        const vencStr = vencimentos.map(v => `${formatDateBR(v.data)} - R$ ${numberToMoney(moneyToNumber(v.valor))}`).join("<br>");
        const totalVal = typeof r.total === "number" ? r.total : moneyToNumber(r.total);
        return `
          <tr>
            <td>${r.fornecedor || ""}</td>
            <td>${r.material || ""}</td>
            <td>${r.tipo || ""}</td>
            <td>${r.forma || ""}</td>
            <td>${formatDateBR(r.emissao)}</td>
            <td>${vencStr}</td>
            <td>R$ ${numberToMoney(totalVal)}</td>
          </tr>
        `;
      }).join("");

      const filtroLabel = (() => {
        if (!mode || mode === "periodo") {
          const ini = payInicio && payInicio.value ? formatDateBR(payInicio.value) : "";
          const fim = payFim && payFim.value ? formatDateBR(payFim.value) : "";
          return ini || fim ? `Periodo: ${ini || "inicio"} a ${fim || "fim"}` : "Periodo: completo";
        }
        if (mode === "mes") return `Mes: ${payMonth ? payMonth.value : ""}`;
        if (mode === "ano") return `Ano: ${payYear ? payYear.value : ""}`;
        return "";
      })();

      const html = `
        <html>
          <head>
            <title>Contas a pagar</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 16px; color: #111827; font-size: 10px; }
              h2 { margin: 0 0 6px 0; font-size: 14px; }
              .muted { color: #6b7280; font-size: 10px; margin-bottom: 10px; }
              table { width: 100%; border-collapse: collapse; font-size: 10px; }
              th, td { border: 1px solid #9ca3af; padding: 6px; text-align: left; vertical-align: top; }
              thead th { background: #e5e7eb; }
            </style>
          </head>
          <body>
            <h2>Contas a Pagar</h2>
            <div class="muted">
              Emissao: ${new Date().toLocaleString("pt-BR")} | ${filtroLabel}
            </div>
            <table>
              <thead>
                <tr>
                  <th>Fornecedor</th>
                  <th>Material</th>
                  <th>Tipo</th>
                  <th>Forma</th>
                  <th>Lancamento</th>
                  <th>Vencimento(s)</th>
                  <th>Valor total</th>
                </tr>
              </thead>
              <tbody>${rows}</tbody>
            </table>
            <script>window.print();<\/script>
          </body>
        </html>
      `;
      const win = window.open("", "_blank");
      if (win) {
        win.document.write(html);
        win.document.close();
      }
      closePayExportModal();
    }

    if (exportModal && !exportModal.dataset.bound) {
      exportModal.addEventListener("click", (ev) => {
        if (ev.target === exportModal) closeExportModal();
      });
      exportModal.querySelector("#fin-exp-cancel").addEventListener("click", closeExportModal);
      exportModal.querySelector("#fin-exp-apply").addEventListener("click", exportRelatorioPDF);
      exportModal.dataset.bound = "1";
    }
    if (payExportModal && !payExportModal.dataset.bound) {
      payExportModal.addEventListener("click", (ev) => {
        if (ev.target === payExportModal) closePayExportModal();
      });
      if (payMode) payMode.addEventListener("change", togglePayExportMode);
      payExportModal.querySelector("#pay-exp-cancel").addEventListener("click", closePayExportModal);
      payExportModal.querySelector("#pay-exp-apply").addEventListener("click", exportPagarPDF);
      payExportModal.dataset.bound = "1";
    }

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary)">Financeiro</h2>';
    container.appendChild(header);

    const layout = document.createElement("div");
    layout.className = "finance-layout";
    const subnav = document.createElement("div");
    subnav.className = "finance-subnav";
    const panel = document.createElement("div");
    panel.className = "finance-panel";

    layout.appendChild(subnav);
    layout.appendChild(panel);
    container.appendChild(layout);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    const buttons = [];
    tabs.forEach(tab => {
      const btn = document.createElement("button");
      btn.className = "sub-btn";
      btn.innerHTML = `<img src="${tab.icon}" alt="">${tab.label}`;
      btn.addEventListener("click", () => setTab(tab.id));
      buttons.push({ id: tab.id, el: btn });
      subnav.appendChild(btn);
    });

    function renderPlaceholder(title, desc) {
      panel.innerHTML = `
        <div class="finance-note">
          <strong>${title}</strong>
          <div class="small-muted">${desc}</div>
        </div>
      `;
    }

    function renderContasReceber() {
      seedContasReceber();
      let registros = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");
      // Garante IDs unicos para cada registro, facilitando edicao
      let idsUpdated = false;
      registros = registros.map((r, idx) => {
        if (r.id == null) {
          idsUpdated = true;
          return { ...r, id: Date.now() + idx };
        }
        return r;
      });
      if (idsUpdated) {
        localStorage.setItem(RECEBER_KEY, JSON.stringify(registros));
      }
      const statusTotals = {};
      const statusCounts = {};
      Object.keys(RECEBER_STATUS_META).forEach(key => {
        statusTotals[key] = 0;
        statusCounts[key] = 0;
      });

      registros.forEach(r => {
        const totalVal = typeof r.total === "number" ? r.total : moneyToNumber(r.total);
        const statusKey = RECEBER_STATUS_META[r.status] ? r.status : "A vencer";
        statusTotals[statusKey] = (statusTotals[statusKey] || 0) + totalVal;
        statusCounts[statusKey] = (statusCounts[statusKey] || 0) + 1;
      });

      const summary = document.createElement("div");
      summary.className = "status-summary";
      summary.innerHTML = Object.keys(RECEBER_STATUS_META).map(status => {
        const meta = getReceberStatusMeta(status);
        return `
          <div class="status-card">
            <div>
              <div class="small-muted">${status}</div>
              <div style="font-size:18px; font-weight:700;">${statusCounts[status] || 0} lanc.</div>
            </div>
            <span class="status-pill ${meta.cls}">R$ ${numberToMoney(statusTotals[status] || 0)}</span>
          </div>
        `;
      }).join("");

      const tableWrap = document.createElement("div");
      tableWrap.className = "list-card";
      tableWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 style="margin:0;">Relatorio de lancamentos</h4>
          <div class="actions" style="margin-top:0;">
            <button class="icon-btn" id="fin-export-btn"><img src="static/icone_pdf.svg" alt="" height="16">Exportar PDF</button>
          </div>
        </div>
        <div class="small-muted">De duplo clique em um lancamento para editar.</div>
      `;
      const table = document.createElement("table");
      table.className = "table";
      table.innerHTML = `
        <thead>
          <tr>
            <th>Cliente</th>
            <th>Data de Emissao</th>
            <th>Data de Vencimento</th>
            <th>Valor</th>
            <th>Situacao</th>
          </tr>
        </thead>
        <tbody>
          ${registros.map(r => {
            const vencimentos = (r.vencimentos && r.vencimentos.length) ? r.vencimentos : [{ data: r.vencimento || r.dataVencimento || "", valor: r.total }];
            const vencText = vencimentos.length > 1
              ? `${formatDateBR(vencimentos[0].data)} (+${vencimentos.length - 1})`
              : formatDateBR(vencimentos[0].data);
            const vencTitle = vencimentos.map(v => `${formatDateBR(v.data)} - R$ ${numberToMoney(moneyToNumber(v.valor))}`).join("\n");
            const totalVal = typeof r.total === "number" ? r.total : moneyToNumber(r.total);
            const meta = getReceberStatusMeta(r.status);
            return `
              <tr data-id="${r.id || ""}">
                <td>${r.cliente || ""}</td>
                <td>${formatDateBR(r.emissao)}</td>
                <td title="${vencTitle}">${vencText}</td>
                <td>R$ ${numberToMoney(totalVal)}</td>
                <td><span class="status-pill ${meta.cls}">${r.status || ""}</span></td>
              </tr>
            `;
          }).join('') || '<tr><td colspan="5" style="color:#777;">Nenhum lancamento cadastrado.</td></tr>'}
        </tbody>
      `;
      tableWrap.appendChild(table);

      if (registros.length) {
        Array.from(table.querySelectorAll("tbody tr")).forEach((tr) => {
          const rowId = tr.dataset.id;
          tr.style.cursor = "pointer";
          tr.addEventListener("dblclick", () => {
            const list = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");
            let reg = null;
            if (rowId) {
              reg = list.find(r => (r.id != null ? r.id.toString() : "") === rowId.toString()) || null;
            }
            if (!reg) {
              reg = list[Array.from(tr.parentNode.children).indexOf(tr)] || null;
            }
            if (reg) startEdit(reg);
          });
        });
      }
      const exportBtn = tableWrap.querySelector("#fin-export-btn");
      if (exportBtn) exportBtn.addEventListener("click", openExportModal);

      const formWrap = document.createElement("div");
      formWrap.className = "list-card";
      formWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 id="fin-form-title" style="margin:0;">Registrar recebimento</h4>
          <button class="ghost-btn" id="fin-delete" style="display:none;">Excluir</button>
        </div>
        <div class="form-grid">
          <div class="field">
            <label>Cliente</label>
            <input type="text" id="fin-cliente" placeholder="Nome do cliente">
          </div>
          <div class="field">
            <label>Data de Emissao</label>
            <input type="date" id="fin-emissao">
          </div>
          <div class="field">
            <label>Forma de pagamento</label>
            <select id="fin-forma">
              <option value="">Selecione</option>
              <option value="Dinheiro">Dinheiro</option>
              <option value="Boleto Bancario">Boleto Bancario</option>
              <option value="Cartao de debito">Cartao de debito</option>
              <option value="Cartao de credito">Cartao de credito</option>
              <option value="Deposito">Deposito</option>
              <option value="PIX">PIX</option>
              <option value="Cheque">Cheque</option>
            </select>
          </div>
          <div class="field" id="fin-vencimento-unico-wrap">
            <label>Data de vencimento</label>
            <input type="date" id="fin-vencimento-unico">
          </div>
          <div class="field" id="fin-parcelas-wrap" style="display:none;">
            <label>Quantidade de parcelas</label>
            <input type="number" id="fin-parcelas" min="1" max="36" value="1">
          </div>
          <div class="field">
            <label>Situacao</label>
            <select id="fin-situacao">
              <option value="A vencer">A vencer</option>
              <option value="Liquidados">Liquidados</option>
              <option value="Vencidos">Vencidos</option>
              <option value="Bloqueados">Bloqueados</option>
            </select>
          </div>
          <div class="field">
            <label>Valor total (R$)</label>
            <input type="text" id="fin-total" placeholder="0,00">
          </div>
        </div>
        <div id="fin-parcelas-container" class="parcel-list" style="display:none;"></div>
        <div class="finance-note">
          <strong>Regras</strong><br>
          - Dinheiro, cartao de debito e PIX preenchem vencimento com a data atual (editavel).<br>
          - Boleto, cartao de credito, deposito e cheque habilitam parcelas e exigem soma igual ao total.
        </div>
        <div class="actions" style="justify-content:flex-end;">
          <button class="ghost-btn" id="fin-clear">Limpar</button>
          <button class="primary-btn" id="fin-save">Salvar lancamento</button>
        </div>
        <div class="muted" id="fin-hint"></div>
      `;

      const clienteInput = formWrap.querySelector("#fin-cliente");
      const emissaoInput = formWrap.querySelector("#fin-emissao");
      const formaInput = formWrap.querySelector("#fin-forma");
      const vencimentoWrap = formWrap.querySelector("#fin-vencimento-unico-wrap");
      const vencimentoInput = formWrap.querySelector("#fin-vencimento-unico");
      const parcelasWrap = formWrap.querySelector("#fin-parcelas-wrap");
      const parcelasInput = formWrap.querySelector("#fin-parcelas");
      const parcelasContainer = formWrap.querySelector("#fin-parcelas-container");
      const totalInput = formWrap.querySelector("#fin-total");
      const statusInput = formWrap.querySelector("#fin-situacao");
      const hintEl = formWrap.querySelector("#fin-hint");
      const deleteBtn = formWrap.querySelector("#fin-delete");
      const titleEl = formWrap.querySelector("#fin-form-title");
      const saveBtn = formWrap.querySelector("#fin-save");

      const immediateForms = ["Dinheiro", "Cartao de debito", "PIX"];

      function sanitizeMoneyInput(el) {
        el.value = el.value.replace(/[^\d.,]/g, "");
      }
      function formatMoneyInput(el) {
        el.value = numberToMoney(moneyToNumber(el.value));
      }
      function applyNfeData(data) {
        if (!data || data.error) return;
        const emissaoFmt = formatXmlDateNfe(data.emissaoRaw);
        if (data.fornecedor) fornecedorInput.value = data.fornecedor;
        if (data.items && data.items.length) {
          const firstName = data.items[0].split(" - ")[0];
          materialInput.value = data.items.length > 1 ? `${firstName} + ${data.items.length - 1} itens` : firstName;
        }
        if (!tipoInput.value) tipoInput.value = "Nota Fiscal";
        if (data.total != null && data.total !== "") {
          totalInput.value = numberToMoney(parseXmlNumberNfe(data.total));
        }
        if (emissaoFmt) {
          emissaoInput.value = emissaoFmt;
          if (immediateForms.includes(formaInput.value)) {
            vencimentoInput.value = emissaoFmt;
          }
        }
        if (xmlNumeroInput) xmlNumeroInput.value = data.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = data.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = data.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = data.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = data.ie || "";
        if (xmlNatInput) xmlNatInput.value = data.natOp || "";
        if (xmlItensInput) xmlItensInput.value = (data.items || []).join("\n");
      }

      function applyNfeData(data) {
        if (!data || data.error) return;
        const emissaoFmt = formatXmlDateNfe(data.emissaoRaw);
        if (data.fornecedor) fornecedorInput.value = data.fornecedor;
        if (data.items && data.items.length) {
          const firstName = data.items[0].split(" - ")[0];
          materialInput.value = data.items.length > 1 ? `${firstName} + ${data.items.length - 1} itens` : firstName;
        }
        if (!tipoInput.value) tipoInput.value = "Nota Fiscal";
        if (data.total) totalInput.value = numberToMoney(moneyToNumber(data.total));
        if (emissaoFmt) {
          emissaoInput.value = emissaoFmt;
          if (immediateForms.includes(formaInput.value)) {
            vencimentoInput.value = emissaoFmt;
          }
        }
        if (xmlNumeroInput) xmlNumeroInput.value = data.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = data.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = data.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = data.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = data.ie || "";
        if (xmlNatInput) xmlNatInput.value = data.natOp || "";
        if (xmlItensInput) xmlItensInput.value = (data.items || []).join("\n");
      }

      function getXmlText(root, tag) {
        if (!root) return "";
        const el = root.getElementsByTagName(tag)[0] || root.getElementsByTagNameNS("*", tag)[0];
        return el ? (el.textContent || "").trim() : "";
      }

      function formatXmlDate(value) {
        if (!value) return "";
        if (/^\d{4}-\d{2}-\d{2}/.test(value)) return value.slice(0, 10);
        if (/^\d{2}\/\d{2}\/\d{4}/.test(value)) {
          const [d, m, y] = value.split("/");
          return `${y}-${m}-${d}`;
        }
        return "";
      }

      function parseNfeXml(xmlText) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(xmlText, "application/xml");
        if (doc.getElementsByTagName("parsererror").length) {
          return { error: "XML inválido." };
        }
        const infNFe = doc.getElementsByTagName("infNFe")[0] || doc.getElementsByTagNameNS("*", "infNFe")[0];
        const ide = doc.getElementsByTagName("ide")[0] || doc.getElementsByTagNameNS("*", "ide")[0];
        const emit = doc.getElementsByTagName("emit")[0] || doc.getElementsByTagNameNS("*", "emit")[0];
        const icmsTot = doc.getElementsByTagName("ICMSTot")[0] || doc.getElementsByTagNameNS("*", "ICMSTot")[0] || doc;
        const chave = infNFe ? (infNFe.getAttribute("Id") || "").replace(/^NFe/, "") : "";
        const numero = getXmlText(ide, "nNF");
        const serie = getXmlText(ide, "serie");
        const natOp = getXmlText(ide, "natOp");
        const emissaoRaw = getXmlText(ide, "dhEmi") || getXmlText(ide, "dEmi");
        const fornecedor = getXmlText(emit, "xNome");
        const cnpj = getXmlText(emit, "CNPJ") || getXmlText(emit, "CPF");
        const ie = getXmlText(emit, "IE");
        const total = getXmlText(icmsTot, "vNF");

        const dets = Array.from(doc.getElementsByTagName("det"));
        const detsNs = dets.length ? dets : Array.from(doc.getElementsByTagNameNS("*", "det"));
        const items = detsNs.map(det => {
          const prod = det.getElementsByTagName("prod")[0] || det.getElementsByTagNameNS("*", "prod")[0] || det;
          const nome = getXmlText(prod, "xProd");
          const qtd = getXmlText(prod, "qCom");
          const unidade = getXmlText(prod, "uCom");
          const preco = getXmlText(prod, "vUnCom");
          if (!nome) return "";
          const qtdLabel = qtd ? `${qtd}${unidade ? " " + unidade : ""}` : "";
          const precoLabel = preco ? ` (R$ ${preco})` : "";
          return `${nome}${qtdLabel ? " - " + qtdLabel : ""}${precoLabel}`;
        }).filter(Boolean);

        return {
          chave,
          numero,
          serie,
          natOp,
          emissaoRaw,
          fornecedor,
          cnpj,
          ie,
          total,
          items,
        };
      }

      function applyNfeData(data) {
        if (!data || data.error) return;
        const emissaoFmt = formatXmlDate(data.emissaoRaw);
        if (data.fornecedor) fornecedorInput.value = data.fornecedor;
        if (data.items && data.items.length) {
          const firstName = data.items[0].split(" - ")[0];
          materialInput.value = data.items.length > 1 ? `${firstName} + ${data.items.length - 1} itens` : firstName;
        }
        if (!tipoInput.value) tipoInput.value = "Nota Fiscal";
        if (data.total) totalInput.value = numberToMoney(moneyToNumber(data.total));
        if (emissaoFmt) {
          emissaoInput.value = emissaoFmt;
          if (immediateForms.includes(formaInput.value)) {
            vencimentoInput.value = emissaoFmt;
          }
        }
        if (xmlNumeroInput) xmlNumeroInput.value = data.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = data.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = data.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = data.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = data.ie || "";
        if (xmlNatInput) xmlNatInput.value = data.natOp || "";
        if (xmlItensInput) xmlItensInput.value = (data.items || []).join("\n");
      }

      function getXmlText(root, tag) {
        if (!root) return "";
        const el = root.getElementsByTagName(tag)[0];
        return el ? (el.textContent || "").trim() : "";
      }

      function formatXmlDate(value) {
        if (!value) return "";
        if (/^\d{4}-\d{2}-\d{2}/.test(value)) return value.slice(0, 10);
        if (/^\d{2}\/\d{2}\/\d{4}/.test(value)) {
          const [d, m, y] = value.split("/");
          return `${y}-${m}-${d}`;
        }
        return "";
      }

      function parseNfeXml(xmlText) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(xmlText, "application/xml");
        if (doc.getElementsByTagName("parsererror").length) {
          return { error: "XML inválido." };
        }
        const infNFe = doc.getElementsByTagName("infNFe")[0];
        const ide = doc.getElementsByTagName("ide")[0];
        const emit = doc.getElementsByTagName("emit")[0];
        const icmsTot = doc.getElementsByTagName("ICMSTot")[0] || doc;
        const chave = infNFe ? (infNFe.getAttribute("Id") || "").replace(/^NFe/, "") : "";
        const numero = getXmlText(ide, "nNF");
        const serie = getXmlText(ide, "serie");
        const natOp = getXmlText(ide, "natOp");
        const emissaoRaw = getXmlText(ide, "dhEmi") || getXmlText(ide, "dEmi");
        const fornecedor = getXmlText(emit, "xNome");
        const cnpj = getXmlText(emit, "CNPJ") || getXmlText(emit, "CPF");
        const ie = getXmlText(emit, "IE");
        const total = getXmlText(icmsTot, "vNF");

        const dets = Array.from(doc.getElementsByTagName("det"));
        const items = dets.map(det => {
          const prod = det.getElementsByTagName("prod")[0] || det;
          const nome = getXmlText(prod, "xProd");
          const qtd = getXmlText(prod, "qCom");
          const unidade = getXmlText(prod, "uCom");
          const preco = getXmlText(prod, "vUnCom");
          if (!nome) return "";
          const qtdLabel = qtd ? `${qtd}${unidade ? " " + unidade : ""}` : "";
          const precoLabel = preco ? ` (R$ ${preco})` : "";
          return `${nome}${qtdLabel ? " - " + qtdLabel : ""}${precoLabel}`;
        }).filter(Boolean);

        return {
          chave,
          numero,
          serie,
          natOp,
          emissaoRaw,
          fornecedor,
          cnpj,
          ie,
          total,
          items,
        };
      }

      function applyNfeData(data) {
        if (!data || data.error) return;
        const emissaoFmt = formatXmlDate(data.emissaoRaw);
        if (data.fornecedor) fornecedorInput.value = data.fornecedor;
        if (data.items && data.items.length) {
          const firstName = data.items[0].split(" - ")[0];
          materialInput.value = data.items.length > 1 ? `${firstName} + ${data.items.length - 1} itens` : firstName;
        }
        if (!tipoInput.value) tipoInput.value = "Nota Fiscal";
        if (data.total) totalInput.value = numberToMoney(moneyToNumber(data.total));
        if (emissaoFmt) {
          emissaoInput.value = emissaoFmt;
          if (immediateForms.includes(formaInput.value)) {
            vencimentoInput.value = emissaoFmt;
          }
        }
        if (xmlNumeroInput) xmlNumeroInput.value = data.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = data.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = data.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = data.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = data.ie || "";
        if (xmlNatInput) xmlNatInput.value = data.natOp || "";
        if (xmlItensInput) xmlItensInput.value = (data.items || []).join("\n");
      }

      function buildParcelas(count) {
        parcelasContainer.innerHTML = "";
        if (count <= 0) return;
        const baseDate = emissaoInput.value || todayISO();
        const totalVal = moneyToNumber(totalInput.value);
        const baseValue = count ? totalVal / count : 0;
        for (let i = 0; i < count; i++) {
          const row = document.createElement("div");
          row.className = "parcel-row";
          row.innerHTML = `
            <div class="field">
              <label>Vencimento ${i + 1}</label>
              <input type="date" class="parcel-date" data-idx="${i}" value="${addMonths(baseDate, i)}">
            </div>
            <div class="field">
              <label>Valor ${i + 1}</label>
              <input type="text" class="parcel-value" data-idx="${i}" value="${numberToMoney(baseValue || 0)}">
            </div>
          `;
          const valInput = row.querySelector(".parcel-value");
          valInput.addEventListener("input", () => sanitizeMoneyInput(valInput));
          valInput.addEventListener("blur", () => formatMoneyInput(valInput));
          parcelasContainer.appendChild(row);
        }
        parcelasContainer.style.display = "grid";
      }

      function resetForm() {
        editingId = null;
        editingIndex = -1;
        clienteInput.value = "";
        emissaoInput.value = todayISO();
        formaInput.value = "Dinheiro";
        vencimentoInput.value = todayISO();
        totalInput.value = "";
        statusInput.value = "A vencer";
        parcelasInput.value = 1;
        parcelasContainer.innerHTML = "";
        parcelasContainer.style.display = "none";
        parcelsMode();
        hintEl.textContent = "";
        deleteBtn.style.display = "none";
        titleEl.textContent = "Registrar recebimento";
        saveBtn.textContent = "Salvar lancamento";
      }

      function parcelsMode() {
        const forma = formaInput.value;
        const isImmediate = immediateForms.includes(forma);
        if (isImmediate) {
          parcelasWrap.style.display = "none";
          parcelasContainer.style.display = "none";
          vencimentoWrap.style.display = "block";
          if (!vencimentoInput.value) vencimentoInput.value = todayISO();
        } else {
          vencimentoWrap.style.display = "none";
          parcelasWrap.style.display = "block";
          const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
          parcelasInput.value = qtd;
          buildParcelas(qtd);
        }
      }

      function startEdit(registro, idx) {
        if (!registro) return;
        const list = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");

        // Localiza registro pelo id (ou gera se faltar)
        let storageIdx = -1;
        let currentId = registro.id != null ? registro.id : null;
        if (currentId != null) {
          const rid = currentId.toString();
          storageIdx = list.findIndex(r => (r.id != null ? r.id.toString() : "") === rid);
        }
        if (storageIdx < 0) {
          storageIdx = list.findIndex(r =>
            (r.cliente || "") === (registro.cliente || "") &&
            (r.emissao || "") === (registro.emissao || "") &&
            String(r.total || "") === String(registro.total || "")
          );
        }
        if (storageIdx < 0) {
          currentId = Date.now();
        } else {
          const persisted = list[storageIdx] || {};
          if (persisted.id == null) {
            persisted.id = Date.now();
            list[storageIdx] = persisted;
            localStorage.setItem(RECEBER_KEY, JSON.stringify(list));
          }
          currentId = list[storageIdx].id;
        }
        editingId = currentId;
        editingIndex = storageIdx >= 0 ? storageIdx : (typeof idx === "number" ? idx : -1);
        titleEl.textContent = "Editando lancamento";
        saveBtn.textContent = "Atualizar lancamento";
        deleteBtn.style.display = "inline-flex";
        hintEl.textContent = "Edite os campos e salve ou exclua.";
        clienteInput.value = registro.cliente || "";
        emissaoInput.value = registro.emissao || todayISO();
        formaInput.value = registro.forma || "Dinheiro";
        statusInput.value = registro.status || "A vencer";
        totalInput.value = numberToMoney(typeof registro.total === "number" ? registro.total : moneyToNumber(registro.total));
        const vencimentos = (registro.vencimentos && registro.vencimentos.length) ? registro.vencimentos : [];
        const isImmediate = immediateForms.includes(formaInput.value);
        if (isImmediate || vencimentos.length <= 1) {
          vencimentoWrap.style.display = "block";
          parcelasWrap.style.display = "none";
          parcelasContainer.style.display = "none";
          vencimentoInput.value = vencimentos[0]?.data || registro.vencimento || todayISO();
          parcelasContainer.innerHTML = "";
        } else {
          parcelasWrap.style.display = "block";
          vencimentoWrap.style.display = "none";
          const qtd = Math.max(vencimentos.length, 1);
          parcelasInput.value = qtd;
          buildParcelas(qtd);
          parcelasContainer.style.display = "grid";
          const dateInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-date"));
          const valInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-value"));
          vencimentos.forEach((v, idx) => {
            if (dateInputs[idx]) dateInputs[idx].value = v.data || "";
            if (valInputs[idx]) valInputs[idx].value = numberToMoney(moneyToNumber(v.valor));
          });
        }
      }

      function deleteLancamento() {
        if (editingId === null) {
          hintEl.textContent = "Selecione um lancamento para excluir (duplo clique).";
          return;
        }
        if (!confirm("Deseja excluir este lancamento?")) return;
        const registros = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");
        const filtered = editingId !== null
          ? registros.filter(r => (r.id != null ? r.id.toString() : "") !== editingId.toString())
          : registros;
        localStorage.setItem(RECEBER_KEY, JSON.stringify(filtered));
        editingId = null;
        editingIndex = -1;
        hintEl.textContent = "Lancamento excluido.";
        renderContasReceber();
      }

      function saveLancamento() {
        const cliente = (clienteInput.value || "").trim();
        const emissao = emissaoInput.value || todayISO();
        const forma = formaInput.value;
        const status = statusInput.value || "A vencer";
        const totalVal = moneyToNumber(totalInput.value);
        hintEl.textContent = "";

        if (!cliente) {
          hintEl.textContent = "Informe o cliente.";
          return;
        }
        if (!forma) {
          hintEl.textContent = "Escolha a forma de pagamento.";
          return;
        }
        if (totalVal <= 0) {
          hintEl.textContent = "Informe o valor total.";
          return;
        }

        let vencimentos = [];
        if (immediateForms.includes(forma)) {
          const vencDate = vencimentoInput.value || todayISO();
          vencimentos = [{ data: vencDate, valor: totalVal }];
        } else {
          const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
          const dateInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-date"));
          const valueInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-value"));
          vencimentos = dateInputs.map((inp, idx) => ({
            data: inp.value,
            valor: moneyToNumber(valueInputs[idx] ? valueInputs[idx].value : 0),
          })).filter(v => v.data);
          const soma = vencimentos.reduce((sum, v) => sum + (v.valor || 0), 0);
          if (vencimentos.length !== qtd) {
            hintEl.textContent = "Preencha todos os vencimentos.";
            return;
          }
          if (Math.abs(soma - totalVal) > 0.01) {
            hintEl.textContent = "Soma das parcelas deve ser igual ao total.";
            return;
          }
        }

        let registros = JSON.parse(localStorage.getItem(RECEBER_KEY) || "[]");
        // Certifica IDs
        let updatedIds = false;
        registros = registros.map((r, idx) => {
          if (r.id == null) {
            updatedIds = true;
            return { ...r, id: Date.now() + idx };
          }
          return r;
        });
        if (updatedIds) {
          localStorage.setItem(RECEBER_KEY, JSON.stringify(registros));
        }

        if (editingId !== null) {
          const targetId = editingId.toString();
          let idx = registros.findIndex(r => (r.id != null ? r.id.toString() : "") === targetId);
          // fallback pelo indice da linha caso o id nao seja localizado (dados antigos sem id)
          if (idx < 0 && editingIndex >= 0 && editingIndex < registros.length) {
            idx = editingIndex;
          }
          if (idx >= 0) {
            const newId = registros[idx].id != null ? registros[idx].id : editingId;
            registros[idx] = { ...registros[idx], id: newId, cliente, emissao, forma, vencimentos, total: totalVal, status };
            hintEl.textContent = "Lancamento atualizado.";
          } else {
            hintEl.textContent = "Lancamento nao encontrado, foi criado um novo.";
            registros.unshift({
              id: Date.now(),
              cliente,
              emissao,
              forma,
              vencimentos,
              total: totalVal,
              status,
            });
          }
          editingId = null;
          editingIndex = -1;
        } else {
          registros.unshift({
            id: Date.now(),
            cliente,
            emissao,
            forma,
            vencimentos,
            total: totalVal,
            status,
          });
          hintEl.textContent = "Lancamento salvo.";
        }
        localStorage.setItem(RECEBER_KEY, JSON.stringify(registros));
        renderContasReceber();
      }

      emissaoInput.addEventListener("change", () => {
        if (parcelasContainer.style.display !== "none") {
          buildParcelas(parseInt(parcelasInput.value, 10) || 1);
        } else if (!vencimentoInput.value) {
          vencimentoInput.value = emissaoInput.value;
        }
      });
      formaInput.addEventListener("change", parcelsMode);
      parcelasInput.addEventListener("change", () => {
        const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
        parcelasInput.value = qtd;
        buildParcelas(qtd);
      });
      totalInput.addEventListener("input", () => sanitizeMoneyInput(totalInput));
      totalInput.addEventListener("blur", () => {
        formatMoneyInput(totalInput);
        if (parcelasContainer.style.display !== "none") {
          buildParcelas(parseInt(parcelasInput.value, 10) || 1);
        }
      });
      formWrap.querySelector("#fin-save").addEventListener("click", saveLancamento);
      formWrap.querySelector("#fin-clear").addEventListener("click", resetForm);
      deleteBtn.addEventListener("click", deleteLancamento);

      resetForm();
      panel.innerHTML = "";
      panel.appendChild(summary);
      panel.appendChild(tableWrap);
      panel.appendChild(formWrap);
    }

    function renderContasPagar() {
      seedContasPagar();
      editingId = null;
      editingIndex = -1;
      let registros = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");
      let idsUpdated = false;
      registros = registros.map((r, idx) => {
        if (r.id == null) {
          idsUpdated = true;
          return { ...r, id: Date.now() + idx };
        }
        return r;
      });
      if (idsUpdated) {
        localStorage.setItem(PAGAR_KEY, JSON.stringify(registros));
      }

      const tableWrap = document.createElement("div");
      tableWrap.className = "list-card";
      tableWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 style="margin:0;">Contas a pagar</h4>
          <div class="actions" style="margin-top:0;">
            <button class="icon-btn" id="pay-import-xml"><img src="static/icone_xml.svg" alt="" height="16">Importar XML</button>
            <input type="file" id="pay-xml-input" accept=".xml,application/xml,text/xml" style="display:none;">
            <button class="icon-btn" id="pay-export-btn"><img src="static/icone_pdf.svg" alt="" height="16">Exportar PDF</button>
          </div>
        </div>
        <div class="small-muted">Duplo clique para editar um lancamento.</div>
      `;
      const table = document.createElement("table");
      table.className = "table";
      table.innerHTML = `
        <thead>
          <tr>
            <th>Fornecedor</th>
            <th>Material</th>
            <th>Tipo</th>
            <th>Forma</th>
            <th>Data Lancamento</th>
            <th>Vencimento</th>
            <th>Valor</th>
          </tr>
        </thead>
        <tbody>
          ${registros.map(r => {
            const vencimentos = (r.vencimentos && r.vencimentos.length) ? r.vencimentos : [{ data: r.vencimento || "", valor: r.total }];
            const vencText = vencimentos.length > 1
              ? `${formatDateBR(vencimentos[0].data)} (+${vencimentos.length - 1})`
              : formatDateBR(vencimentos[0].data);
            const vencTitle = vencimentos.map(v => `${formatDateBR(v.data)} - R$ ${numberToMoney(moneyToNumber(v.valor))}`).join("\\n");
            const totalVal = typeof r.total === "number" ? r.total : moneyToNumber(r.total);
            return `
              <tr data-id="${r.id || ""}">
                <td>${r.fornecedor || ""}</td>
                <td>${r.material || ""}</td>
                <td>${r.tipo || ""}</td>
                <td>${r.forma || ""}</td>
                <td>${formatDateBR(r.emissao)}</td>
                <td title="${vencTitle}">${vencText}</td>
                <td>R$ ${numberToMoney(totalVal)}</td>
              </tr>
            `;
          }).join('') || '<tr><td colspan="7" style="color:#777;">Nenhum lancamento cadastrado.</td></tr>'}
        </tbody>
      `;
      tableWrap.appendChild(table);

      if (registros.length) {
        Array.from(table.querySelectorAll("tbody tr")).forEach((tr) => {
          const rowId = tr.dataset.id;
          tr.style.cursor = "pointer";
          tr.addEventListener("dblclick", () => {
            const list = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");
            let reg = null;
            if (rowId) {
              reg = list.find(r => (r.id != null ? r.id.toString() : "") === rowId.toString()) || null;
            }
            if (!reg) {
              reg = list[Array.from(tr.parentNode.children).indexOf(tr)] || null;
            }
            if (reg) startEdit(reg, rowId);
          });
        });
      }
      const exportBtn = tableWrap.querySelector("#pay-export-btn");
      if (exportBtn) exportBtn.addEventListener("click", openPayExportModal);

      const formWrap = document.createElement("div");
      formWrap.className = "list-card";
      formWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 id="pay-form-title" style="margin:0;">Registrar pagamento</h4>
          <button class="ghost-btn" id="pay-delete" style="display:none;">Excluir</button>
        </div>
        <div class="form-grid">
          <div class="field">
            <label>Fornecedor</label>
            <input type="text" id="pay-fornecedor" placeholder="Nome do fornecedor">
          </div>
          <div class="field">
            <label>Material</label>
            <input type="text" id="pay-material" placeholder="Material ou servico">
          </div>
          <div class="field">
            <label>Tipo</label>
            <input type="text" id="pay-tipo" placeholder="Categoria (ex: Servico, Materia-prima)">
          </div>
          <div class="field">
            <label>Forma de pagamento</label>
            <select id="pay-forma">
              <option value="">Selecione</option>
              <option value="Dinheiro">Dinheiro</option>
              <option value="Boleto Bancario">Boleto Bancario</option>
              <option value="Cartao de debito">Cartao de debito</option>
              <option value="Cartao de credito">Cartao de credito</option>
              <option value="Deposito">Deposito</option>
              <option value="PIX">PIX</option>
              <option value="Cheque">Cheque</option>
            </select>
          </div>
          <div class="field">
            <label>Valor total (R$)</label>
            <input type="text" id="pay-total" placeholder="0,00">
          </div>
          <div class="field">
            <label>Data de Lancamento</label>
            <input type="date" id="pay-emissao">
          </div>
          <div class="field" id="pay-vencimento-wrap">
            <label>Data de vencimento</label>
            <input type="date" id="pay-vencimento">
          </div>
          <div class="field" id="pay-parcelas-wrap" style="display:none;">
            <label>Quantidade de parcelas</label>
            <input type="number" id="pay-parcelas" min="1" max="36" value="1">
          </div>
        </div>
        <div class="divider"></div>
        <div class="small-muted" style="margin-bottom:6px;">Dados do XML (NF-e)</div>
        <div class="form-grid">
          <div class="field">
            <label>Nº NF</label>
            <input type="text" id="pay-xml-numero" readonly>
          </div>
          <div class="field">
            <label>Série</label>
            <input type="text" id="pay-xml-serie" readonly>
          </div>
          <div class="field">
            <label>Chave de acesso</label>
            <input type="text" id="pay-xml-chave" readonly>
          </div>
          <div class="field">
            <label>CNPJ/CPF</label>
            <input type="text" id="pay-xml-cnpj" readonly>
          </div>
          <div class="field">
            <label>IE</label>
            <input type="text" id="pay-xml-ie" readonly>
          </div>
          <div class="field">
            <label>Natureza da operação</label>
            <input type="text" id="pay-xml-nat" readonly>
          </div>
          <div class="field" style="grid-column:1/-1;">
            <label>Itens (XML)</label>
            <textarea id="pay-xml-itens" readonly style="width:100%; min-height:72px; padding:10px 12px; border:1px solid var(--border); border-radius:6px; background:#fbfbfd; font-size:14px; resize:vertical;"></textarea>
          </div>
        </div>
        <div id="pay-parcelas-container" class="parcel-list" style="display:none;"></div>
        <div class="finance-note">
          <strong>Regras</strong><br>
          - Dinheiro, cartao de debito e PIX preenchem vencimento com a data do lancamento (editavel).<br>
          - Boleto, cartao de credito, deposito e cheque habilitam parcelas e exigem soma igual ao total.
        </div>
        <div class="actions" style="justify-content:flex-end;">
          <button class="ghost-btn" id="pay-clear">Limpar</button>
          <button class="primary-btn" id="pay-save">Salvar lancamento</button>
        </div>
        <div class="muted" id="pay-hint"></div>
      `;

      const fornecedorInput = formWrap.querySelector("#pay-fornecedor");
      const materialInput = formWrap.querySelector("#pay-material");
      const tipoInput = formWrap.querySelector("#pay-tipo");
      const formaInput = formWrap.querySelector("#pay-forma");
      const totalInput = formWrap.querySelector("#pay-total");
      const emissaoInput = formWrap.querySelector("#pay-emissao");
      const vencimentoWrap = formWrap.querySelector("#pay-vencimento-wrap");
      const vencimentoInput = formWrap.querySelector("#pay-vencimento");
      const parcelasWrap = formWrap.querySelector("#pay-parcelas-wrap");
      const parcelasInput = formWrap.querySelector("#pay-parcelas");
      const parcelasContainer = formWrap.querySelector("#pay-parcelas-container");
      const hintEl = formWrap.querySelector("#pay-hint");
      const deleteBtn = formWrap.querySelector("#pay-delete");
      const titleEl = formWrap.querySelector("#pay-form-title");
      const saveBtn = formWrap.querySelector("#pay-save");
      const xmlNumeroInput = formWrap.querySelector("#pay-xml-numero");
      const xmlSerieInput = formWrap.querySelector("#pay-xml-serie");
      const xmlChaveInput = formWrap.querySelector("#pay-xml-chave");
      const xmlCnpjInput = formWrap.querySelector("#pay-xml-cnpj");
      const xmlIeInput = formWrap.querySelector("#pay-xml-ie");
      const xmlNatInput = formWrap.querySelector("#pay-xml-nat");
      const xmlItensInput = formWrap.querySelector("#pay-xml-itens");
      const xmlBtn = tableWrap.querySelector("#pay-import-xml");
      const xmlInput = tableWrap.querySelector("#pay-xml-input");

      const immediateForms = ["Dinheiro", "Cartao de debito", "PIX"];

      function applyNfeData(data) {
        if (!data || data.error) return;
        const emissaoFmt = formatXmlDateNfe(data.emissaoRaw);
        if (data.fornecedor) fornecedorInput.value = data.fornecedor;
        if (data.items && data.items.length) {
          const firstName = data.items[0].split(" - ")[0];
          materialInput.value = data.items.length > 1 ? `${firstName} + ${data.items.length - 1} itens` : firstName;
        }
        if (!tipoInput.value) tipoInput.value = "Nota Fiscal";
        if (data.total != null && data.total !== "") {
          totalInput.value = numberToMoney(parseXmlNumberNfe(data.total));
        }
        if (emissaoFmt) {
          emissaoInput.value = emissaoFmt;
          if (immediateForms.includes(formaInput.value)) {
            vencimentoInput.value = emissaoFmt;
          }
        }
        if (xmlNumeroInput) xmlNumeroInput.value = data.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = data.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = data.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = data.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = data.ie || "";
        if (xmlNatInput) xmlNatInput.value = data.natOp || "";
        if (xmlItensInput) xmlItensInput.value = (data.items || []).join("\n");
      }

      function sanitizeMoneyInput(el) {
        el.value = el.value.replace(/[^\d.,]/g, "");
      }
      function formatMoneyInput(el) {
        el.value = numberToMoney(moneyToNumber(el.value));
      }

      function buildParcelas(count) {
        parcelasContainer.innerHTML = "";
        if (count <= 0) return;
        const baseDate = emissaoInput.value || todayISO();
        const totalVal = moneyToNumber(totalInput.value);
        const baseValue = count ? totalVal / count : 0;
        for (let i = 0; i < count; i++) {
          const row = document.createElement("div");
          row.className = "parcel-row";
          row.innerHTML = `
            <div class="field">
              <label>Vencimento ${i + 1}</label>
              <input type="date" class="parcel-date" data-idx="${i}" value="${addMonths(baseDate, i)}">
            </div>
            <div class="field">
              <label>Valor ${i + 1}</label>
              <input type="text" class="parcel-value" data-idx="${i}" value="${numberToMoney(baseValue || 0)}">
            </div>
          `;
          const valInput = row.querySelector(".parcel-value");
          valInput.addEventListener("input", () => sanitizeMoneyInput(valInput));
          valInput.addEventListener("blur", () => formatMoneyInput(valInput));
          parcelasContainer.appendChild(row);
        }
        parcelasContainer.style.display = "grid";
      }

      function resetForm() {
        editingId = null;
        editingIndex = -1;
        fornecedorInput.value = "";
        materialInput.value = "";
        tipoInput.value = "";
        formaInput.value = "Dinheiro";
        totalInput.value = "";
        emissaoInput.value = todayISO();
        vencimentoInput.value = todayISO();
        parcelasInput.value = 1;
        parcelasContainer.innerHTML = "";
        parcelasContainer.style.display = "none";
        parcelsMode();
        hintEl.textContent = "";
        deleteBtn.style.display = "none";
        titleEl.textContent = "Registrar pagamento";
        saveBtn.textContent = "Salvar lancamento";
        if (xmlNumeroInput) xmlNumeroInput.value = "";
        if (xmlSerieInput) xmlSerieInput.value = "";
        if (xmlChaveInput) xmlChaveInput.value = "";
        if (xmlCnpjInput) xmlCnpjInput.value = "";
        if (xmlIeInput) xmlIeInput.value = "";
        if (xmlNatInput) xmlNatInput.value = "";
        if (xmlItensInput) xmlItensInput.value = "";
        if (xmlInput) xmlInput.value = "";
      }

      if (xmlBtn && xmlInput) {
        xmlBtn.addEventListener("click", () => {
          xmlInput.click();
        });
        xmlInput.addEventListener("change", () => {
          const file = xmlInput.files && xmlInput.files[0];
          if (!file) return;
          const reader = new FileReader();
          reader.onload = () => {
            const data = parseNfeXml(reader.result || "");
            if (data.error) {
              hintEl.textContent = data.error;
              return;
            }
            applyNfeData(data);
            hintEl.textContent = "XML importado. Revise e salve o lançamento.";
            parcelsMode();
          };
          reader.onerror = () => {
            hintEl.textContent = "Não foi possível ler o arquivo XML.";
          };
          reader.readAsText(file, "UTF-8");
        });
      }

      function parcelsMode() {
        const forma = formaInput.value;
        const isImmediate = immediateForms.includes(forma);
        if (isImmediate) {
          parcelasWrap.style.display = "none";
          parcelasContainer.style.display = "none";
          vencimentoWrap.style.display = "block";
          if (!vencimentoInput.value) vencimentoInput.value = emissaoInput.value || todayISO();
        } else {
          vencimentoWrap.style.display = "none";
          parcelasWrap.style.display = "block";
          const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
          parcelasInput.value = qtd;
          buildParcelas(qtd);
        }
      }

      function startEdit(registro) {
        if (!registro) return;
        const list = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");

        let storageIdx = -1;
        let currentId = registro.id != null ? registro.id : null;
        if (currentId != null) {
          const rid = currentId.toString();
          storageIdx = list.findIndex(r => (r.id != null ? r.id.toString() : "") === rid);
        }
        if (storageIdx < 0) {
          storageIdx = list.findIndex(r =>
            (r.fornecedor || "") === (registro.fornecedor || "") &&
            (r.material || "") === (registro.material || "") &&
            String(r.total || "") === String(registro.total || "")
          );
        }
        if (storageIdx < 0) {
          currentId = Date.now();
        } else {
          const persisted = list[storageIdx] || {};
          if (persisted.id == null) {
            persisted.id = Date.now();
            list[storageIdx] = persisted;
            localStorage.setItem(PAGAR_KEY, JSON.stringify(list));
          }
          currentId = list[storageIdx].id;
        }
        editingId = currentId;
        editingIndex = storageIdx;
        titleEl.textContent = "Editando lancamento";
        saveBtn.textContent = "Atualizar lancamento";
        deleteBtn.style.display = "inline-flex";
        hintEl.textContent = "Edite os campos e salve ou exclua.";

        fornecedorInput.value = registro.fornecedor || "";
        materialInput.value = registro.material || "";
        tipoInput.value = registro.tipo || "";
        formaInput.value = registro.forma || "Dinheiro";
        totalInput.value = numberToMoney(typeof registro.total === "number" ? registro.total : moneyToNumber(registro.total));
        emissaoInput.value = registro.emissao || todayISO();
        const xml = registro.xml || {};
        if (xmlNumeroInput) xmlNumeroInput.value = xml.numero || "";
        if (xmlSerieInput) xmlSerieInput.value = xml.serie || "";
        if (xmlChaveInput) xmlChaveInput.value = xml.chave || "";
        if (xmlCnpjInput) xmlCnpjInput.value = xml.cnpj || "";
        if (xmlIeInput) xmlIeInput.value = xml.ie || "";
        if (xmlNatInput) xmlNatInput.value = xml.natOp || "";
        if (xmlItensInput) xmlItensInput.value = xml.itens || "";
        const vencimentos = (registro.vencimentos && registro.vencimentos.length) ? registro.vencimentos : [];
        const isImmediate = immediateForms.includes(formaInput.value);
        if (isImmediate || vencimentos.length <= 1) {
          vencimentoWrap.style.display = "block";
          parcelasWrap.style.display = "none";
          parcelasContainer.style.display = "none";
          vencimentoInput.value = vencimentos[0]?.data || registro.vencimento || emissaoInput.value || todayISO();
          parcelasContainer.innerHTML = "";
        } else {
          parcelasWrap.style.display = "block";
          vencimentoWrap.style.display = "none";
          const qtd = Math.max(vencimentos.length, 1);
          parcelasInput.value = qtd;
          buildParcelas(qtd);
          parcelasContainer.style.display = "grid";
          const dateInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-date"));
          const valInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-value"));
          vencimentos.forEach((v, idx) => {
            if (dateInputs[idx]) dateInputs[idx].value = v.data || "";
            if (valInputs[idx]) valInputs[idx].value = numberToMoney(moneyToNumber(v.valor));
          });
        }
      }

      function deleteLancamento() {
        if (editingId === null) {
          hintEl.textContent = "Selecione um lancamento para excluir (duplo clique).";
          return;
        }
        if (!confirm("Deseja excluir este lancamento?")) return;
        const registrosList = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");
        const filtered = editingId !== null
          ? registrosList.filter(r => (r.id != null ? r.id.toString() : "") !== editingId.toString())
          : registrosList;
        localStorage.setItem(PAGAR_KEY, JSON.stringify(filtered));
        editingId = null;
        editingIndex = -1;
        hintEl.textContent = "Lancamento excluido.";
        renderContasPagar();
      }

      function saveLancamento() {
        const fornecedor = (fornecedorInput.value || "").trim();
        const material = (materialInput.value || "").trim();
        const tipo = (tipoInput.value || "").trim();
        const forma = formaInput.value;
        const totalVal = moneyToNumber(totalInput.value);
        const emissao = emissaoInput.value || todayISO();
        const xmlData = {
          numero: xmlNumeroInput ? xmlNumeroInput.value : "",
          serie: xmlSerieInput ? xmlSerieInput.value : "",
          chave: xmlChaveInput ? xmlChaveInput.value : "",
          cnpj: xmlCnpjInput ? xmlCnpjInput.value : "",
          ie: xmlIeInput ? xmlIeInput.value : "",
          natOp: xmlNatInput ? xmlNatInput.value : "",
          itens: xmlItensInput ? xmlItensInput.value : "",
        };
        hintEl.textContent = "";

        if (!fornecedor) {
          hintEl.textContent = "Informe o fornecedor.";
          return;
        }
        if (!forma) {
          hintEl.textContent = "Escolha a forma de pagamento.";
          return;
        }
        if (totalVal <= 0) {
          hintEl.textContent = "Informe o valor total.";
          return;
        }

        let vencimentos = [];
        if (immediateForms.includes(forma)) {
          const vencDate = vencimentoInput.value || emissao;
          vencimentos = [{ data: vencDate, valor: totalVal }];
        } else {
          const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
          const dateInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-date"));
          const valueInputs = Array.from(parcelasContainer.querySelectorAll(".parcel-value"));
          vencimentos = dateInputs.map((inp, idx) => ({
            data: inp.value,
            valor: moneyToNumber(valueInputs[idx] ? valueInputs[idx].value : 0),
          })).filter(v => v.data);
          const soma = vencimentos.reduce((sum, v) => sum + (v.valor || 0), 0);
          if (vencimentos.length !== qtd) {
            hintEl.textContent = "Preencha todos os vencimentos.";
            return;
          }
          if (Math.abs(soma - totalVal) > 0.01) {
            hintEl.textContent = "Soma das parcelas deve ser igual ao total.";
            return;
          }
        }

        let registrosList = JSON.parse(localStorage.getItem(PAGAR_KEY) || "[]");
        let updatedIds = false;
        registrosList = registrosList.map((r, idx) => {
          if (r.id == null) {
            updatedIds = true;
            return { ...r, id: Date.now() + idx };
          }
          return r;
        });
        if (updatedIds) {
          localStorage.setItem(PAGAR_KEY, JSON.stringify(registrosList));
        }

        if (editingId !== null) {
          const targetId = editingId.toString();
          let idx = registrosList.findIndex(r => (r.id != null ? r.id.toString() : "") === targetId);
          if (idx < 0 && editingIndex >= 0 && editingIndex < registrosList.length) {
            idx = editingIndex;
          }
          if (idx >= 0) {
            const newId = registrosList[idx].id != null ? registrosList[idx].id : editingId;
            registrosList[idx] = { ...registrosList[idx], id: newId, fornecedor, material, tipo, forma, emissao, vencimentos, total: totalVal, xml: xmlData };
            hintEl.textContent = "Lancamento atualizado.";
          } else {
            hintEl.textContent = "Lancamento nao encontrado, foi criado um novo.";
            registrosList.unshift({
              id: Date.now(),
              fornecedor,
              material,
              tipo,
              forma,
              emissao,
              vencimentos,
              total: totalVal,
              xml: xmlData,
            });
          }
          editingId = null;
          editingIndex = -1;
        } else {
          registrosList.unshift({
            id: Date.now(),
            fornecedor,
            material,
            tipo,
            forma,
            emissao,
            vencimentos,
            total: totalVal,
            xml: xmlData,
          });
          hintEl.textContent = "Lancamento salvo.";
        }
        localStorage.setItem(PAGAR_KEY, JSON.stringify(registrosList));
        renderContasPagar();
      }

      emissaoInput.addEventListener("change", () => {
        if (parcelasContainer.style.display !== "none") {
          buildParcelas(parseInt(parcelasInput.value, 10) || 1);
        } else if (!vencimentoInput.value) {
          vencimentoInput.value = emissaoInput.value;
        }
      });
      formaInput.addEventListener("change", parcelsMode);
      parcelasInput.addEventListener("change", () => {
        const qtd = Math.max(1, parseInt(parcelasInput.value, 10) || 1);
        parcelasInput.value = qtd;
        buildParcelas(qtd);
      });
      totalInput.addEventListener("input", () => sanitizeMoneyInput(totalInput));
      totalInput.addEventListener("blur", () => {
        formatMoneyInput(totalInput);
        if (parcelasContainer.style.display !== "none") {
          buildParcelas(parseInt(parcelasInput.value, 10) || 1);
        }
      });
      formWrap.querySelector("#pay-save").addEventListener("click", saveLancamento);
      formWrap.querySelector("#pay-clear").addEventListener("click", resetForm);
      deleteBtn.addEventListener("click", deleteLancamento);

      resetForm();
      panel.innerHTML = "";
      panel.appendChild(tableWrap);
      panel.appendChild(formWrap);
    }

    function renderFluxoMensal() {
      let fluxos = JSON.parse(localStorage.getItem(FLUXO_KEY) || "[]");
      let editingFluxoId = null;
      let editingFluxoIndex = -1;

      const entradaTotal = (r) => [
        r.entradaCredito, r.entradaDebito, r.entradaPix,
        r.entradaBoleto, r.entradaDinheiro, r.entradaOutros
      ].map(v => Number(v) || 0).reduce((a, b) => a + b, 0);
      const saidaTotal = (r) => [
        r.saidaBoletos, r.saidaDinheiro, r.saidaOutros
      ].map(v => Number(v) || 0).reduce((a, b) => a + b, 0);

      const totalEntradas = fluxos.reduce((s, r) => s + entradaTotal(r), 0);
      const totalSaidas = fluxos.reduce((s, r) => s + saidaTotal(r), 0);
      const saldoGeral = totalEntradas - totalSaidas;

      const summary = document.createElement("div");
      summary.className = "status-summary";
      summary.innerHTML = `
        <div class="status-card">
          <div>
            <div class="small-muted">Entradas</div>
            <div style="font-size:18px; font-weight:700;">R$ ${numberToMoney(totalEntradas)}</div>
          </div>
          <span class="status-pill liq">+ Entradas</span>
        </div>
        <div class="status-card">
          <div>
            <div class="small-muted">Saidas</div>
            <div style="font-size:18px; font-weight:700;">R$ ${numberToMoney(totalSaidas)}</div>
          </div>
          <span class="status-pill vencido">- Saidas</span>
        </div>
        <div class="status-card">
          <div>
            <div class="small-muted">Saldo</div>
            <div style="font-size:18px; font-weight:700;">R$ ${numberToMoney(saldoGeral)}</div>
          </div>
          <span class="status-pill ${saldoGeral >= 0 ? "liq" : "bloq"}">${saldoGeral >= 0 ? "Positivo" : "Negativo"}</span>
        </div>
      `;

      const tableWrap = document.createElement("div");
      tableWrap.className = "list-card";
      tableWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 style="margin:0;">Fluxo Mensal Financeiro</h4>
          <div class="actions" style="margin-top:0;">
            <input type="date" id="fluxo-report-inicio" style="padding:8px; border:1px solid var(--border); border-radius:6px;">
            <input type="date" id="fluxo-report-fim" style="padding:8px; border:1px solid var(--border); border-radius:6px;">
            <button class="icon-btn" id="fluxo-report-btn"><img src="static/icone_fluxo_financeiro_mensal.svg" alt="" height="16">Emitir relatorio</button>
            <button class="ghost-btn" id="fluxo-clear-selection" style="display:none;">Cancelar edicao</button>
          </div>
        </div>
        <div class="small-muted">Duplo clique em uma linha para editar.</div>
      `;

      const table = document.createElement("table");
      table.className = "table";
      table.innerHTML = `
        <thead>
          <tr>
            <th>Data</th>
            <th>Entrada Credito</th>
            <th>Entrada Debito</th>
            <th>Entrada PIX</th>
            <th>Entrada Boleto</th>
            <th>Entrada Dinheiro</th>
            <th>Entrada Outros</th>
            <th>Entrada Soma</th>
            <th>Saida Boletos</th>
            <th>Saida Dinheiro</th>
            <th>Saida Outros</th>
            <th>Saida Soma</th>
            <th>Resultado</th>
          </tr>
        </thead>
        <tbody>
          ${
            fluxos.map(f => {
              const somaEntradas = entradaTotal(f);
              const somaSaidas = saidaTotal(f);
              const saldoDia = somaEntradas - somaSaidas;
              return `
                <tr data-id="${f.id || ""}">
                  <td>${formatDateBR(f.data)}</td>
                  <td>R$ ${numberToMoney(f.entradaCredito || 0)}</td>
                  <td>R$ ${numberToMoney(f.entradaDebito || 0)}</td>
                  <td>R$ ${numberToMoney(f.entradaPix || 0)}</td>
                  <td>R$ ${numberToMoney(f.entradaBoleto || 0)}</td>
                  <td>R$ ${numberToMoney(f.entradaDinheiro || 0)}</td>
                  <td>R$ ${numberToMoney(f.entradaOutros || 0)}</td>
                  <td><strong>R$ ${numberToMoney(somaEntradas)}</strong></td>
                  <td>R$ ${numberToMoney(f.saidaBoletos || 0)}</td>
                  <td>R$ ${numberToMoney(f.saidaDinheiro || 0)}</td>
                  <td>R$ ${numberToMoney(f.saidaOutros || 0)}</td>
                  <td><strong>R$ ${numberToMoney(somaSaidas)}</strong></td>
                  <td style="font-weight:700; color:${saldoDia >= 0 ? '#1b864c' : '#c0392b'};">R$ ${numberToMoney(saldoDia)}</td>
                </tr>
              `;
            }).join("") || '<tr><td colspan="14" style="color:#777;">Nenhum lancamento registrado.</td></tr>'
          }
          ${
            fluxos.length ? (() => {
              const tot = {
                eCred: fluxos.reduce((s,r)=>s+ (Number(r.entradaCredito)||0),0),
                eDeb: fluxos.reduce((s,r)=>s+ (Number(r.entradaDebito)||0),0),
                ePix: fluxos.reduce((s,r)=>s+ (Number(r.entradaPix)||0),0),
                eBol: fluxos.reduce((s,r)=>s+ (Number(r.entradaBoleto)||0),0),
                eDin: fluxos.reduce((s,r)=>s+ (Number(r.entradaDinheiro)||0),0),
                eOut: fluxos.reduce((s,r)=>s+ (Number(r.entradaOutros)||0),0),
                sBol: fluxos.reduce((s,r)=>s+ (Number(r.saidaBoletos)||0),0),
                sDin: fluxos.reduce((s,r)=>s+ (Number(r.saidaDinheiro)||0),0),
                sOut: fluxos.reduce((s,r)=>s+ (Number(r.saidaOutros)||0),0),
              };
              const somaE = tot.eCred+tot.eDeb+tot.ePix+tot.eBol+tot.eDin+tot.eOut;
              const somaS = tot.sBol+tot.sDin+tot.sOut;
              const resultado = somaE - somaS;
              return `
                <tr style="background:#f5f7fb; font-weight:700;">
                  <td>Total</td>
                  <td>R$ ${numberToMoney(tot.eCred)}</td>
                  <td>R$ ${numberToMoney(tot.eDeb)}</td>
                  <td>R$ ${numberToMoney(tot.ePix)}</td>
                  <td>R$ ${numberToMoney(tot.eBol)}</td>
                  <td>R$ ${numberToMoney(tot.eDin)}</td>
                  <td>R$ ${numberToMoney(tot.eOut)}</td>
                  <td>R$ ${numberToMoney(somaE)}</td>
                  <td>R$ ${numberToMoney(tot.sBol)}</td>
                  <td>R$ ${numberToMoney(tot.sDin)}</td>
                  <td>R$ ${numberToMoney(tot.sOut)}</td>
                  <td>R$ ${numberToMoney(somaS)}</td>
                  <td style="color:${resultado>=0 ? '#1b864c' : '#c0392b'};">R$ ${numberToMoney(resultado)}</td>
                </tr>
              `;
            })() : ""
          }
        </tbody>
      `;
      tableWrap.appendChild(table);

      const formWrap = document.createElement("div");
      formWrap.className = "list-card";
      formWrap.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
          <h4 id="fluxo-form-title" style="margin:0;">Novo lancamento</h4>
          <button class="ghost-btn" id="fluxo-delete" style="display:none;">Excluir</button>
        </div>
        <div class="form-grid">
          <div class="field">
            <label>Data</label>
            <input type="date" id="fluxo-data">
          </div>
          <div class="field">
            <label>Entrada (Credito)</label>
            <input type="text" id="fluxo-entr-cred" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (Debito)</label>
            <input type="text" id="fluxo-entr-deb" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (PIX)</label>
            <input type="text" id="fluxo-entr-pix" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (Boleto)</label>
            <input type="text" id="fluxo-entr-bol" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (Dinheiro)</label>
            <input type="text" id="fluxo-entr-din" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (Outros)</label>
            <input type="text" id="fluxo-entr-out" placeholder="0,00">
          </div>
          <div class="field">
            <label>Entrada (Soma)</label>
            <input type="text" id="fluxo-entr-soma" readonly>
          </div>
          <div class="field">
            <label>Saida (Boletos)</label>
            <input type="text" id="fluxo-sai-bol" placeholder="0,00">
          </div>
          <div class="field">
            <label>Saida (Dinheiro)</label>
            <input type="text" id="fluxo-sai-din" placeholder="0,00">
          </div>
          <div class="field">
            <label>Saida (Outros)</label>
            <input type="text" id="fluxo-sai-out" placeholder="0,00">
          </div>
          <div class="field">
            <label>Saida (Soma)</label>
            <input type="text" id="fluxo-sai-soma" readonly>
          </div>
        </div>
        <div class="actions" style="justify-content:flex-end;">
          <button class="ghost-btn" id="fluxo-clear">Limpar</button>
          <button class="primary-btn" id="fluxo-save">Salvar lancamento</button>
        </div>
        <div class="muted" id="fluxo-hint"></div>
      `;

      const dataInput = formWrap.querySelector("#fluxo-data");
      const eCred = formWrap.querySelector("#fluxo-entr-cred");
      const eDeb = formWrap.querySelector("#fluxo-entr-deb");
      const ePix = formWrap.querySelector("#fluxo-entr-pix");
      const eBol = formWrap.querySelector("#fluxo-entr-bol");
      const eDin = formWrap.querySelector("#fluxo-entr-din");
      const eOut = formWrap.querySelector("#fluxo-entr-out");
      const eSoma = formWrap.querySelector("#fluxo-entr-soma");
      const sBol = formWrap.querySelector("#fluxo-sai-bol");
      const sDin = formWrap.querySelector("#fluxo-sai-din");
      const sOut = formWrap.querySelector("#fluxo-sai-out");
      const sSoma = formWrap.querySelector("#fluxo-sai-soma");
      const hint = formWrap.querySelector("#fluxo-hint");
      const deleteBtn = formWrap.querySelector("#fluxo-delete");
      const title = formWrap.querySelector("#fluxo-form-title");
      const cancelEditBtn = tableWrap.querySelector("#fluxo-clear-selection");
      const reportBtn = tableWrap.querySelector("#fluxo-report-btn");
      const reportInicio = tableWrap.querySelector("#fluxo-report-inicio");
      const reportFim = tableWrap.querySelector("#fluxo-report-fim");

      const entradaInputs = [eCred, eDeb, ePix, eBol, eDin, eOut];
      const saidaInputs = [sBol, sDin, sOut];

      const sanitize = (el) => { el.value = el.value.replace(/[^\d.,-]/g, ""); };
      const format = (el) => { el.value = numberToMoney(moneyToNumber(el.value)); };

      function updateSomas() {
        const somaE = entradaInputs.reduce((sum, inp) => sum + moneyToNumber(inp.value), 0);
        const somaS = saidaInputs.reduce((sum, inp) => sum + moneyToNumber(inp.value), 0);
        eSoma.value = numberToMoney(somaE);
        sSoma.value = numberToMoney(somaS);
      }

      function resetForm() {
        editingFluxoId = null;
        editingFluxoIndex = -1;
        dataInput.value = todayISO();
        entradaInputs.forEach(inp => inp.value = "");
        saidaInputs.forEach(inp => inp.value = "");
        eSoma.value = "";
        sSoma.value = "";
        hint.textContent = "";
        deleteBtn.style.display = "none";
        cancelEditBtn.style.display = "none";
        title.textContent = "Novo lancamento";
        updateSomas();
      }

      function startEdit(registro, idx) {
        if (!registro) return;
        editingFluxoId = registro.id != null ? registro.id : Date.now();
        editingFluxoIndex = typeof idx === "number" ? idx : fluxos.findIndex(r => (r.id || "").toString() === (registro.id || "").toString());
        dataInput.value = registro.data || todayISO();
        eCred.value = numberToMoney(registro.entradaCredito || 0);
        eDeb.value = numberToMoney(registro.entradaDebito || 0);
        ePix.value = numberToMoney(registro.entradaPix || 0);
        eBol.value = numberToMoney(registro.entradaBoleto || 0);
        eDin.value = numberToMoney(registro.entradaDinheiro || 0);
        eOut.value = numberToMoney(registro.entradaOutros || 0);
        sBol.value = numberToMoney(registro.saidaBoletos || 0);
        sDin.value = numberToMoney(registro.saidaDinheiro || 0);
        sOut.value = numberToMoney(registro.saidaOutros || 0);
        updateSomas();
        deleteBtn.style.display = "inline-flex";
        cancelEditBtn.style.display = "inline-flex";
        title.textContent = "Editando lancamento";
        hint.textContent = "Edite os valores e salve.";
      }

      function saveFluxo() {
        const data = dataInput.value || todayISO();
        const reg = {
          id: editingFluxoId || Date.now(),
          data,
          entradaCredito: moneyToNumber(eCred.value),
          entradaDebito: moneyToNumber(eDeb.value),
          entradaPix: moneyToNumber(ePix.value),
          entradaBoleto: moneyToNumber(eBol.value),
          entradaDinheiro: moneyToNumber(eDin.value),
          entradaOutros: moneyToNumber(eOut.value),
          saidaBoletos: moneyToNumber(sBol.value),
          saidaDinheiro: moneyToNumber(sDin.value),
          saidaOutros: moneyToNumber(sOut.value),
        };
        if (!data) {
          hint.textContent = "Informe a data.";
          return;
        }
        const list = JSON.parse(localStorage.getItem(FLUXO_KEY) || "[]");
        if (editingFluxoId) {
          const idx = list.findIndex(r => (r.id || "").toString() === editingFluxoId.toString());
          if (idx >= 0) {
            list[idx] = { ...list[idx], ...reg };
          } else if (editingFluxoIndex >= 0 && editingFluxoIndex < list.length) {
            list[editingFluxoIndex] = { ...list[editingFluxoIndex], ...reg };
          } else {
            list.unshift(reg);
          }
          hint.textContent = "Lancamento atualizado.";
        } else {
          list.unshift(reg);
          hint.textContent = "Lancamento salvo.";
        }
        localStorage.setItem(FLUXO_KEY, JSON.stringify(list));
        renderFluxoMensal();
      }

      function deleteFluxo() {
        if (!editingFluxoId) {
          hint.textContent = "Selecione um lancamento (duplo clique) para excluir.";
          return;
        }
        const list = JSON.parse(localStorage.getItem(FLUXO_KEY) || "[]");
        const filtered = list.filter(r => (r.id || "").toString() !== editingFluxoId.toString());
        localStorage.setItem(FLUXO_KEY, JSON.stringify(filtered));
        hint.textContent = "Lancamento excluido.";
        renderFluxoMensal();
      }

      entradaInputs.concat(saidaInputs).forEach(inp => {
        inp.addEventListener("input", () => { sanitize(inp); updateSomas(); });
        inp.addEventListener("blur", () => { format(inp); updateSomas(); });
      });

      formWrap.querySelector("#fluxo-save").addEventListener("click", saveFluxo);
      formWrap.querySelector("#fluxo-clear").addEventListener("click", resetForm);
      deleteBtn.addEventListener("click", deleteFluxo);
      cancelEditBtn.addEventListener("click", resetForm);

      function generateReport() {
        const ini = reportInicio.value ? parseLocalDate(reportInicio.value) : null;
        const fim = reportFim.value ? parseLocalDate(reportFim.value) : null;
        const list = JSON.parse(localStorage.getItem(FLUXO_KEY) || "[]").filter(r => r.data);
        const filtered = list.filter(r => {
          const d = parseLocalDate(r.data);
          if (!d) return false;
          if (ini && d < ini) return false;
          if (fim && d > fim) return false;
          return true;
        }).sort((a,b)=> {
          const da = parseLocalDate(a.data);
          const db = parseLocalDate(b.data);
          return (da ? da.getTime() : 0) - (db ? db.getTime() : 0);
        });
        if (!filtered.length) {
          hint.textContent = "Nenhum lancamento no periodo informado.";
          return;
        }
        const sumField = (arr, key) => arr.reduce((s,r)=>s+(Number(r[key])||0),0);
        const totals = {
          eCred: sumField(filtered,"entradaCredito"),
          eDeb: sumField(filtered,"entradaDebito"),
          ePix: sumField(filtered,"entradaPix"),
          eBol: sumField(filtered,"entradaBoleto"),
          eDin: sumField(filtered,"entradaDinheiro"),
          eOut: sumField(filtered,"entradaOutros"),
          sBol: sumField(filtered,"saidaBoletos"),
          sDin: sumField(filtered,"saidaDinheiro"),
          sOut: sumField(filtered,"saidaOutros"),
        };
        const somaE = totals.eCred+totals.eDeb+totals.ePix+totals.eBol+totals.eDin+totals.eOut;
        const somaS = totals.sBol+totals.sDin+totals.sOut;
        const resultadoTot = somaE - somaS;

        const rows = filtered.map(r => {
          const eSum = entradaTotal(r);
          const sSum = saidaTotal(r);
          const res = eSum - sSum;
          return `
            <tr>
              <td>${formatDateBR(r.data)}</td>
              <td>R$ ${numberToMoney(r.entradaCredito || 0)}</td>
              <td>R$ ${numberToMoney(r.entradaDebito || 0)}</td>
              <td>R$ ${numberToMoney(r.entradaPix || 0)}</td>
              <td>R$ ${numberToMoney(r.entradaBoleto || 0)}</td>
              <td>R$ ${numberToMoney(r.entradaDinheiro || 0)}</td>
              <td>R$ ${numberToMoney(r.entradaOutros || 0)}</td>
              <td><strong>R$ ${numberToMoney(eSum)}</strong></td>
              <td>R$ ${numberToMoney(r.saidaBoletos || 0)}</td>
              <td>R$ ${numberToMoney(r.saidaDinheiro || 0)}</td>
              <td>R$ ${numberToMoney(r.saidaOutros || 0)}</td>
              <td><strong>R$ ${numberToMoney(sSum)}</strong></td>
              <td style="font-weight:700; color:${res>=0 ? '#1b864c' : '#c0392b'};">R$ ${numberToMoney(res)}</td>
            </tr>
          `;
        }).join("");

        const html = `
          <html>
            <head>
              <title>Fluxo Mensal Financeiro</title>
              <style>
                body { font-family: Arial, sans-serif; padding:16px; color:#111827; font-size:11px; }
                h2 { margin:0 0 8px 0; }
                .muted { color:#6b7280; margin-bottom:10px; }
                table { width:100%; border-collapse:collapse; font-size:11px; }
                th, td { border:1px solid #d1d5db; padding:6px; text-align:left; }
                thead th { background:#f3f4f6; }
                tfoot td { background:#f5f7fb; font-weight:700; }
              </style>
            </head>
            <body>
              <h2>Fluxo Mensal Financeiro</h2>
              <div class="muted">
                Emitido em ${new Date().toLocaleString("pt-BR")}
                ${ini ? " | De " + formatDateBR(reportInicio.value) : ""}
                ${fim ? " ate " + formatDateBR(reportFim.value) : ""}
              </div>
              <table>
                <thead>
                  <tr>
                    <th>Data</th>
                    <th>Entrada Credito</th>
                    <th>Entrada Debito</th>
                    <th>Entrada PIX</th>
                    <th>Entrada Boleto</th>
                    <th>Entrada Dinheiro</th>
                    <th>Entrada Outros</th>
                    <th>Entrada Soma</th>
                    <th>Saida Boletos</th>
                    <th>Saida Dinheiro</th>
                    <th>Saida Outros</th>
                    <th>Saida Soma</th>
                    <th>Resultado</th>
                  </tr>
                </thead>
                <tbody>${rows}</tbody>
                <tfoot>
                  <tr>
                    <td>Total</td>
                    <td>R$ ${numberToMoney(totals.eCred)}</td>
                    <td>R$ ${numberToMoney(totals.eDeb)}</td>
                    <td>R$ ${numberToMoney(totals.ePix)}</td>
                    <td>R$ ${numberToMoney(totals.eBol)}</td>
                    <td>R$ ${numberToMoney(totals.eDin)}</td>
                    <td>R$ ${numberToMoney(totals.eOut)}</td>
                    <td>R$ ${numberToMoney(somaE)}</td>
                    <td>R$ ${numberToMoney(totals.sBol)}</td>
                    <td>R$ ${numberToMoney(totals.sDin)}</td>
                    <td>R$ ${numberToMoney(totals.sOut)}</td>
                    <td>R$ ${numberToMoney(somaS)}</td>
                    <td>R$ ${numberToMoney(resultadoTot)}</td>
                  </tr>
                </tfoot>
              </table>
              <script>window.print();<\/script>
            </body>
          </html>
        `;
        const win = window.open("", "_blank");
        if (win) {
          win.document.write(html);
          win.document.close();
        }
      }

      if (reportBtn) reportBtn.addEventListener("click", generateReport);

      if (fluxos.length) {
        Array.from(table.querySelectorAll("tbody tr")).forEach((tr, idx) => {
          const id = tr.dataset.id;
          tr.style.cursor = "pointer";
          tr.addEventListener("dblclick", () => {
            const list = JSON.parse(localStorage.getItem(FLUXO_KEY) || "[]");
            const reg = id ? list.find(r => (r.id || "").toString() === id.toString()) : list[idx];
            startEdit(reg, idx);
          });
        });
      }

      resetForm();
      panel.innerHTML = "";
      panel.appendChild(summary);
      panel.appendChild(tableWrap);
      panel.appendChild(formWrap);
    }

    function setTab(tabId) {
      activeTab = tabId;
      buttons.forEach(btn => btn.el.classList.toggle("active", btn.id === tabId));
      if (tabId === "receber") {
        renderContasReceber();
      } else if (tabId === "pagar") {
        renderContasPagar();
      } else if (tabId === "fluxo") {
        renderFluxoMensal();
      } else if (tabId === "extrato") {
        renderPlaceholder("Extrato diario", "Inclua aqui o extrato de fluxo diario.");
      } else {
        renderPlaceholder("Area em construcao", "Selecione uma opcao valida.");
      }
    }

    setTab(activeTab);
  }

  function renderConfiguracoes() {
    const users = JSON.parse(localStorage.getItem("printlab_users") || "[]");
    let selectedIndex = users.length ? 0 : -1;
    const produtos = JSON.parse(localStorage.getItem("printlab_produtos") || "[]");
    let selectedProdIndex = produtos.length ? 0 : -1;

    const container = document.createElement("div");
    container.className = "card";
    const header = document.createElement("div");
    header.style.display = "flex";
    header.style.justifyContent = "space-between";
    header.style.alignItems = "center";
    header.innerHTML = '<h2 style="margin:0; color:var(--primary); display:flex; align-items:center; gap:8px;"><img src="static/icone_cadastro_usuario.svg" alt="" height="22">Usu&aacute;rios</h2><button class="icon-btn" id="cfg-new-user"><img src="static/icone_cadastro_usuario.svg" alt="" height="18">Novo Usuario</button>';
    container.appendChild(header);

    const wrap = document.createElement("div");
    wrap.className = "config-grid";

    const table = document.createElement("table");
    table.className = "table";
    table.innerHTML = `
      <thead>
        <tr>
          <th>Usuario</th>
          <th>Nome</th>
          <th>Email</th>
          <th>Perfil</th>
        </tr>
      </thead>
      <tbody id="cfg-users-body"></tbody>
    `;

    const formCard = document.createElement("div");
    formCard.className = "list-card";
    formCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_cadastro_usuario.svg" alt="" height="18">Editar usuario</h4>
      <div class="field"><label>Usuario</label><input id="cfg-user" class="inline-input" type="text" placeholder="usuario"></div>
      <div class="field"><label>Nome</label><input id="cfg-name" class="inline-input" type="text" placeholder="Nome completo"></div>
      <div class="field"><label>Senha</label><input id="cfg-pass" class="inline-input" type="password" placeholder="Senha"></div>
      <div class="field"><label>Perfil</label>
        <select id="cfg-role" class="inline-input">
          <option value="Administrador">Administrador</option>
          <option value="Atendimento">Atendimento</option>
          <option value="Designer">Designer</option>
          <option value="Producao">Producao</option>
          <option value="Financeiro">Financeiro</option>
          <option value="Recursos Humanos">Recursos Humanos</option>
        </select>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="cfg-cancel">Cancelar</button>
        <button class="primary-btn" id="cfg-save">Salvar</button>
      </div>
      <div class="muted" id="cfg-hint"></div>
    `;

    wrap.appendChild(table);
    wrap.appendChild(formCard);
    container.appendChild(wrap);

    const permCard = document.createElement("div");
    permCard.className = "list-card";
    permCard.innerHTML = `
      <h4>Permiss&otilde;es por usu&aacute;rio</h4>
      <div class="field">
        <label>Usuario</label>
        <select id="perm-user" class="inline-input"></select>
      </div>
      <div id="perm-checks"></div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="perm-allow-all">Liberar tudo</button>
        <button class="primary-btn" id="perm-save">Salvar permissoes</button>
      </div>
      <div class="muted" id="perm-hint"></div>
    `;
    const permChecks = permCard.querySelector("#perm-checks");
    permChecks.style.display = "grid";
    permChecks.style.gridTemplateColumns = "repeat(auto-fit, minmax(180px, 1fr))";
    permChecks.style.gap = "8px";
    container.appendChild(permCard);

    const divider = document.createElement("div");
    divider.className = "divider";
    container.appendChild(divider);

    const prodHeader = document.createElement("div");
    prodHeader.style.display = "flex";
    prodHeader.style.justifyContent = "space-between";
    prodHeader.style.alignItems = "center";
    prodHeader.innerHTML = `
      <h2 style="margin:0; color:var(--primary); display:flex; align-items:center; gap:8px;"><img src="static/icone_cadastro_produto.svg" alt="" height="22">Produtos</h2>
      <div style="display:flex; gap:8px; flex-wrap:wrap;">
        <button class="icon-btn" id="cfg-prod-seed"><img src="static/icone_novo_emissor.svg" alt="" height="18">Gerar impressao</button>
        <button class="icon-btn" id="cfg-prod-seed-uv"><img src="static/icone_novo_emissor.svg" alt="" height="18">Gerar UV</button>
        <button class="icon-btn" id="cfg-prod-seed-serv"><img src="static/icone_novo_emissor.svg" alt="" height="18">Gerar servicos</button>
        <button class="icon-btn" id="cfg-prod-seed-com"><img src="static/icone_novo_emissor.svg" alt="" height="18">Gerar comunicacao</button>
        <button class="icon-btn" id="cfg-new-prod"><img src="static/icone_cadastro_produto.svg" alt="" height="18">Novo Produto</button>
      </div>
    `;
    container.appendChild(prodHeader);

    const prodWrap = document.createElement("div");
    prodWrap.className = "config-grid";

    const prodTable = document.createElement("table");
    prodTable.className = "table";
    prodTable.innerHTML = `
      <thead>
        <tr>
          <th>Material</th>
          <th>Descrição</th>
          <th>Unidade</th>
          <th>Preço Unitário (R$)</th>
        </tr>
      </thead>
      <tbody id="cfg-prod-body"></tbody>
    `;

    const prodFormCard = document.createElement("div");
    prodFormCard.className = "list-card";
    prodFormCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_cadastro_produto.svg" alt="" height="18">Cadastro de produto</h4>
      <div class="field"><label>Material</label><input id="cfg-prod-material" class="inline-input upper-input" type="text" placeholder="Material"></div>
      <div class="field"><label>Descrição</label><input id="cfg-prod-descricao" class="inline-input upper-input" type="text" placeholder="Descrição"></div>
      <div class="field">
        <label>Unidade</label>
        <select id="cfg-prod-unidade" class="inline-input upper-input">
          <option value="UNIDADE(S)">UNIDADE(S)</option>
          <option value="CONJUNTO(S)">CONJUNTO(S)</option>
          <option value="CENTO(S)">CENTO(S)</option>
        </select>
      </div>
      <div class="field"><label>Preço Unitário</label><input id="cfg-prod-preco" class="inline-input" type="text" placeholder="0,00"></div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="cfg-prod-cancel">Cancelar</button>
        <button class="primary-btn" id="cfg-prod-save">Salvar</button>
      </div>
      <div class="muted" id="cfg-prod-hint"></div>
    `;

    prodWrap.appendChild(prodTable);
    prodWrap.appendChild(prodFormCard);
    container.appendChild(prodWrap);

    const extraDivider = document.createElement("div");
    extraDivider.className = "divider";
    container.appendChild(extraDivider);

    const extraWrap = document.createElement("div");
    extraWrap.className = "config-grid";

    const setorCard = document.createElement("div");
    setorCard.className = "list-card";
    setorCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_setor.svg" alt="" height="18">Setor</h4>
      <div class="field">
        <label>Cadastro de setor</label>
        <input id="setor-name" class="inline-input" type="text" placeholder="Nome do setor">
      </div>
      <div class="field">
        <label>Usuarios desse setor</label>
        <select id="setor-users" class="inline-input" multiple size="6"></select>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="setor-cancel">Cancelar</button>
        <button class="primary-btn" id="setor-save">Salvar</button>
      </div>
      <div class="muted" id="setor-hint"></div>
      <div class="divider"></div>
      <div class="field">
        <label>Lista de setores e usuarios</label>
        <div class="produto-table-like">
          <table>
            <thead>
              <tr>
                <th>Setor</th>
                <th>Usuarios</th>
              </tr>
            </thead>
            <tbody id="setor-list-body"></tbody>
          </table>
        </div>
      </div>
    `;

    const fluxogramaCard = document.createElement("div");
    fluxogramaCard.className = "list-card";
    fluxogramaCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_fluxograma.svg" alt="" height="18">Fluxograma</h4>
      <div class="field">
        <label>Produto</label>
        <select id="flux-produto" class="inline-input"></select>
      </div>
      <div class="field">
        <label>Setor</label>
        <div style="display:flex; gap:8px; align-items:center;">
          <select id="flux-setor" class="inline-input" style="flex:1;"></select>
          <button class="ghost-btn" type="button" id="flux-add-setor">Adicionar setor</button>
        </div>
      </div>
      <div class="field">
        <label>Sequencia de setores</label>
        <ol id="flux-seq-list" style="margin:0; padding-left:18px;"></ol>
        <div class="small-muted" id="flux-seq-empty" style="margin-top:6px;"></div>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="flux-cancel">Cancelar</button>
        <button class="primary-btn" id="flux-save">Salvar</button>
      </div>
      <div class="muted" id="flux-hint"></div>
      <div class="divider"></div>
      <div class="field">
        <label>Lista de fluxogramas</label>
        <div class="produto-table-like">
          <table>
            <thead>
              <tr>
                <th>Produto</th>
                <th>Fluxo</th>
              </tr>
            </thead>
            <tbody id="flux-list-body"></tbody>
          </table>
        </div>
      </div>
    `;

    const maquinasCard = document.createElement("div");
    maquinasCard.className = "list-card";
    maquinasCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_maquinas_e_impressoras.svg" alt="" height="18">Maquinas e Impressoras</h4>
      <div class="field">
        <label>Tipo</label>
        <select id="maq-tipo" class="inline-input">
          <option value="Maquina">Maquina</option>
          <option value="Impressora">Impressora</option>
          <option value="Computador">Computador</option>
        </select>
      </div>
      <div class="field"><label>Numero de serie</label><input id="maq-serie" class="inline-input" type="text" placeholder="Numero de serie"></div>
      <div class="field"><label>Data de Cadastro</label><input id="maq-data" class="inline-input" type="text" readonly></div>
      <div class="field">
        <label>Usuario</label>
        <select id="maq-user" class="inline-input"></select>
      </div>
      <div class="field">
        <label>Tecnico</label>
        <select id="maq-tecnico" class="inline-input"></select>
      </div>
      <div class="field"><label>Codigo</label><input id="maq-codigo" class="inline-input" type="text" readonly></div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="maq-cancel">Cancelar</button>
        <button class="primary-btn" id="maq-save">Salvar</button>
      </div>
      <div class="muted" id="maq-hint"></div>
      <div class="divider"></div>
      <div class="field">
        <label>Lista de maquinas e impressoras</label>
        <div class="produto-table-like">
          <table>
            <thead>
              <tr>
                <th>Codigo</th>
                <th>Tipo</th>
                <th>Numero de serie</th>
                <th>Data de Cadastro</th>
                <th>Usuario</th>
                <th>Tecnico</th>
              </tr>
            </thead>
            <tbody id="maq-list-body"></tbody>
          </table>
        </div>
      </div>
    `;

    const tecnicoCard = document.createElement("div");
    tecnicoCard.className = "list-card";
    tecnicoCard.innerHTML = `
      <h4 style="display:flex; align-items:center; gap:8px;"><img src="static/icone_cadastro_tecnico.svg" alt="" height="18">Técnico</h4>
      <div class="field"><label>Nome</label><input id="tec-nome" class="inline-input" type="text" placeholder="Nome"></div>
      <div class="field"><label>Telefone</label><input id="tec-telefone" class="inline-input" type="text" placeholder="(00) 00000-0000"></div>
      <div class="field"><label>Data de Cadastro</label><input id="tec-data" class="inline-input" type="text" readonly></div>
      <div class="field">
        <label>Tipo de Contrato</label>
        <select id="tec-contrato" class="inline-input">
          <option value="Mensal">Mensal</option>
          <option value="Hora">Hora</option>
        </select>
      </div>
      <div class="actions" style="justify-content:flex-end;">
        <button class="ghost-btn" id="tec-cancel">Cancelar</button>
        <button class="primary-btn" id="tec-save">Salvar</button>
      </div>
      <div class="muted" id="tec-hint"></div>
      <div class="divider"></div>
      <div class="field">
        <label>Lista de tecnicos cadastrados</label>
        <div class="produto-table-like">
          <table>
            <thead>
              <tr>
                <th>Nome</th>
                <th>Telefone</th>
                <th>Data de Cadastro</th>
                <th>Tipo de Contrato</th>
              </tr>
            </thead>
            <tbody id="tec-list-body"></tbody>
          </table>
        </div>
      </div>
    `;

    extraWrap.appendChild(setorCard);
    extraWrap.appendChild(fluxogramaCard);
    extraWrap.appendChild(maquinasCard);
    extraWrap.appendChild(tecnicoCard);
    container.appendChild(extraWrap);

    mainContent.innerHTML = "";
    mainContent.appendChild(container);

    const tbody = table.querySelector("#cfg-users-body");
    const hint = document.getElementById("cfg-hint");
    const permHint = document.getElementById("perm-hint");
    const permUserSelect = document.getElementById("perm-user");
    let permissions = JSON.parse(localStorage.getItem("printlab_permissions") || "{}");
    const inputs = {
      user: document.getElementById("cfg-user"),
      name: document.getElementById("cfg-name"),
      pass: document.getElementById("cfg-pass"),
      role: document.getElementById("cfg-role"),
    };
    const setorUsersSelect = document.getElementById("setor-users");
    const setorNameInput = document.getElementById("setor-name");
    const setorHint = document.getElementById("setor-hint");
    const setorListBody = document.getElementById("setor-list-body");
    const setorSaveBtn = document.getElementById("setor-save");
    const setorCancelBtn = document.getElementById("setor-cancel");
    let setores = JSON.parse(localStorage.getItem("printlab_setores") || "[]");
    const fluxProdutoSelect = document.getElementById("flux-produto");
    const fluxSetorSelect = document.getElementById("flux-setor");
    const fluxAddSetorBtn = document.getElementById("flux-add-setor");
    const fluxSeqList = document.getElementById("flux-seq-list");
    const fluxSeqEmpty = document.getElementById("flux-seq-empty");
    const fluxHint = document.getElementById("flux-hint");
    const fluxListBody = document.getElementById("flux-list-body");
    const fluxSaveBtn = document.getElementById("flux-save");
    const fluxCancelBtn = document.getElementById("flux-cancel");
    let fluxogramas = JSON.parse(localStorage.getItem("printlab_fluxogramas") || "[]");
    let fluxoSetores = [];
    const tecNomeInput = document.getElementById("tec-nome");
    const tecTelefoneInput = document.getElementById("tec-telefone");
    const tecDataInput = document.getElementById("tec-data");
    const tecContratoSelect = document.getElementById("tec-contrato");
    const tecHint = document.getElementById("tec-hint");
    const tecListBody = document.getElementById("tec-list-body");
    const tecSaveBtn = document.getElementById("tec-save");
    const tecCancelBtn = document.getElementById("tec-cancel");
    let tecnicos = JSON.parse(localStorage.getItem("printlab_tecnicos") || "[]");
    const maqTipoSelect = document.getElementById("maq-tipo");
    const maqSerieInput = document.getElementById("maq-serie");
    const maqDataInput = document.getElementById("maq-data");
    const maqUserSelect = document.getElementById("maq-user");
    const maqTecnicoSelect = document.getElementById("maq-tecnico");
    const maqCodigoInput = document.getElementById("maq-codigo");
    const maqHint = document.getElementById("maq-hint");
    const maqListBody = document.getElementById("maq-list-body");
    const maqSaveBtn = document.getElementById("maq-save");
    const maqCancelBtn = document.getElementById("maq-cancel");
    let maquinas = JSON.parse(localStorage.getItem("printlab_maquinas") || "[]");

    function renderSetorUsersOptions() {
      if (!setorUsersSelect) return;
      setorUsersSelect.innerHTML = "";
      if (!users.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum usuario cadastrado";
        setorUsersSelect.appendChild(opt);
        if (setorHint) setorHint.textContent = "Cadastre usuarios para selecionar neste setor.";
        return;
      }
      users.forEach(u => {
        const opt = document.createElement("option");
        opt.value = u.user;
        opt.textContent = u.user || u.name || "Usuario";
        setorUsersSelect.appendChild(opt);
      });
      if (setorHint) setorHint.textContent = "Selecione os usuarios que pertencem ao setor.";
    }

    function renderSetorList() {
      if (!setorListBody) return;
      setorListBody.innerHTML = "";
      if (!setores.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = `<td colspan="2" class="small-muted">Nenhum setor cadastrado.</td>`;
        setorListBody.appendChild(tr);
        return;
      }
      setores.forEach(item => {
        const tr = document.createElement("tr");
        const usersText = Array.isArray(item.users) && item.users.length ? item.users.join(", ") : "-";
        tr.innerHTML = `<td>${item.name || "-"}</td><td>${usersText}</td>`;
        setorListBody.appendChild(tr);
      });
    }

    function getProdutoLabel(prod) {
      const material = (prod?.material || "").trim();
      const descricao = (prod?.descricao || "").trim();
      if (material && descricao) return `${material} - ${descricao}`;
      return material || descricao || "Produto";
    }

    function renderFluxoProdutoOptions() {
      if (!fluxProdutoSelect) return;
      fluxProdutoSelect.innerHTML = "";
      if (!produtos.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum produto cadastrado";
        fluxProdutoSelect.appendChild(opt);
        return;
      }
      produtos.forEach(prod => {
        const label = getProdutoLabel(prod);
        const opt = document.createElement("option");
        opt.value = label;
        opt.textContent = label;
        fluxProdutoSelect.appendChild(opt);
      });
    }

    function renderFluxoSetorOptions() {
      if (!fluxSetorSelect) return;
      fluxSetorSelect.innerHTML = "";
      if (!setores.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum setor cadastrado";
        fluxSetorSelect.appendChild(opt);
        return;
      }
      setores.forEach(item => {
        const name = (item?.name || "").trim() || "Setor";
        const opt = document.createElement("option");
        opt.value = name;
        opt.textContent = name;
        fluxSetorSelect.appendChild(opt);
      });
    }

    function renderFluxoSequencia() {
      if (!fluxSeqList) return;
      fluxSeqList.innerHTML = "";
      if (!fluxoSetores.length) {
        if (fluxSeqEmpty) fluxSeqEmpty.textContent = "Nenhum setor adicionado.";
        return;
      }
      if (fluxSeqEmpty) fluxSeqEmpty.textContent = "";
      fluxoSetores.forEach(setor => {
        const li = document.createElement("li");
        li.textContent = setor;
        fluxSeqList.appendChild(li);
      });
    }

    function renderFluxogramasList() {
      if (!fluxListBody) return;
      fluxListBody.innerHTML = "";
      if (!fluxogramas.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = `<td colspan="2" class="small-muted">Nenhum fluxograma cadastrado.</td>`;
        fluxListBody.appendChild(tr);
        return;
      }
      fluxogramas.forEach(item => {
        const tr = document.createElement("tr");
        const fluxoText = Array.isArray(item.setores) && item.setores.length ? item.setores.join(" > ") : "-";
        tr.innerHTML = `<td>${item.produto || "-"}</td><td>${fluxoText}</td>`;
        fluxListBody.appendChild(tr);
      });
    }

    function resetFluxogramaForm() {
      fluxoSetores = [];
      if (fluxProdutoSelect) fluxProdutoSelect.selectedIndex = 0;
      if (fluxSetorSelect) fluxSetorSelect.selectedIndex = 0;
      if (fluxHint) fluxHint.textContent = "";
      renderFluxoSequencia();
    }

    function renderTecnicosList() {
      if (!tecListBody) return;
      tecListBody.innerHTML = "";
      if (!tecnicos.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = `<td colspan="4" class="small-muted">Nenhum tecnico cadastrado.</td>`;
        tecListBody.appendChild(tr);
        return;
      }
      tecnicos.forEach(item => {
        const tr = document.createElement("tr");
        tr.innerHTML = `
          <td>${item.nome || "-"}</td>
          <td>${item.telefone || "-"}</td>
          <td>${item.dataCadastro || "-"}</td>
          <td>${item.contrato || "-"}</td>
        `;
        tecListBody.appendChild(tr);
      });
    }

    function renderMaquinasList() {
      if (!maqListBody) return;
      maqListBody.innerHTML = "";
      if (!maquinas.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = `<td colspan="6" class="small-muted">Nenhuma maquina cadastrada.</td>`;
        maqListBody.appendChild(tr);
        return;
      }
      maquinas.forEach(item => {
        const tr = document.createElement("tr");
        tr.innerHTML = `
          <td>${item.codigo || "-"}</td>
          <td>${item.tipo || "-"}</td>
          <td>${item.serie || "-"}</td>
          <td>${item.dataCadastro || "-"}</td>
          <td>${item.usuario || "-"}</td>
          <td>${item.tecnico || "-"}</td>
        `;
        maqListBody.appendChild(tr);
      });
    }

    function renderMaquinasUserOptions() {
      if (!maqUserSelect) return;
      maqUserSelect.innerHTML = "";
      if (!users.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum usuario cadastrado";
        maqUserSelect.appendChild(opt);
        return;
      }
      users.forEach(u => {
        const opt = document.createElement("option");
        opt.value = u.user;
        opt.textContent = u.user || u.name || "Usuario";
        maqUserSelect.appendChild(opt);
      });
    }

    function renderMaquinasTecnicoOptions() {
      if (!maqTecnicoSelect) return;
      maqTecnicoSelect.innerHTML = "";
      if (!tecnicos.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum tecnico cadastrado";
        maqTecnicoSelect.appendChild(opt);
        return;
      }
      tecnicos.forEach(t => {
        const opt = document.createElement("option");
        opt.value = t.nome || "";
        opt.textContent = t.nome || "Tecnico";
        maqTecnicoSelect.appendChild(opt);
      });
    }

    function generateMaquinaCodigo() {
      const rand = Math.random().toString(36).slice(2, 6).toUpperCase();
      return `EQ-${Date.now().toString(36).toUpperCase()}-${rand}`;
    }

    function renderPermUserOptions(selectedUser) {
      permUserSelect.innerHTML = "";
      if (!users.length) {
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = "Nenhum usuario cadastrado";
        permUserSelect.appendChild(opt);
        return;
      }
      users.forEach(u => {
        const opt = document.createElement("option");
        opt.value = u.user;
        opt.textContent = u.user;
        permUserSelect.appendChild(opt);
      });
      if (selectedUser && users.some(u => u.user === selectedUser)) {
        permUserSelect.value = selectedUser;
      }
    }

    function renderPermChecks(userId) {
      permChecks.innerHTML = "";
      if (!userId) {
        permHint.textContent = "Cadastre um usuario para definir permissoes.";
        return;
      }
      const allowed = new Set(permissions[userId] || MENU_ACTIONS.map(a => a.id));
      MENU_ACTIONS.forEach(act => {
        const wrapCheck = document.createElement("label");
        wrapCheck.style.display = "flex";
        wrapCheck.style.alignItems = "center";
        wrapCheck.style.gap = "6px";
        wrapCheck.style.fontSize = "14px";
        const cb = document.createElement("input");
        cb.type = "checkbox";
        cb.value = act.id;
        cb.checked = allowed.has(act.id);
        wrapCheck.appendChild(cb);
        wrapCheck.appendChild(document.createTextNode(act.label));
        permChecks.appendChild(wrapCheck);
      });
      permHint.textContent = "Marque quais botoes do menu este usuario pode acessar.";
    }

    function handlePermUserChange() {
      const selectedUser = permUserSelect.value;
      renderPermChecks(selectedUser);
    }

    renderPermUserOptions(users[0]?.user);
    renderPermChecks(users[0]?.user || "");
    renderSetorUsersOptions();
    renderSetorList();
    renderFluxoProdutoOptions();
    renderFluxoSetorOptions();
    renderFluxoSequencia();
    renderFluxogramasList();
    renderTecnicosList();
    renderMaquinasUserOptions();
    renderMaquinasTecnicoOptions();
    renderMaquinasList();
    permUserSelect.addEventListener("change", handlePermUserChange);

    document.getElementById("perm-allow-all").addEventListener("click", () => {
      permChecks.querySelectorAll("input[type=checkbox]").forEach(cb => cb.checked = true);
      permHint.textContent = "Todas as permissoes liberadas para este usuario.";
    });

    document.getElementById("perm-save").addEventListener("click", () => {
      const userId = permUserSelect.value;
      if (!userId) {
        permHint.textContent = "Selecione um usuario primeiro.";
        return;
      }
      const checked = Array.from(permChecks.querySelectorAll("input[type=checkbox]"))
        .filter(cb => cb.checked)
        .map(cb => cb.value);
      permissions[userId] = checked;
      localStorage.setItem("printlab_permissions", JSON.stringify(permissions));
      permHint.textContent = "Permissoes salvas para " + userId + ".";
    });

    if (setorSaveBtn) {
      setorSaveBtn.addEventListener("click", () => {
        const name = (setorNameInput?.value || "").trim();
        const selectedUsers = Array.from(setorUsersSelect?.selectedOptions || []).map(o => o.value).filter(Boolean);
        if (!name) {
          if (setorHint) setorHint.textContent = "Informe o nome do setor.";
          return;
        }
        const existing = setores.findIndex(s => (s.name || "").toLowerCase() === name.toLowerCase());
        if (existing >= 0) {
          setores[existing].users = selectedUsers;
        } else {
          setores.push({ name, users: selectedUsers });
        }
        localStorage.setItem("printlab_setores", JSON.stringify(setores));
        if (setorHint) setorHint.textContent = "Setor salvo.";
        renderSetorList();
        renderFluxoSetorOptions();
      });
    }

    if (setorCancelBtn) {
      setorCancelBtn.addEventListener("click", () => {
        if (setorNameInput) setorNameInput.value = "";
        if (setorUsersSelect) {
          Array.from(setorUsersSelect.options).forEach(opt => opt.selected = false);
        }
        if (setorHint) setorHint.textContent = "";
      });
    }

    if (fluxAddSetorBtn) {
      fluxAddSetorBtn.addEventListener("click", () => {
        const setor = (fluxSetorSelect?.value || "").trim();
        if (!setor) {
          if (fluxHint) fluxHint.textContent = "Selecione um setor.";
          return;
        }
        fluxoSetores.push(setor);
        if (fluxHint) fluxHint.textContent = "Setor adicionado.";
        renderFluxoSequencia();
      });
    }

    if (fluxSaveBtn) {
      fluxSaveBtn.addEventListener("click", () => {
        const produto = (fluxProdutoSelect?.value || "").trim();
        if (!produto) {
          if (fluxHint) fluxHint.textContent = "Selecione um produto.";
          return;
        }
        if (!fluxoSetores.length) {
          if (fluxHint) fluxHint.textContent = "Adicione pelo menos um setor.";
          return;
        }
        const record = { produto, setores: [...fluxoSetores] };
        const existing = fluxogramas.findIndex(f => (f.produto || "").toLowerCase() === produto.toLowerCase());
        if (existing >= 0) {
          fluxogramas[existing] = record;
        } else {
          fluxogramas.push(record);
        }
        localStorage.setItem("printlab_fluxogramas", JSON.stringify(fluxogramas));
        if (fluxHint) fluxHint.textContent = "Fluxograma salvo.";
        renderFluxogramasList();
        resetFluxogramaForm();
      });
    }

    if (fluxCancelBtn) {
      fluxCancelBtn.addEventListener("click", () => {
        resetFluxogramaForm();
      });
    }

    if (tecDataInput) {
      const today = new Date();
      tecDataInput.value = today.toLocaleDateString("pt-BR");
    }

    if (tecSaveBtn) {
      tecSaveBtn.addEventListener("click", () => {
        const nome = (tecNomeInput?.value || "").trim();
        const telefone = (tecTelefoneInput?.value || "").trim();
        const dataCadastro = (tecDataInput?.value || "").trim();
        const contrato = tecContratoSelect?.value || "Mensal";
        if (!nome) {
          if (tecHint) tecHint.textContent = "Informe o nome do tecnico.";
          return;
        }
        const existing = tecnicos.findIndex(t => (t.nome || "").toLowerCase() === nome.toLowerCase());
        const record = { nome, telefone, dataCadastro, contrato };
        if (existing >= 0) {
          tecnicos[existing] = record;
        } else {
          tecnicos.push(record);
        }
        localStorage.setItem("printlab_tecnicos", JSON.stringify(tecnicos));
        if (tecHint) tecHint.textContent = "Tecnico salvo.";
        renderTecnicosList();
      });
    }

    if (tecCancelBtn) {
      tecCancelBtn.addEventListener("click", () => {
        if (tecNomeInput) tecNomeInput.value = "";
        if (tecTelefoneInput) tecTelefoneInput.value = "";
        if (tecContratoSelect) tecContratoSelect.value = "Mensal";
        if (tecDataInput) {
          const today = new Date();
          tecDataInput.value = today.toLocaleDateString("pt-BR");
        }
        if (tecHint) tecHint.textContent = "";
      });
    }

    if (maqDataInput) {
      const today = new Date();
      maqDataInput.value = today.toLocaleDateString("pt-BR");
    }
    if (maqCodigoInput) {
      maqCodigoInput.value = generateMaquinaCodigo();
    }

    if (maqSaveBtn) {
      maqSaveBtn.addEventListener("click", () => {
        const tipo = maqTipoSelect?.value || "Maquina";
        const serie = (maqSerieInput?.value || "").trim();
        const dataCadastro = (maqDataInput?.value || "").trim();
        const usuario = maqUserSelect?.value || "";
        const tecnico = maqTecnicoSelect?.value || "";
        const codigo = (maqCodigoInput?.value || "").trim() || generateMaquinaCodigo();
        if (!serie) {
          if (maqHint) maqHint.textContent = "Informe o numero de serie.";
          return;
        }
        const record = { codigo, tipo, serie, dataCadastro, usuario, tecnico };
        const existing = maquinas.findIndex(m => (m.codigo || "") === codigo);
        if (existing >= 0) {
          maquinas[existing] = record;
        } else {
          maquinas.push(record);
        }
        localStorage.setItem("printlab_maquinas", JSON.stringify(maquinas));
        if (maqHint) maqHint.textContent = "Item salvo.";
        renderMaquinasList();
        if (maqCodigoInput) maqCodigoInput.value = generateMaquinaCodigo();
      });
    }

    if (maqCancelBtn) {
      maqCancelBtn.addEventListener("click", () => {
        if (maqTipoSelect) maqTipoSelect.value = "Maquina";
        if (maqSerieInput) maqSerieInput.value = "";
        if (maqUserSelect) maqUserSelect.selectedIndex = 0;
        if (maqTecnicoSelect) maqTecnicoSelect.selectedIndex = 0;
        if (maqDataInput) {
          const today = new Date();
          maqDataInput.value = today.toLocaleDateString("pt-BR");
        }
        if (maqCodigoInput) maqCodigoInput.value = generateMaquinaCodigo();
        if (maqHint) maqHint.textContent = "";
      });
    }

    function fillForm(idx) {
      const u = users[idx];
      if (!u) {
        inputs.user.value = "";
        inputs.name.value = "";
        inputs.pass.value = "";
        inputs.role.value = "Atendimento";
        hint.textContent = "";
        return;
      }
      inputs.user.value = u.user || "";
      inputs.name.value = u.name || "";
      inputs.pass.value = u.pass || "";
      inputs.role.value = u.role || "Atendimento";
      hint.textContent = "Editando usuario " + inputs.user.value;
    }

    function renderRows() {
      tbody.innerHTML = "";
      if (!users.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = '<td colspan="4" style="color:#777;">Nenhum usuario cadastrado.</td>';
        tbody.appendChild(tr);
        return;
      }
      users.forEach((u, idx) => {
        const tr = document.createElement("tr");
        tr.dataset.idx = idx;
        tr.style.cursor = "pointer";
        tr.innerHTML = `
          <td>${u.user || ""}</td>
          <td>${u.name || ""}</td>
          <td>${u.email || ""}</td>
          <td>${u.role || ""}</td>
        `;
        tr.addEventListener("click", () => {
          selectedIndex = idx;
          fillForm(selectedIndex);
          Array.from(tbody.children).forEach(row => row.style.background = "");
          tr.style.background = "#eef2fb";
        });
        tbody.appendChild(tr);
      });
      if (selectedIndex >= 0 && selectedIndex < tbody.children.length) {
        tbody.children[selectedIndex].style.background = "#eef2fb";
      }
    }

    renderRows();
    if (selectedIndex >= 0) fillForm(selectedIndex);

    document.getElementById("cfg-new-user").addEventListener("click", () => {
      selectedIndex = -1;
      Array.from(tbody.children).forEach(row => row.style.background = "");
      fillForm(-1);
      hint.textContent = "Novo usuario";
    });

    document.getElementById("cfg-cancel").addEventListener("click", () => {
      if (selectedIndex >= 0) {
        fillForm(selectedIndex);
        if (tbody.children[selectedIndex]) tbody.children[selectedIndex].style.background = "#eef2fb";
      } else {
        fillForm(-1);
      }
    });

    document.getElementById("cfg-save").addEventListener("click", async () => {
      const previousUser = selectedIndex >= 0 ? users[selectedIndex].user : null;
      const u = {
        user: inputs.user.value.trim(),
        name: inputs.name.value.trim(),
        email: selectedIndex >= 0 && users[selectedIndex] ? (users[selectedIndex].email || "") : "",
        pass: inputs.pass.value.trim(),
        role: inputs.role.value,
      };
      if (!u.user || !u.name) {
        hint.textContent = "Usuario e Nome sao obrigatorios.";
        return;
      }
      const existingIndex = users.findIndex((item, idx) => item.user === u.user && idx !== selectedIndex);
      if (existingIndex !== -1) {
        hint.textContent = "Ja existe um usuario com este login.";
        return;
      }
      try {
        if (selectedIndex >= 0) {
          await apiFetch(`users/${encodeURIComponent(previousUser)}`, {
            method: "PUT",
            body: JSON.stringify({
              username: u.user,
              name: u.name,
              email: u.email,
              role: u.role,
              password: u.pass || "",
            }),
          });
        } else {
          if (!u.pass) {
            hint.textContent = "Informe uma senha para o novo usuario.";
            return;
          }
          await apiFetch("users", {
            method: "POST",
            body: JSON.stringify({
              username: u.user,
              name: u.name,
              email: u.email,
              role: u.role,
              password: u.pass,
            }),
          });
        }
      } catch (err) {
        hint.textContent = err.message || "Erro ao salvar usuario.";
        return;
      }

      if (previousUser && previousUser !== u.user && permissions[previousUser]) {
        permissions[u.user] = permissions[previousUser];
        delete permissions[previousUser];
        localStorage.setItem("printlab_permissions", JSON.stringify(permissions));
      }

      await refreshUsersFromApi();
      const updatedUsers = JSON.parse(localStorage.getItem("printlab_users") || "[]");
      users.length = 0;
      users.push(...updatedUsers);
      selectedIndex = users.findIndex(item => item.user === u.user);
      renderRows();
      fillForm(selectedIndex);
      hint.textContent = "Usuario salvo.";
      renderPermUserOptions(u.user);
      permUserSelect.value = u.user;
      renderPermChecks(u.user);
    });

    const prodTbody = prodTable.querySelector("#cfg-prod-body");
    const prodHint = document.getElementById("cfg-prod-hint");
    const prodInputs = {
      material: document.getElementById("cfg-prod-material"),
      descricao: document.getElementById("cfg-prod-descricao"),
      unidade: document.getElementById("cfg-prod-unidade"),
      preco: document.getElementById("cfg-prod-preco"),
    };

    function fillProdForm(idx) {
      const p = produtos[idx];
      if (!p) {
        prodInputs.material.value = "";
        prodInputs.descricao.value = "";
        prodInputs.unidade.value = "UNIDADE(S)";
        prodInputs.preco.value = "";
        prodHint.textContent = "";
        return;
      }
      prodInputs.material.value = p.material || "";
      prodInputs.descricao.value = p.descricao || "";
      const unidade = (p.unidade || "").toUpperCase();
      const unidadeOptions = Array.from(prodInputs.unidade.options || []).map(opt => opt.value);
      if (unidade && !unidadeOptions.includes(unidade)) {
        const opt = document.createElement("option");
        opt.value = unidade;
        opt.textContent = unidade;
        prodInputs.unidade.appendChild(opt);
      }
      prodInputs.unidade.value = unidade || "UNIDADE(S)";
      prodInputs.preco.value = numberToMoney(p.preco || 0);
      prodHint.textContent = "Editando produto " + (p.material || "");
    }

    function renderProdRows() {
      prodTbody.innerHTML = "";
      if (!produtos.length) {
        const tr = document.createElement("tr");
        tr.innerHTML = '<td colspan="4" style="color:#777;">Nenhum produto cadastrado.</td>';
        prodTbody.appendChild(tr);
        return;
      }
      produtos.forEach((p, idx) => {
        const tr = document.createElement("tr");
        tr.dataset.idx = idx;
        tr.style.cursor = "pointer";
        const material = (p.material || "").toUpperCase();
        const descricao = (p.descricao || "").toUpperCase();
        const unidade = (p.unidade || "").toUpperCase();
        tr.innerHTML = `
          <td>${material}</td>
          <td>${descricao}</td>
          <td>${unidade}</td>
          <td>${numberToMoney(p.preco || 0)}</td>
        `;
        tr.addEventListener("click", () => {
          selectedProdIndex = idx;
          fillProdForm(selectedProdIndex);
          Array.from(prodTbody.children).forEach(row => row.style.background = "");
          tr.style.background = "#eef2fb";
        });
        prodTbody.appendChild(tr);
      });
      if (selectedProdIndex >= 0 && selectedProdIndex < prodTbody.children.length) {
        prodTbody.children[selectedProdIndex].style.background = "#eef2fb";
      }
    }

    const impressaoMateriais = [
      "Sulfite 75 gramas",
      "Offset 90 gramas",
      "Offset 120 gramas",
      "Offset 150 gramas",
      "Offset 180 gramas",
      "Offset 230 gramas",
      "Couchê 120 gramas",
      "Couchê 150 gramas",
      "Couchê 180 gramas",
      "Couchê 250 gramas",
      "Couchê 300 gramas",
      "Sulfite Azul 75 gramas",
      "Reciclado 120 gramas",
      "Reciclado 230 gramas",
      "Aspen 230 gramas",
      "Linho 230 gramas",
      "Poliéster",
      "Transparência",
      "Transfer Laser",
      "Transfer Sublimático",
      "Adesivo Papel Fosco",
      "Adesivo Papel Brilho",
      "Adesivo Vinil Transparente",
      "Adesivo Vinil Branco"
    ];
    const impressaoCores = ["4x0", "1x0", "4x4", "1x1"];
    const impressaoTamanhos = ["A6", "A5", "A4", "A3"];
    const uvFlexMateriais = [
      "Adesivo vinil branco fosco",
      "Adesivo vinil branco brilho",
      "Adesivo vinil transparente",
      "Adesivo vinil metalizado prata",
      "Adesivo vinil metalizado dourado",
      "Adesivo vinil holográfico",
      "Policarbonato liso 0.12 mm",
      "Policarbonato liso 0.16 mm",
      "Policarbonato liso 0.25 mm",
      "Policarbonato liso 0.32 mm",
      "Policarbonato texturizado 0.12 mm",
      "Policarbonato texturizado 0.16 mm",
      "Policarbonato texturizado 0.25 mm",
      "Policarbonato texturizado 0.32 mm"
    ];
    const uvRigidaMateriais = [
      "P.S Branco 0.50 mm",
      "P.S Branco 1.00 mm",
      "P.S Branco 2.00 mm",
      "P.S Branco 3.00 mm",
      "PVC Branco 5.00 mm",
      "PVC Branco 10 mm",
      "PVC Branco 20 mm",
      "Acrílico Cristal 2 mm",
      "Acrílico Cristal 3 mm",
      "Plastionda 2 mm",
      "Plastionda 3 mm",
      "Plastionda 4 mm",
      "ACM 3 mm",
      "Papelão 3 mm",
      "Duplex 440 gramas"
    ];
    const uvCores = [
      "1x0 - Branco | Frente",
      "2x0 - Branco + Verniz | Frente",
      "1x1 - Branco | Frente x Verso",
      "2x2 - Branco + Verniz | Frente x Verso",
      "4x0 - CMYK | Frente",
      "5x0 - CMYK + Verniz | Frente",
      "0x1 - Branco | Verso",
      "0x4 - CMYK | Verso",
      "4x4 - CMYK | Frente x Verso",
      "5x5 - CMYK + Verniz | Frente x Verso",
      "5x0 - CMYK + Branco | Frente",
      "6x0 - CMYK + Branco + Verniz | Frente",
      "5x5 - CMYK + Branco | Frente x Verso",
      "6x6 - CMYK + Branco + Verniz | Frente x Verso",
      "0x5 - CMYK + Branco | Verso"
    ];
    const uvRigidaTipos = ["Placa", "Display", "Cubo", "Totem"];
    const servicosPadroes = {
      cartao: [
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto - laminação fosca",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto - laminação fosca",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - corte reto - laminação brilho",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - corte reto - laminação brilho",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado - laminação fosca",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado - laminação fosca",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x0 - canto arredondado - laminação brilho",
        "Couchê 300 gramas - 90 mm x 50 mm - 4x4 - canto arredondado - laminação brilho"
      ],
      flyer: [
        "Sulfite 75 gramas - A6 - 1x0 - refile",
        "Couchê 120 gramas - A6 - 1x0 - refile",
        "Couchê 150 gramas - A6 - 1x0 - refile",
        "Sulfite 75 gramas - A6 - 1x1 - refile",
        "Couchê 120 gramas - A6 - 1x1 - refile",
        "Couchê 150 gramas - A6 - 1x1 - refile",
        "Sulfite 75 gramas - A6 - 4x0 - refile",
        "Couchê 120 gramas - A6 - 4x0 - refile",
        "Couchê 150 gramas - A6 - 4x0 - refile",
        "Sulfite 75 gramas - A6 - 4x4 - refile",
        "Couchê 120 gramas - A6 - 4x4 - refile",
        "Couchê 150 gramas - A6 - 4x4 - refile",
        "Sulfite 75 gramas - A5 - 1x0 - refile",
        "Couchê 120 gramas - A5 - 1x0 - refile",
        "Couchê 150 gramas - A5 - 1x0 - refile",
        "Sulfite 75 gramas - A5 - 1x1 - refile",
        "Couchê 120 gramas - A5 - 1x1 - refile",
        "Couchê 150 gramas - A5 - 1x1 - refile",
        "Sulfite 75 gramas - A5 - 4x0 - refile",
        "Couchê 120 gramas - A5 - 4x0 - refile",
        "Couchê 150 gramas - A5 - 4x0 - refile",
        "Sulfite 75 gramas - A5 - 4x4 - refile",
        "Couchê 120 gramas - A5 - 4x4 - refile",
        "Couchê 150 gramas - A5 - 4x4 - refile",
        "Sulfite 75 gramas - A4 - 1x0 - refile",
        "Couchê 120 gramas - A4 - 1x0 - refile",
        "Couchê 150 gramas - A4 - 1x0 - refile",
        "Sulfite 75 gramas - A4 - 1x1 - refile",
        "Couchê 120 gramas - A4 - 1x1 - refile",
        "Couchê 150 gramas - A4 - 1x1 - refile",
        "Sulfite 75 gramas - A4 - 4x0 - refile",
        "Couchê 120 gramas - A4 - 4x0 - refile",
        "Couchê 150 gramas - A4 - 4x0 - refile",
        "Sulfite 75 gramas - A4 - 4x4 - refile",
        "Couchê 120 gramas - A4 - 4x4 - refile",
        "Couchê 150 gramas - A4 - 4x4 - refile"
      ],
      pastas: [
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha - laminação fosca",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - sem bolso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - sem bolso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - com bolso impresso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - com bolso impresso - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x0 - dobra - orelha - laminação brilho",
        "Couchê 300 gramas - 450 mm x 310 mm - 4x4 - dobra - orelha - laminação brilho"
      ],
      credencial: [
        "Couchê 150 gramas - 95 mm x 145 mm - 4x0 - sem cordão",
        "Couchê 150 gramas - 95 mm x 145 mm - 4x4 - sem cordão",
        "Couchê 150 gramas - 95 mm x 145 mm - 4x0 - com cordão",
        "Couchê 150 gramas - 95 mm x 145 mm - 4x4 - com cordão",
        "Offset 150 gramas - 95 mm x 145 mm - 4x0 - plastificado - sem cordão",
        "Offset 150 gramas - 95 mm x 145 mm - 4x4 - plastificado - sem cordão",
        "Offset 150 gramas - 95 mm x 145 mm - 4x0 - plastificado - com cordão",
        "Offset 150 gramas - 95 mm x 145 mm - 4x4 - plastificado - com cordão",
        "Couchê 300 gramas - 95 mm x 145 mm - 4x0 - sem cordão",
        "Couchê 300 gramas - 95 mm x 145 mm - 4x4 - sem cordão",
        "Couchê 300 gramas - 95 mm x 145 mm - 4x0 - com cordão",
        "Couchê 300 gramas - 95 mm x 145 mm - 4x4 - com cordão"
      ],
      diversos: [
        "Máscara - A4 - Sem cordão",
        "Máscara - A4 - Com cordão",
        "Máscara - A3 - Sem cordão",
        "Máscara - A3 - Com cordão",
        "Receituário B1"
      ]
    };
    const comunicacao = {
      tipo: [
        "Adesivo",
        "Película",
        "Lona",
        "Imã",
        "Lona Canvas",
        "Papel Fotográfico",
        "Papel Outdoor"
      ],
      adesivo: [
        "Adesivo Vinil Branco Fosco",
        "Adesivo Vinil Branco Brilho",
        "Adesivo Vinil Transparente",
        "Adesivo Vinil Perfurado",
        "Adesivo Vinil Eletrostático",
        "Adesivo Vinil Blackout Fosco",
        "Adesivo Vinil Blackout Brilho"
      ],
      pelicula: [
        "Película G30",
        "Película G20",
        "Película G5",
        "Película Espelhada Prata",
        "Película Espelhada"
      ],
      lona: [
        "Corte Reto",
        "Faixa",
        "Banner",
        "Solda na Imagem com Ilhós",
        "Quadro de Madeira"
      ],
      ima: [
        "0.40 mm",
        "0.80 mm",
        "Aplicado sob P.S 0.50 mm",
        "Aplicado sob P.S 1.00 mm",
        "Aplicado sob P.S 2.00 mm",
        "Aplicado sob P.S 3.00 mm",
        "Aplicado sob ACM 3.00 mm"
      ],
      aplicado: [
        "P.S Branco 0.50 mm",
        "P.S Branco 1.00 mm",
        "P.S Branco 2.00 mm",
        "P.S Branco 3.00 mm",
        "PVC Branco 5.00 mm",
        "PVC Branco 10 mm",
        "PVC Branco 20 mm",
        "Acrílico Cristal 2 mm",
        "Acrílico Cristal 3 mm",
        "Plastionda 2 mm",
        "Plastionda 3 mm",
        "Plastionda 4 mm",
        "ACM 3 mm",
        "Papelão 3 mm",
        "Duplex 440 gramas"
      ],
      instalacao: [
        "Sem instalação",
        "Criciúma",
        "Içara",
        "Balneário Rincão",
        "Forquilhinha",
        "Nova Veneza",
        "Siderópolis",
        "Cocal do Sul",
        "Morro da Fumaça",
        "Treviso",
        "Lauro Muller",
        "Morro Grande",
        "Meleiro",
        "Maracajá",
        "Araranguá",
        "Balneário Arroio do Silva",
        "Balneário Gaivota",
        "Sombrio",
        "Ermo",
        "Turvo",
        "Timbé do Sul",
        "Jacinto Machado",
        "Santa Rosa do Sul",
        "Passo de Torres",
        "São João do Sul",
        "Praia Grande",
        "Jaguaruna",
        "Sangão",
        "Treze de Maio",
        "Tubarão",
        "Pedras Grandes",
        "Capivari de Baixo",
        "Laguna",
        "Pescaria Brava",
        "Gravatal",
        "São Ludgero",
        "Orleans",
        "Imaruí",
        "Imbituba",
        "Armazém",
        "Braço do Norte",
        "Grão Pará",
        "Rio Fortuna",
        "São Martinho"
      ]
    };

    function addProdutoIfMissing(material, descricao, unidade = "un", preco = 0) {
      const exists = produtos.some(p =>
        (p.material || "").toLowerCase() === material.toLowerCase() &&
        (p.descricao || "").toLowerCase() === descricao.toLowerCase()
      );
      if (exists) return false;
      produtos.push({ material, descricao, unidade, preco });
      return true;
    }

    function seedProdutosImpressao() {
      let added = 0;
      impressaoMateriais.forEach(mat => {
        impressaoCores.forEach(cor => {
          impressaoTamanhos.forEach(tam => {
            const material = "Impressão";
            const descricao = `${mat} - ${cor} - ${tam}`;
            if (addProdutoIfMissing(material, descricao)) added += 1;
          });
        });
      });
      localStorage.setItem("printlab_produtos", JSON.stringify(produtos));
      selectedProdIndex = produtos.length ? 0 : -1;
      renderProdRows();
      fillProdForm(selectedProdIndex);
      prodHint.textContent = added ? `Adicionados ${added} produtos de impressao.` : "Nenhum novo produto adicionado.";
      refreshProdutosDatalist();
      renderFluxoProdutoOptions();
    }

    function seedProdutosUV() {
      let added = 0;
      uvFlexMateriais.forEach(mat => {
        uvCores.forEach(cor => {
          if (addProdutoIfMissing("Impressão UV - Flexível", `${mat} - ${cor}`)) added += 1;
        });
      });
      uvRigidaMateriais.forEach(mat => {
        uvRigidaTipos.forEach(tipo => {
          uvCores.forEach(cor => {
            if (addProdutoIfMissing("Impressão UV - Rígida", `${mat} - ${tipo} - ${cor}`)) added += 1;
          });
        });
      });
      localStorage.setItem("printlab_produtos", JSON.stringify(produtos));
      selectedProdIndex = produtos.length ? 0 : -1;
      renderProdRows();
      fillProdForm(selectedProdIndex);
      prodHint.textContent = added ? `Adicionados ${added} produtos de UV.` : "Nenhum novo produto adicionado.";
      refreshProdutosDatalist();
      renderFluxoProdutoOptions();
    }

    function seedProdutosServicos() {
      let added = 0;
      servicosPadroes.cartao.forEach(item => {
        if (addProdutoIfMissing("Serviço Padrão - Cartão de visita", item)) added += 1;
      });
      servicosPadroes.flyer.forEach(item => {
        if (addProdutoIfMissing("Serviço Padrão - Flyer", item)) added += 1;
      });
      servicosPadroes.pastas.forEach(item => {
        if (addProdutoIfMissing("Serviço Padrão - Pastas", item)) added += 1;
      });
      servicosPadroes.credencial.forEach(item => {
        if (addProdutoIfMissing("Serviço Padrão - Credencial", item)) added += 1;
      });
      servicosPadroes.diversos.forEach(item => {
        if (addProdutoIfMissing("Serviço Padrão - Diversos", item)) added += 1;
      });
      localStorage.setItem("printlab_produtos", JSON.stringify(produtos));
      selectedProdIndex = produtos.length ? 0 : -1;
      renderProdRows();
      fillProdForm(selectedProdIndex);
      prodHint.textContent = added ? `Adicionados ${added} serviços padrao.` : "Nenhum novo produto adicionado.";
      refreshProdutosDatalist();
    }

    function seedProdutosComunicacao() {
      let added = 0;
      comunicacao.tipo.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Tipo", item)) added += 1;
      });
      comunicacao.adesivo.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Adesivo", item)) added += 1;
      });
      comunicacao.pelicula.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Película", item)) added += 1;
      });
      comunicacao.lona.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Lona", item)) added += 1;
      });
      comunicacao.ima.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Imã", item)) added += 1;
      });
      comunicacao.aplicado.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Aplicado em", item)) added += 1;
      });
      comunicacao.instalacao.forEach(item => {
        if (addProdutoIfMissing("Comunicação Visual - Instalação", item)) added += 1;
      });
      localStorage.setItem("printlab_produtos", JSON.stringify(produtos));
      selectedProdIndex = produtos.length ? 0 : -1;
      renderProdRows();
      fillProdForm(selectedProdIndex);
      prodHint.textContent = added ? `Adicionados ${added} produtos de comunicação visual.` : "Nenhum novo produto adicionado.";
      refreshProdutosDatalist();
    }

    renderProdRows();
    if (selectedProdIndex >= 0) fillProdForm(selectedProdIndex);

    document.getElementById("cfg-new-prod").addEventListener("click", () => {
      selectedProdIndex = -1;
      Array.from(prodTbody.children).forEach(row => row.style.background = "");
      fillProdForm(-1);
      prodHint.textContent = "Novo produto";
    });
    const seedBtn = document.getElementById("cfg-prod-seed");
    if (seedBtn) {
      seedBtn.addEventListener("click", () => {
        seedProdutosImpressao();
      });
    }
    const seedBtnUv = document.getElementById("cfg-prod-seed-uv");
    if (seedBtnUv) {
      seedBtnUv.addEventListener("click", () => {
        seedProdutosUV();
      });
    }
    const seedBtnServ = document.getElementById("cfg-prod-seed-serv");
    if (seedBtnServ) {
      seedBtnServ.addEventListener("click", () => {
        seedProdutosServicos();
      });
    }
    const seedBtnCom = document.getElementById("cfg-prod-seed-com");
    if (seedBtnCom) {
      seedBtnCom.addEventListener("click", () => {
        seedProdutosComunicacao();
      });
    }

    document.getElementById("cfg-prod-cancel").addEventListener("click", () => {
      if (selectedProdIndex >= 0) {
        fillProdForm(selectedProdIndex);
        if (prodTbody.children[selectedProdIndex]) prodTbody.children[selectedProdIndex].style.background = "#eef2fb";
      } else {
        fillProdForm(-1);
      }
    });

    prodInputs.preco.addEventListener("input", () => {
      prodInputs.preco.value = prodInputs.preco.value.replace(/[^\d.,]/g, "");
    });

    document.getElementById("cfg-prod-save").addEventListener("click", () => {
      const p = {
        material: prodInputs.material.value.trim(),
        descricao: prodInputs.descricao.value.trim(),
        unidade: prodInputs.unidade.value.trim(),
        preco: moneyToNumber(prodInputs.preco.value),
      };
      if (!p.material) {
        prodHint.textContent = "Material e obrigatorio.";
        return;
      }
      const existingProdIndex = produtos.findIndex((item, idx) => (item.material || "").toLowerCase() === p.material.toLowerCase() && idx !== selectedProdIndex);
      if (existingProdIndex !== -1) {
        prodHint.textContent = "Ja existe um produto com este material.";
        return;
      }
      if (selectedProdIndex >= 0) {
        produtos[selectedProdIndex] = p;
      } else {
        produtos.push(p);
        selectedProdIndex = produtos.length - 1;
      }
      localStorage.setItem("printlab_produtos", JSON.stringify(produtos));
      renderProdRows();
      fillProdForm(selectedProdIndex);
      prodHint.textContent = "Produto salvo.";
      refreshProdutosDatalist();
    });
  }

  function renderUnderConstruction() {
    mainContent.innerHTML = `
      <div class="card" style="display:flex; justify-content:center; align-items:center;">
        <img src="static/pagina_em_construcao.jpg" alt="Em construcao" style="max-width:100%; height:auto;">
      </div>
    `;
  }

  function hasPermission(target) {
    const currentUser = localStorage.getItem("printlab_current_user");
    if (!currentUser) return false;
    if (currentUser === MASTER_USER.user) return true;
    const perms = JSON.parse(localStorage.getItem("printlab_permissions") || "{}");
    const allowed = perms[currentUser];
    if (Array.isArray(allowed)) {
      return allowed.includes(target);
    }
    // Se nao ha configuracao para o usuario, libera tudo por padrao
    return true;
  }

  function applyMenuPermissions() {
    const currentUser = localStorage.getItem("printlab_current_user");
    document.querySelectorAll('.side-btn[data-target]').forEach(btn => {
      const target = btn.dataset.target;
      const allowed = hasPermission(target);
      btn.disabled = !allowed;
      btn.style.opacity = allowed ? "1" : "0.45";
      btn.style.pointerEvents = allowed ? "auto" : "none";
      btn.title = allowed ? "" : "Sem permissao para " + target;
    });
  }

  document.querySelectorAll('.side-btn[data-target]').forEach(btn => {
    btn.addEventListener('click', () => {
      if (!hasPermission(btn.dataset.target)) {
        alert("Voce nao tem permissao para acessar esta area.");
        return;
      }
      if (btn.dataset.target === 'orcamento') {
        renderOrcamento();
      } else if (btn.dataset.target === 'pedido') {
        renderPedidosVenda();
      } else if (btn.dataset.target === 'ordem') {
        renderOrdensProducao();
      } else if (btn.dataset.target === 'chat') {
        renderChat();
      } else if (btn.dataset.target === 'financeiro') {
        renderFinanceiro();
      } else if (btn.dataset.target === 'agenda') {
        renderAgenda();
      } else if (btn.dataset.target === 'crm') {
        renderCRM();
      } else if (btn.dataset.target === 'config') {
        renderConfiguracoes();
      } else if (btn.dataset.target === 'dashboard') {
        renderDashboard();
      } else {
        renderUnderConstruction();
      }
    });
  });

  document.getElementById("pedido-close").addEventListener("click", closePedidoModal);
  document.getElementById("pedido-modal").addEventListener("click", (ev) => {
    if (ev.target === pedidoModal) closePedidoModal();
  });
  document.getElementById("whats-modal")?.addEventListener("click", (ev) => {
    if (ev.target === whatsModal) closeWhatsModal();
  });
  document.getElementById("whats-close")?.addEventListener("click", closeWhatsModal);
  document.getElementById("whats-copy")?.addEventListener("click", copyWhatsText);
  document.getElementById("pv-add-item").addEventListener("click", () => {
    pedidoItems.push({ produto: "", material: "", descricao: "", unidade: "", arquivo: "", quantidade: "1", unitario: "0,00", subtotal: 0, imagem: "" });
    renderPedidoItems();
  });
  document.getElementById("pv-whats").addEventListener("click", openWhatsModal);
  document.getElementById("pv-entrega").addEventListener("change", updateEntregaFields);
  document.getElementById("pv-preco-entrega").addEventListener("input", () => {
    const input = document.getElementById("pv-preco-entrega");
    input.value = input.value.replace(/[^\d.,]/g, "");
    updatePedidoTotal();
  });
  applyUppercaseInput(document.getElementById("pv-cliente"));
  applyUppercaseInput(document.getElementById("pv-contato"));
  applyUppercaseInput(document.getElementById("pv-endereco"));
  applyTelefoneMask(document.getElementById("pv-telefone"));
  document.getElementById("pv-forma").addEventListener("change", () => {
    updateCondicoesByForma();
  });
  document.getElementById("pv-busca-cliente").addEventListener("click", () => {
    const clientes = JSON.parse(localStorage.getItem("printlab_clients") || "[]");
    if (!clientes.length) {
      pedidoAlert.textContent = "Nenhum cliente cadastrado.";
      return;
    }
    openClienteSearchModal((cliente) => {
      fillClienteFields(cliente);
    });
  });
  document.getElementById("pv-save").addEventListener("click", savePedidoVenda);
  document.getElementById("pv-export").addEventListener("click", exportPedidoPdf);
  const pvOrcBuscar = document.getElementById("pv-orc-buscar");
  if (pvOrcBuscar) {
    pvOrcBuscar.addEventListener("click", () => {
      const ref = document.getElementById("pv-orc-ref").value.trim();
      const hint = document.getElementById("pv-orc-hint");
      const found = ref ? findBudgetByNumber(ref) : null;
      if (!found) {
        if (hint) hint.textContent = "Orçamento não encontrado.";
        return;
      }
      applyBudgetToPedido(found);
    });
  }
  const pvPedidoBuscar = document.getElementById("pv-pedido-buscar");
  if (pvPedidoBuscar) {
    pvPedidoBuscar.addEventListener("click", () => {
      const ref = document.getElementById("pv-pedido-ref").value.trim();
      const hint = document.getElementById("pv-pedido-hint");
      const found = ref ? findPedidoByNumber(ref) : null;
      if (!found) {
        if (hint) hint.textContent = "Pedido não encontrado ou não informado.";
        if (!ref) openPedidoRefModal();
        return;
      }
      applyPedidoToOrdem(found);
    });
  }
  const produtoFormClear = document.getElementById("produto-form-clear");
  if (produtoFormClear) {
    produtoFormClear.addEventListener("click", () => {
      // Limpa campos de texto e selects do popup
      document.querySelectorAll('#produto-form-modal input[type="text"], #produto-form-modal textarea').forEach(inp => inp.value = "");
      document.querySelectorAll('#produto-form-modal select').forEach(sel => sel.selectedIndex = 0);
      document.querySelectorAll('#produto-form-modal input[type="radio"], #produto-form-modal input[type="checkbox"]').forEach(inp => inp.checked = false);
    });
  }

  document.getElementById('btn-logout').addEventListener('click', async () => {
    const currentUser = localStorage.getItem("printlab_current_user");
    if (currentUser) {
      const online = new Set(JSON.parse(localStorage.getItem("printlab_online_users") || "[]"));
      online.delete(currentUser);
      localStorage.setItem("printlab_online_users", JSON.stringify(Array.from(online)));
      localStorage.removeItem("printlab_current_user");
    }
    try {
      await apiFetch("logout", { method: "POST" });
    } catch (err) {
      console.warn("Falha ao encerrar sessao", err);
    }
    appShell.style.display = 'none';
    loginScreen.style.display = 'flex';
    mainContent.innerHTML = '';
    window.scrollTo(0,0);
  });
  window.addEventListener('load', () => {
    tryRestoreSession();
  });
</script>
</body>
</html>



