// qdata.jsx — data + helpers for the QUOTES (Báo giá) module.
// Loaded after cdata.jsx (reuses TODAY, vnd, vndShort, daysBetween, it, pay, CUSTOMER_ADDR).

// Nhãn 2 bước dễ nhầm đã đổi cho rõ vai trò (key/logic GIỮ NGUYÊN):
// accepted = khách ĐÃ đồng ý, chờ hoàn tất (chuyển HĐ hoặc chốt trực tiếp) → "Khách đồng ý"
// won      = kết thúc THẮNG mà không lập hợp đồng (≤ ngưỡng)                → "Chốt không HĐ"
const QUOTE_STATUS = {
  draft:     { vi:'Nháp',          en:'Draft',             cls:'badge-neutral' },
  sent:      { vi:'Đã gửi',        en:'Sent',              cls:'badge-info' },
  accepted:  { vi:'Khách đồng ý',  en:'Agreed',            cls:'badge-success' },
  rejected:  { vi:'Từ chối',       en:'Declined',          cls:'badge-error' },
  expired:   { vi:'Hết hạn',       en:'Expired',           cls:'badge-warning' },
  converted: { vi:'Đã chuyển HĐ',  en:'Converted',         cls:'badge-success' },
  won:       { vi:'Chốt không HĐ', en:'Won (no contract)', cls:'badge-success' },
};

// Báo giá > ngưỡng này thì NÊN lập hợp đồng (khuyến nghị + cảnh báo, KHÔNG bắt buộc — luôn cho chốt trực tiếp).
const QUOTE_CONTRACT_THRESHOLD = 10000000;

// Chiều báo giá: 'sell' (gửi khách hàng) | 'buy' (nhận từ NCC). Mặc định sell — báo giá cũ không đổi.
function quoteDir(q){ return q && q.direction === 'buy' ? 'buy' : 'sell'; }

// Nhãn trạng thái theo chiều: báo giá MUA là bản nhận từ NCC nên vài bước đổi tên cho đúng nghĩa
// (key/logic GIỮ NGUYÊN — chỉ đổi chữ hiển thị; 'sent' không dùng cho chiều mua).
const QUOTE_STATUS_BUY_LABEL = {
  draft:     { vi:'Ghi nhận',        en:'Recorded' },
  accepted:  { vi:'Đồng ý mua',      en:'Approved' },
  converted: { vi:'Đã chuyển HĐ', en:'Converted (PO)' },
  won:       { vi:'Mua không HĐ',    en:'Bought (no contract)' },
  rejected:  { vi:'Không chọn',      en:'Not selected' },
};
function quoteStatusLabel(q, st, lang){
  const s = QUOTE_STATUS[st] || {};
  const o = quoteDir(q) === 'buy' ? QUOTE_STATUS_BUY_LABEL[st] : null;
  return (o && (o[lang] || o.vi)) || s[lang] || s.vi || st;
}

function addDays(dateStr, n){ const d = new Date(dateStr || TODAY); d.setDate(d.getDate() + n); return d.toISOString().slice(0, 10); }

/* ---- quotes ---- */
// q = { code, customer, rep, owner, issueDate, validDays, validUntil, status, discountPct,
//       notes, items:[it()], sentDate, sentTo:[], convertedTo }
const QUOTES = [
  { code:'BG-2026-045', customer:'VTIDC', rep:'LH-0013', owner:'Lê Thu Hà', issueDate:'2026-06-06', validDays:30, validUntil:'2026-07-06', status:'draft', discountPct:0,
    notes:'Mở rộng hạ tầng Cloud cho trung tâm dữ liệu.', sentDate:null, sentTo:[], convertedTo:null,
    items:[ it('Thuê hạ tầng Cloud & vận hành (gói mở rộng)', 'tháng', 12, 22000000, 8), it('Phí khởi tạo & migrate dữ liệu', 'lần', 1, 35000000, 8) ] },

  { code:'BG-2026-044', customer:'HQGTECH', rep:'LH-0011', owner:'Phạm Quốc Bảo', issueDate:'2026-06-04', validDays:30, validUntil:'2026-07-04', status:'sent', discountPct:5,
    notes:'Nâng cấp hệ thống quản lý vận hành theo trao đổi tại buổi họp 04/06.', sentDate:'2026-06-04', sentTo:['kien.do@hqg.vn'], convertedTo:null,
    items:[ it('Nâng cấp phần mềm quản lý vận hành (SaaS)', 'năm', 1, 168000000, 8), it('Tùy biến quy trình & tích hợp', 'gói', 1, 48000000, 8) ] },

  { code:'BG-2026-043', customer:'SEMITEC', rep:'LH-0002', owner:'Lê Thu Hà', issueDate:'2026-06-05', validDays:30, validUntil:'2026-07-05', status:'draft', discountPct:0,
    notes:'Gói vận hành hệ thống quản lý linh kiện năm 2026.', sentDate:null, sentTo:[], convertedTo:null,
    items:[ it('Dịch vụ vận hành hệ thống quản lý linh kiện', 'tháng', 12, 26000000, 8) ] },

  { code:'BG-2026-042', customer:'KYANON', rep:'LH-0006', owner:'Trần Minh Quân', issueDate:'2026-05-20', validDays:30, validUntil:'2026-06-19', status:'accepted', discountPct:0,
    notes:'Khách đã xác nhận chấp nhận báo giá qua email 25/05.', sentDate:'2026-05-20', sentTo:['mai.le@kyanon.digital'], convertedTo:null,
    items:[ it('Tổng đài Cloud VoIP — 50 máy nhánh', 'tháng', 6, 9000000, 8), it('Phí khởi tạo & cấu hình', 'lần', 1, 12000000, 8) ] },

  { code:'BG-2026-041', customer:'TSD', rep:'LH-0004', owner:'Trần Minh Quân', issueDate:'2026-06-01', validDays:30, validUntil:'2026-07-01', status:'sent', discountPct:0,
    notes:'Triển khai tổng đài Cloud VoIP cho 30 máy nhánh.', sentDate:'2026-06-01', sentTo:['chau.tran@tsd.vn'], convertedTo:null,
    items:[ it('Tổng đài Cloud VoIP — 30 máy nhánh (gói triển khai)', 'gói', 1, 80000000, 8) ] },

  { code:'BG-2026-040', customer:'NGOCMINH', rep:'LH-0008', owner:'Phạm Quốc Bảo', issueDate:'2026-04-20', validDays:30, validUntil:'2026-05-20', status:'sent', discountPct:0,
    notes:'Gia hạn dịch vụ PC Health Check — chưa nhận phản hồi.', sentDate:'2026-04-20', sentTo:['duc.pham@ngocminh.vn'], convertedTo:null,
    items:[ it('PC Health Check Annual — 80 thiết bị', 'năm', 1, 96000000, 8) ] },

  { code:'BG-2026-039', customer:'KIZUNA', rep:'LH-0001', owner:'Lê Thu Hà', issueDate:'2026-05-28', validDays:30, validUntil:'2026-06-27', status:'sent', discountPct:5,
    notes:'Số hóa quy trình KCN giai đoạn 1 theo biên bản khảo sát 04/06.', sentDate:'2026-05-28', sentTo:['long.nguyen@kizuna.vn'], convertedTo:null,
    items:[ it('Giải pháp số hóa quy trình AppSheet', 'gói', 1, 260000000, 8), it('Đào tạo & chuyển giao vận hành', 'gói', 1, 60000000, 8) ] },

  { code:'BG-2026-038', customer:'DASSVN', rep:'LH-0003', owner:'Lê Thu Hà', issueDate:'2026-04-10', validDays:30, validUntil:'2026-05-10', status:'converted', discountPct:0,
    notes:'Đã chuyển thành hợp đồng HD-2026-007.', sentDate:'2026-04-10', sentTo:['jiwon.park@dass.co.kr'], convertedTo:'HD-2026-007',
    items:[ it('Hệ thống quản lý logistics — License', 'gói', 1, 220000000, 8), it('Phần cứng đầu đọc & thiết bị', 'bộ', 10, 6500000, 10), it('Triển khai tại hiện trường', 'gói', 1, 60000000, 8) ] },

  { code:'BG-2026-037', customer:'AIPOWER', rep:'LH-0010', owner:'Trần Minh Quân', issueDate:'2026-04-25', validDays:30, validUntil:'2026-05-25', status:'rejected', discountPct:0,
    notes:'Khách chọn phương án khác — ngân sách chưa phù hợp.', sentDate:'2026-04-25', sentTo:['anh.vu@aipower.vn'], convertedTo:null,
    items:[ it('Hợp tác phát triển module AI — Giai đoạn 1', 'giai đoạn', 1, 70000000, 8) ] },
];

function quoteTotals(q){
  let sub = 0;
  (q.items || []).forEach(i => { sub += i.qty * i.price; });
  const discPct = +q.discountPct || 0;
  const discount = sub * discPct / 100;
  let vat = 0;
  (q.items || []).forEach(i => { const line = i.qty * i.price; vat += line * (1 - discPct / 100) * (i.vat / 100); });
  return { sub, discPct, discount, afterDisc:sub - discount, vat, total:sub - discount + vat };
}

function quoteStatus(q){
  // Báo giá MUA không có bước 'sent' → hết hiệu lực tính ngay từ bước Ghi nhận (quá hạn NCC chào).
  if (q.direction === 'buy' && q.status === 'draft' && q.validUntil && daysBetween(TODAY, q.validUntil) < 0) return 'expired';
  if (['draft', 'accepted', 'rejected', 'converted', 'won'].includes(q.status)) return q.status;
  if (q.status === 'sent' && q.validUntil && daysBetween(TODAY, q.validUntil) < 0) return 'expired';
  return q.status;
}
// một báo giá coi như “đã chốt” (thắng) khi đã chấp nhận/chuyển HĐ/chốt trực tiếp
function quoteWon(q){ return ['accepted', 'converted', 'won'].includes(quoteStatus(q)); }
// có NÊN lập hợp đồng không (giá trị > ngưỡng — chỉ để khuyến nghị/cảnh báo, không chặn)
function quoteNeedsContract(q){ return quoteTotals(q).total > QUOTE_CONTRACT_THRESHOLD; }

// quotes that are sent and within `days` of expiring (and not yet expired)
function quoteExpiringSoon(q, days){
  if (quoteStatus(q) !== 'sent' || !q.validUntil) return false;
  const d = daysBetween(TODAY, q.validUntil);
  return d >= 0 && d <= (days || 7);
}

// Lịch sử theo dõi báo giá — 1 sự kiện. type: create|send|status|note|convert.
function qEvt(type, note, by){ return { date:TODAY, type, note:note || '', by:by || '' }; }
// Trả về quote với 1 sự kiện được thêm vào history (mới nhất ở cuối mảng).
function qWithHist(q, evt){ return { ...q, history:[...(q.history || []), evt] }; }

Object.assign(window, {
  QUOTE_STATUS, QUOTES, QUOTE_CONTRACT_THRESHOLD, addDays, quoteTotals, quoteStatus,
  quoteExpiringSoon, quoteWon, quoteNeedsContract, qEvt, qWithHist,
  quoteDir, quoteStatusLabel,
});
