// data/fleet.js — 羚牛 Hydrogen Fleet · Asset-management dataset
// Switched from driver-centric to asset-centric model per business spec.
// Vehicles relate to: 业务部门 / 业务负责人 / 客户 / 所属公司 / 租赁公司
// Driver field intentionally removed.
(function(){

// ── Companies & departments ──────────────────────────────
const COMPANIES = {
  own: ["浙江羚牛氢能科技有限公司", "嘉兴羚牛新能源运营公司"],
  lease: ["JXLN-23 浙F氢能", "JXGW-G 浙F氢能", "LNZLHT 嘉兴港区"],
};

const DEPARTMENTS = [
  { id: "biz1", name: "业务一部", lead: "高伟",   color: "#1F8B4C" },
  { id: "biz2", name: "业务二部", lead: "陈高伟", color: "#2E8C8C" },
  { id: "biz3", name: "业务三部", lead: "尚建华", color: "#7A8C2E" },
  { id: "biz4", name: "业务四部", lead: "刘念念", color: "#C97A3D" },
  { id: "biz5", name: "业务五部", lead: "周志强", color: "#7A4FB4" },
  { id: "biz6", name: "业务六部", lead: "金可鹏", color: "#B45F8A" },
  { id: "ops",  name: "运营部",   lead: "张兰",   color: "#5C6E7C" },
];

const CUSTOMERS = [
  "嘉兴公司自营", "嘉兴氢能业务一部", "欧宝软件",
  "汇通运营公司", "嘉兴港区二部", "嘉兴县嘉一部",
  "午潮停车场", "—",
];

const PARKINGS = [
  "平湖停车场", "平湖停车场异常", "嘉兴公司自营", "欧宝停车场",
  "汇通停车场", "嘉兴港区停车场", "午潮码头停车场", "云洋停车场",
];

const CITIES = [
  "浙江省·嘉兴市·平湖", "浙江省·嘉兴市", "浙江省·嘉兴市·港区",
  "浙江省·嘉兴市·南湖", "广东省·云浮市", "浙江省·杭州市·萧山",
];

// VIN/车架号 prefix patterns from screenshot: LA9HE6.. / LA9G6.. / LJRC1..
const VIN_PREFIXES = ["LA9HE6F2N1A", "LA9G6E7L4N1B", "LJRC14A22NA0", "LA9HE6F8N1C"];

// ── Asset/operation status enums ──────────────────────────
// asset:  in_stock(在库) | leasing(租赁中) | abnormal(异常)
// own:    self(自有) | lease(外租)
// op:     operating(运营中) | suspended(停运) | maintenance(待整备)
// gps:    online(在线) | offline(离线)
// grade:  A | B | C
// status (legacy): ok | warn | danger | idle  (kept for map color coding)

// ── Helper: deterministic pseudo-random ───────────────────
const seed = (n) => { let x = (n*9301+49297)%233280; return () => (x = (x*9301+49297)%233280) / 233280; };

// ── Build vehicles ────────────────────────────────────────
// Start with the 12 mapped vehicles (preserve x/y for the map),
// enrich with business fields. Then add 40 more (no map coords).

const _mapped = [
  // Real plate numbers from the data screenshot · 浙F prefix
  // Coordinates positioned within Jiaxing Zhapu Port viewport (1240×800, sea below y=620)
  { id: "浙F03980F", x: 320, y: 180, h: 320, status: "ok",     speed: 56, soc: 78, src: "B" },
  { id: "浙F03311F", x: 460, y: 280, h: 60,  status: "warn",   speed: 0,  soc: 24, src: "T" },
  { id: "浙F03000F", x: 600, y: 240, h: 110, status: "ok",     speed: 78, soc: 31, src: "B" },
  { id: "浙FK800F",  x: 760, y: 290, h: 200, status: "ok",     speed: 64, soc: 82, src: "T" },
  { id: "浙FK808F",  x: 880, y: 410, h: 280, status: "ok",     speed: 51, soc: 47, src: "B" },
  { id: "浙F07918F", x: 240, y: 540, h: 30,  status: "idle",   speed: 0,  soc: 96, src: "T" },
  { id: "浙F01505F", x: 600, y: 470, h: 160, status: "ok",     speed: 44, soc: 55, src: "B" },
  { id: "浙F30778F", x: 540, y: 380, h: 240, status: "ok",     speed: 38, soc: 71, src: "T" },
  { id: "浙F39086F", x: 1000, y: 360, h: 90, status: "danger", speed: 0,  soc: 9,  src: "B" },
  { id: "浙F02618F", x: 700, y: 540, h: 350, status: "ok",     speed: 42, soc: 64, src: "T" },
  { id: "浙F09860F", x: 960, y: 540, h: 70,  status: "warn",   speed: 0,  soc: 18, src: "B" },
  { id: "浙F02399F", x: 820, y: 470, h: 190, status: "ok",     speed: 48, soc: 88, src: "J" },
];

// Additional 40 vehicles — list-only, no map coords
const _extra = [
  "浙F08991F","浙F05969F","浙F07179F","浙F08278F","浙F02002F","浙F01689F",
  "浙F00598F","浙F02608F","浙F08638F","浙F00278F","浙F02289F","浙F06196F",
  "浙F00885F","浙F08889F","浙F03127F","浙F04421F","浙F05538F","浙F06693F",
  "浙F07412F","浙F08810F","浙F09125F","浙F10232F","浙F11456F","浙F12674F",
  "浙F13891F","浙F14037F","浙F15268F","浙F16495F","浙F17712F","浙F18934F",
  "浙F19156F","浙F20389F","浙F21516F","浙F22748F","浙F23973F","浙F24196F",
  "浙F25425F","浙F26658F","浙F27873F","浙F28095F",
].map(id => ({ id, x: null, y: null, h: 0, status: "ok", speed: 0, soc: 0, src: "T" }));

// ── Enrichment ────────────────────────────────────────────
const _enrich = (v, i) => {
  const r = seed(i + 1);
  const isLeased = r() < 0.55;          // 55% 外租
  const dept = DEPARTMENTS[Math.floor(r() * 5)];
  const company = isLeased ? COMPANIES.lease[Math.floor(r() * 3)] : COMPANIES.own[Math.floor(r() * 2)];
  const ownCompany = COMPANIES.own[Math.floor(r() * 2)];

  // Asset status correlates with vehicle status
  let asset, op, gps;
  if (v.status === "danger") { asset = "abnormal"; op = "suspended"; gps = "offline"; }
  else if (v.status === "idle") { asset = "in_stock"; op = "maintenance"; gps = r() < 0.4 ? "online" : "offline"; }
  else if (isLeased) { asset = "leasing"; op = "operating"; gps = v.status === "warn" ? "offline" : "online"; }
  else { asset = "in_stock"; op = r() < 0.4 ? "maintenance" : "operating"; gps = "online"; }

  // Status duration in days
  const statusDays = Math.floor(r() * 120) + 1;

  // Mileage 
  const totalKm = Math.floor(r() * 80000) + 12000;
  const lastMaintKm = totalKm - Math.floor(r() * 8000) - 1000;
  const nextMaintKm = lastMaintKm + 10000;
  const kmToMaint = nextMaintKm - totalKm;

  // Last maintenance date (days ago)
  const lastMaintDays = Math.floor(r() * 90) + 1;

  // Grade
  const grade = ["A","B","B","C"][Math.floor(r()*4)];

  // VIN
  const vin = VIN_PREFIXES[Math.floor(r() * VIN_PREFIXES.length)] + String(1000 + Math.floor(r()*9000));
  const fleetCode = (i < 12 && r() < 0.3) ? (Math.floor(r()*99)+10) + "Q" : null;

  // Operating city
  const city = CITIES[Math.floor(r() * CITIES.length)];

  // Customer (only if leased)
  const customer = asset === "leasing" ? CUSTOMERS[Math.floor(r() * 6)] : (asset === "in_stock" ? "—" : CUSTOMERS[Math.floor(r() * 6)]);

  // Parking
  const parking = PARKINGS[Math.floor(r() * PARKINGS.length)];

  // Contract
  const hasContract = asset === "leasing" || (asset === "abnormal" && r() < 0.5);
  const contractNo = hasContract ? "JX-" + dept.id.toUpperCase() + "-2024-" + String(2000 + i) : null;
  const handoverKm = hasContract ? Math.floor(r() * 3000) + 200 : null;
  const returnKm = (asset === "in_stock" && hasContract) ? handoverKm + Math.floor(r()*40000) + 5000 : null;

  // Hydrogen pressure (MPa) and motor temp
  const h2 = v.status === "danger" ? 0.8 : (v.soc / 100 * 5.6 + 0.2).toFixed(1);
  const motorTemp = v.status === "danger" ? 102 : 58 + Math.floor(r()*15);

  // ── Brand & model — 真实国内氢能车型样本 ──
  const MODELS = [
    { brand: "上汽大通",  model: "MIFA-H 氢燃料 MPV" },
    { brand: "上汽大通",  model: "EUNIQ 7 氢电版" },
    { brand: "现代",      model: "NEXO" },
    { brand: "丰田",      model: "MIRAI 第二代" },
    { brand: "格罗夫",    model: "格罗夫氢能 SUV" },
    { brand: "海马汽车",  model: "7X-H" },
    { brand: "红旗",      model: "H5 FCV" },
    { brand: "长安深蓝",  model: "SL03 氢燃料版" },
    { brand: "飞驰科技",  model: "FCB80 氢燃料客车" },
    { brand: "宇通客车",  model: "ZK6105FCEVG3" },
  ];
  const m = MODELS[Math.floor(r() * MODELS.length)];

  // ── Integration / 对接情况 ──
  // src: T = TBOX(GB/T 32960), J = JT808/1078, B = both
  // 状态：online (recent) / offline (had data, now stale) / not_connected (从未对接)
  // 5% 完全未对接（重点标记） · 12% TBOX 断流 · 8% JT 断流
  const integFlag = r();
  let gbStatus, jtStatus;
  if (i >= 12 && integFlag < 0.05) {
    // 5% 全部未对接（重点标记）
    gbStatus = "not_connected";
    jtStatus = "not_connected";
  } else {
    if (v.src === "T" || v.src === "B") {
      gbStatus = (r() < 0.12) ? "offline" : "online";
    } else {
      gbStatus = (r() < 0.30) ? "offline" : "not_connected";
    }
    if (v.src === "J" || v.src === "B") {
      jtStatus = (r() < 0.08) ? "offline" : "online";
    } else {
      jtStatus = (r() < 0.20) ? "offline" : "not_connected";
    }
  }

  // 时间戳生成
  const now = Date.now();
  const minute = 60 * 1000, hour = 60 * minute, day = 24 * hour;
  const tsFor = (st, baseSeed) => {
    if (st === "not_connected") return null;
    if (st === "online") return now - Math.floor(baseSeed * 5 * minute) - 2000; // 2s ~ 5min
    // offline
    return now - Math.floor(baseSeed * 7 * day) - 30 * minute; // 30min ~ 7d ago
  };
  const gbLastSeen = tsFor(gbStatus, r());
  const jtLastSeen = tsFor(jtStatus, r());

  // 接入时间（首次对接日期，6 个月内随机）
  const onboardDays = Math.floor(r() * 180) + 7;
  const onboardAt = now - onboardDays * day;

  return {
    ...v,
    plate: v.id,
    vin, fleetCode,
    city, parking,
    asset, own: isLeased ? "lease" : "self", op, gps, grade, statusDays,
    dept: dept.id, deptName: dept.name, deptLead: dept.lead, deptColor: dept.color,
    customer,
    company, ownCompany,
    contractNo, handoverKm, returnKm,
    totalKm, lastMaintKm, nextMaintKm, kmToMaint, lastMaintDays,
    h2, motorTemp,
    // Hydrogen-specific
    h2Pressure: parseFloat(h2),
    range: Math.round(v.soc * 6.2),
    // Brand / model
    brand: m.brand, model: m.model,
    // Integration / 对接情况
    gbStatus, gbLastSeen,
    jtStatus, jtLastSeen,
    onboardAt,
  };
};

// ── Build VEHICLES ────────────────────────────────────────
// 优先使用 vehicles-real.js 提供的 1004 辆真实车辆数据；不存在则回退到合成数据。
let VEHICLES;
if (window.RAW_VEHICLES && window.RAW_VEHICLES.length) {
  // 从 xlsx 抽取的 1004 辆真实数据
  // 前 12 辆叠加乍浦港地图坐标，让总览地图保持原本的演示态
  const RAW = window.RAW_VEHICLES;
  const MAP_OVERLAY = [
    { x: 320, y: 180, h: 320, status: "ok",     speed: 56, soc: 78 },
    { x: 460, y: 280, h: 60,  status: "warn",   speed: 0,  soc: 24 },
    { x: 600, y: 240, h: 110, status: "ok",     speed: 78, soc: 31 },
    { x: 760, y: 290, h: 200, status: "ok",     speed: 64, soc: 82 },
    { x: 880, y: 410, h: 280, status: "ok",     speed: 51, soc: 47 },
    { x: 240, y: 540, h: 30,  status: "idle",   speed: 0,  soc: 96 },
    { x: 600, y: 470, h: 160, status: "ok",     speed: 44, soc: 55 },
    { x: 540, y: 380, h: 240, status: "ok",     speed: 38, soc: 71 },
    { x: 1000,y: 360, h: 90,  status: "danger", speed: 0,  soc: 9  },
    { x: 700, y: 540, h: 350, status: "ok",     speed: 42, soc: 64 },
    { x: 960, y: 540, h: 70,  status: "warn",   speed: 0,  soc: 18 },
    { x: 820, y: 470, h: 190, status: "ok",     speed: 48, soc: 88 },
  ];

  VEHICLES = RAW.map((v, i) => {
    const overlay = i < MAP_OVERLAY.length ? MAP_OVERLAY[i] : { x:null, y:null, h:0, status:"ok", speed:0, soc:0 };
    const dept = DEPARTMENTS.find(d => d.id === v.dept) || DEPARTMENTS[DEPARTMENTS.length-1];
    // 派生氢电指标（xlsx 没有这些字段）
    const soc = overlay.soc || ((i * 17) % 90 + 10);
    const h2 = overlay.status === "danger" ? 0.8 : +(soc / 100 * 5.6 + 0.2).toFixed(1);
    const motorTemp = overlay.status === "danger" ? 102 : 58 + (i % 15);
    const totalKm = 12000 + ((i * 1331) % 80000);
    const lastMaintKm = totalKm - 1000 - ((i * 379) % 8000);
    const nextMaintKm = lastMaintKm + 10000;
    const kmToMaint = nextMaintKm - totalKm;
    const lastMaintDays = 1 + ((i * 41) % 90);
    return {
      ...v,
      // overlay map fields
      x: overlay.x, y: overlay.y, h: overlay.h,
      status: overlay.status,           // for map color (ok/warn/danger/idle)
      speed: overlay.speed, soc,
      // department display fields
      deptName: dept.name, deptLead: dept.lead, deptColor: dept.color,
      // hydrogen-electric derived
      h2, h2Pressure: parseFloat(h2),
      range: Math.round(soc * 6.2),
      motorTemp,
      totalKm, lastMaintKm, nextMaintKm, kmToMaint, lastMaintDays,
      // legacy/compat
      fleetCode: null,
    };
  });
} else {
  // Fallback: 合成数据
  VEHICLES = [..._mapped, ..._extra].map(_enrich);
}

// ── Aggregations for filters ──────────────────────────────
const COUNTS = {
  all: VEHICLES.length,
  // Asset status
  inStock:  VEHICLES.filter(v => v.asset === "in_stock").length,
  leasing:  VEHICLES.filter(v => v.asset === "leasing").length,
  abnormal: VEHICLES.filter(v => v.asset === "abnormal").length,
  // Ownership
  self:  VEHICLES.filter(v => v.own === "self").length,
  lease: VEHICLES.filter(v => v.own === "lease").length,
  // Operation
  operating:   VEHICLES.filter(v => v.op === "operating").length,
  suspended:   VEHICLES.filter(v => v.op === "suspended").length,
  maintenance: VEHICLES.filter(v => v.op === "maintenance").length,
  // GPS
  online:  VEHICLES.filter(v => v.gps === "online").length,
  offline: VEHICLES.filter(v => v.gps === "offline").length,
  // Departments
  byDept: DEPARTMENTS.reduce((acc, d) => {
    acc[d.id] = VEHICLES.filter(v => v.dept === d.id).length;
    return acc;
  }, {}),
  // Integration / 数据接入
  gbOnline:    VEHICLES.filter(v => v.gbStatus === "online").length,
  gbOffline:   VEHICLES.filter(v => v.gbStatus === "offline").length,
  gbNotConn:   VEHICLES.filter(v => v.gbStatus === "not_connected").length,
  jtOnline:    VEHICLES.filter(v => v.jtStatus === "online").length,
  jtOffline:   VEHICLES.filter(v => v.jtStatus === "offline").length,
  jtNotConn:   VEHICLES.filter(v => v.jtStatus === "not_connected").length,
  // 完全未对接（重点标记）
  bothNone:    VEHICLES.filter(v => v.gbStatus === "not_connected" && v.jtStatus === "not_connected").length,
  // 任一在线
  anyOnline:   VEHICLES.filter(v => v.gbStatus === "online" || v.jtStatus === "online").length,
};

// ── User roles for permission demo ────────────────────────
const ROLES = [
  { id: "admin",    name: "总管理员",       scope: "all",     desc: "可见所有车辆 · 所有部门" },
  { id: "biz1_lead",name: "业务一部·负责人", scope: "dept",    deptId: "biz1", desc: "仅可见业务一部车辆" },
  { id: "biz2_lead",name: "业务二部·负责人", scope: "dept",    deptId: "biz2", desc: "仅可见业务二部车辆" },
  { id: "ops",      name: "运营岗",         scope: "ops",     desc: "可见所有车辆 · 仅运维操作" },
  { id: "finance",  name: "财务岗",         scope: "finance", desc: "可见合同/资产 · 隐藏实时车况" },
];

// expose
Object.assign(window, {
  VEHICLES, DEPARTMENTS, COMPANIES, CUSTOMERS, PARKINGS, CITIES, COUNTS, ROLES,
});
})();
