/* screens-history-import.jsx — /admin/history-import
 * Nhập dữ liệu đơn hàng lịch sử để huấn luyện engine dự báo.
 * 4 cột bắt buộc: warehouseCode, customerCode, date, orderCount.
 */

// ============================================================
// Sample preview rows (generated lazily per file name)
// ============================================================
function hiSamplePreview() {
  const wcodes = ['VN-HN-01','VN-HN-01','VN-HCM-01','VN-HN-01','VN-HCM-01','VN-HN-01','VN-HN-01','VN-HCM-01'];
  const ccodes = ['LOR','UNI','VNM','LOR','MBL','UNI','INF','LOR'];
  const newQty = [1180, 940, 1320, 1240, 760, 980, 540, 1300];
  const oldQty = [null, null, null, 1180, 760, 980, null, 1280];
  const dates  = ['2026-04-12','2026-04-12','2026-04-12','2026-04-13','2026-04-13','2026-04-14','2026-04-14','2026-04-15'];
  const rows = wcodes.map((w, i) => {
    const status = oldQty[i] == null ? 'new'
                 : oldQty[i] === newQty[i] ? 'unchanged'
                 : 'update';
    return {
      warehouseCode: w, customerCode: ccodes[i],
      date: dates[i], oldQty: oldQty[i], newQty: newQty[i],
      delta: oldQty[i] == null ? newQty[i] : newQty[i] - oldQty[i],
      status,
    };
  });
  // Add an unchanged dup
  rows.push({ warehouseCode: 'VN-HN-01', customerCode: 'ADI', date: '2026-04-15', oldQty: 410, newQty: 410, delta: 0, status: 'unchanged' });
  return {
    fileName: 'orders-history-2026-04.xlsx',
    fileHash: 'sha256:9bd2…f047',
    previewId: 'hist-prv-3e9a',
    rows,
    errors: [
      { line: 17, col: 'date',       message: 'Không đúng định dạng YYYY-MM-DD (giá trị: 12/04/2026)' },
      { line: 41, col: 'orderCount', message: 'Giá trị âm không hợp lệ (-30)' },
    ],
    coverage: {
      dateMin: '2026-04-01', dateMax: '2026-04-30',
      warehouses: 2, customers: 6, days: 30,
    },
  };
}

// ============================================================
// Screen
// ============================================================
function HistoryImportScreen({ addToast, navigate }) {
  const [step, setStep] = React.useState(1);
  const [method, setMethod] = React.useState('file'); // 'file' | 'form'
  const [file, setFile] = React.useState(null);
  const [parsing, setParsing] = React.useState(false);
  const [committing, setCommitting] = React.useState(false);
  const [filterStatus, setFilterStatus] = React.useState('all');
  const [note, setNote] = React.useState('Đối soát đơn tháng 4/2026 · nguồn TMS');
  const [conflict, setConflict] = React.useState('update'); // update | keep | error
  const { isMobile, vw } = useViewport();
  const stacked = vw < 980;

  const preview = React.useMemo(() => hiSamplePreview(), []);
  const rows = filterStatus === 'all' ? preview.rows : preview.rows.filter(r => r.status === filterStatus);
  const totals = {
    rows: preview.rows.length,
    newC: preview.rows.filter(r => r.status === 'new').length,
    upd:  preview.rows.filter(r => r.status === 'update').length,
    same: preview.rows.filter(r => r.status === 'unchanged').length,
    delta: preview.rows.reduce((s, r) => s + r.delta, 0),
    errors: preview.errors.length,
  };

  function startParse(name) {
    setFile({ name, size: 184_312 });
    setParsing(true);
    setTimeout(() => { setParsing(false); setStep(2); }, 900);
  }
  function commit() {
    setCommitting(true);
    setTimeout(() => {
      setCommitting(false); setStep(3);
      addToast({ kind: 'FULFILLED', title: 'Đã nhập dữ liệu lịch sử',
        body: (totals.newC + totals.upd) + ' dòng đã ghi vào kho dữ liệu lịch sử.' });
    }, 900);
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <PageHeader
        breadcrumb={['Quản trị','Dữ liệu lịch sử']}
        title="Nhập dữ liệu lịch sử"
        subtitle="Nhập đơn hàng đã giao theo khách hàng × ngày × kho. Engine dự báo sẽ học từ dữ liệu này."
        actions={
          <>
            {!isMobile && <Button variant="outline" icon="download">Tải mẫu</Button>}
            <Button variant="outline" icon="history" onClick={() => addToast({ kind: 'INFO', title: 'Lịch sử nhập', body: '12 đợt đã nhập trong 30 ngày qua.' })}>
              {isMobile ? 'Đợt cũ' : 'Đợt nhập trước'}
            </Button>
          </>
        }
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: isMobile ? 14 : 20 }}>
        <Stepper step={step}/>

        {step === 1 && (
          <>
            <div style={{ display: 'flex', gap: 8, marginTop: 16, flexWrap: 'wrap' }}>
              <MethodChip active={method === 'file'} onClick={() => setMethod('file')} icon="upload" label="Tải tệp"     sub="CSV / XLSX · nhiều tháng"/>
              <MethodChip active={method === 'form'} onClick={() => setMethod('form')} icon="layers" label="Nhập tay"    sub="Khách hàng × ngày"/>
            </div>

            {method === 'file' && (
              <div style={{ display: 'grid', gridTemplateColumns: stacked ? '1fr' : '2fr 1fr', gap: isMobile ? 12 : 16, marginTop: 16 }}>
                <Card title="1 · Tải tệp dữ liệu lịch sử" subtitle="CSV hoặc XLSX · tối đa 20 MB · dòng tiêu đề: warehouseCode, customerCode, date, orderCount">
                  <div onClick={() => !parsing && startParse('orders-history-2026-04.xlsx')} style={{
                    border: '2px dashed ' + (parsing ? 'var(--bx-primary)' : 'var(--bx-border)'),
                    borderRadius: 12, padding: '48px 20px', textAlign: 'center',
                    background: parsing ? '#eef2ff' : 'var(--bx-surface-2)', cursor: parsing ? 'wait' : 'pointer',
                    transition: 'background 150ms',
                  }}>
                    <div style={{ width: 52, height: 52, margin: '0 auto', borderRadius: 9999, background: '#fff', color: 'var(--bx-primary)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                      <Icon name={parsing ? 'spark' : 'upload'} size={20}/>
                    </div>
                    <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--bx-text-heading)', marginTop: 12 }}>
                      {parsing ? 'Đang đọc và kiểm tra…' : 'Kéo thả tệp hoặc bấm để chọn'}
                    </div>
                    <div style={{ fontSize: 12.5, color: 'var(--bx-text-muted)', marginTop: 4 }}>
                      {parsing ? 'Đang phân tích và so sánh với dữ liệu hiện có…' : 'Định dạng: .csv, .xlsx · phân tách bằng dấu phẩy hoặc tab'}
                    </div>
                    {!parsing && <Button variant="outline" icon="upload" style={{ marginTop: 16 }}>Chọn tệp</Button>}
                  </div>
                  {parsing && <div style={{ marginTop: 12 }}><Skeleton height={6}/></div>}

                  <div style={{ display: 'grid', gridTemplateColumns: stacked ? '1fr 1fr' : 'repeat(4, 1fr)', gap: 10, marginTop: 16 }}>
                    <HiMiniStat icon="warehouse" label="Kho được nhận" value="Tất cả"/>
                    <HiMiniStat icon="users"     label="Khách hàng"     value="Tự khớp theo mã"/>
                    <HiMiniStat icon="calendar"  label="Khoảng ngày"    value="≤ 24 tháng"/>
                    <HiMiniStat icon="diff"      label="Trùng (kho, KH, ngày)" value="Cập nhật"/>
                  </div>
                </Card>

                <Card title="Định dạng tệp" subtitle="4 cột bắt buộc · phân biệt chữ hoa, thường">
                  <table style={{ width: '100%', fontSize: 12, borderCollapse: 'collapse' }}>
                    <thead>
                      <tr style={{ background: 'var(--bx-surface-2)' }}>
                        <th style={hiTh}>Cột</th>
                        <th style={hiTh}>Kiểu</th>
                        <th style={hiTh}>Ví dụ</th>
                      </tr>
                    </thead>
                    <tbody style={{ fontFamily: 'var(--bx-font-mono)' }}>
                      <tr><td style={hiTd}>warehouseCode</td><td style={hiTd}>chuỗi</td><td style={hiTd}>VN-HN-01</td></tr>
                      <tr><td style={hiTd}>customerCode</td> <td style={hiTd}>chuỗi</td><td style={hiTd}>LOR</td></tr>
                      <tr><td style={hiTd}>date</td>         <td style={hiTd}>YYYY-MM-DD</td><td style={hiTd}>2026-04-12</td></tr>
                      <tr><td style={hiTd}>orderCount</td>   <td style={hiTd}>số nguyên ≥ 0</td><td style={hiTd}>1180</td></tr>
                    </tbody>
                  </table>
                  <div style={{ marginTop: 12, padding: 10, background: 'var(--bx-surface-2)', borderRadius: 8, fontSize: 11.5, color: 'var(--bx-text-body)' }}>
                    <Icon name="info" size={11} style={{ color: 'var(--bx-primary)', marginRight: 6 }}/>
                    Mỗi dòng là <b>tổng số đơn đã giao</b> của một khách hàng tại một kho trong một ngày. 30 ngày × 6 khách hàng × 2 kho = 360 dòng.
                  </div>
                  <Button variant="ghost-primary" size="sm" icon="download" style={{ marginTop: 12 }}>Tải mẫu .xlsx</Button>
                </Card>
              </div>
            )}

            {method === 'form' && <HiManualEntry warehouseId="wh-vn-hn-01" addToast={addToast} navigate={navigate}/>}
          </>
        )}

        {step === 2 && (
          <div style={{ marginTop: 16 }}>
            <div style={{
              display: 'grid',
              gridTemplateColumns: vw < 560 ? 'repeat(2, 1fr)' : vw < 900 ? 'repeat(3, 1fr)' : 'repeat(5, 1fr)',
              gap: isMobile ? 8 : 12, marginBottom: isMobile ? 12 : 16,
            }}>
              <Metric icon="diff"    label="Tổng số dòng" value={totals.rows}/>
              <Metric icon="plus"    label="Thêm mới"     value={totals.newC}/>
              <Metric icon="edit"    label="Cập nhật"     value={totals.upd}/>
              <Metric icon="check"   label="Không đổi"    value={totals.same}/>
              <Metric icon="warning" label="Lỗi"          value={totals.errors} delta={fmt.signed(totals.delta) + ' đơn ròng'} deltaTone={totals.delta >= 0 ? 'up' : 'down'}/>
            </div>

            {/* Coverage */}
            <Card title="Phạm vi dữ liệu" subtitle="Tổng quan các chiều có trong tệp" style={{ marginBottom: 16 }}>
              <div style={{ display: 'grid', gridTemplateColumns: stacked ? '1fr 1fr' : 'repeat(4, 1fr)', gap: 14, fontSize: 12.5 }}>
                <HiKV label="Khoảng ngày" mono value={fmt.date(preview.coverage.dateMin) + ' → ' + fmt.date(preview.coverage.dateMax)}/>
                <HiKV label="Số ngày"     mono value={preview.coverage.days + ' ngày'}/>
                <HiKV label="Kho"         mono value={preview.coverage.warehouses + ' kho'}/>
                <HiKV label="Khách hàng"  mono value={preview.coverage.customers + ' khách hàng'}/>
              </div>
            </Card>

            <Card title="2 · Xem trước thay đổi" subtitle={'Tệp: ' + (file ? file.name : preview.fileName) + ' · ' + preview.fileHash}
              actions={
                <div style={{ overflowX: 'auto', maxWidth: '100%' }}>
                  <Tabs value={filterStatus} onChange={setFilterStatus} dense tabs={[
                    { id: 'all',       label: 'Tất cả',    count: preview.rows.length },
                    { id: 'new',       label: 'Thêm mới',  count: totals.newC },
                    { id: 'update',    label: 'Cập nhật',  count: totals.upd },
                    { id: 'unchanged', label: 'Không đổi', count: totals.same },
                  ]}/>
                </div>
              }
              padding={0}>
              <Table dense columns={[
                { header: 'Kho',         mono: true, render: r => r.warehouseCode },
                { header: 'Khách hàng',  mono: true, render: r => r.customerCode },
                { header: 'Ngày',        mono: true, render: r => fmt.date(r.date) },
                { header: 'Hiện có',     priority: 2, mono: true, align: 'right', render: r => r.oldQty == null ? <span style={{ color: 'var(--bx-text-muted)' }}>—</span> : fmt.int(r.oldQty) },
                { header: 'Số đơn',      mono: true, align: 'right', render: r => fmt.int(r.newQty) },
                { header: 'Δ', mono: true, align: 'right', render: r => (
                  <span style={{ color: r.delta > 0 ? 'var(--bx-success)' : r.delta < 0 ? 'var(--bx-error)' : 'var(--bx-text-muted)', fontWeight: 600 }}>
                    {r.delta === 0 ? '—' : fmt.signed(r.delta)}
                  </span>
                )},
                { header: 'Trạng thái', render: r => <Badge kind={r.status === 'new' ? 'INFO' : r.status === 'update' ? 'WARNING' : 'APPROVED'} size="sm">{r.status === 'new' ? 'MỚI' : r.status === 'update' ? 'CẬP NHẬT' : 'KHÔNG ĐỔI'}</Badge> },
              ]} rows={rows} getRowKey={r => r.warehouseCode + r.customerCode + r.date} emptyText="Không có dòng nào trong bộ lọc này"/>
            </Card>

            {preview.errors.length > 0 && (
              <Card title={'Lỗi đọc tệp · ' + preview.errors.length} subtitle="Các dòng dưới đây sẽ tự động bị bỏ qua." style={{ marginTop: 16 }} padding={0}>
                <Table dense columns={[
                  { header: 'Dòng', mono: true, align: 'right', width: 60, key: 'line' },
                  { header: 'Cột', mono: true, width: 110, key: 'col' },
                  { header: 'Lý do', wrap: true, render: r => <span style={{ color: 'var(--bx-error)' }}>{r.message}</span> },
                ]} rows={preview.errors} getRowKey={(r, i) => i}/>
              </Card>
            )}

            <Card title="Tùy chọn nhập" subtitle="Cách xử lý dữ liệu trùng và ghi chú nhật ký" style={{ marginTop: 16 }}>
              <div style={{ display: 'grid', gridTemplateColumns: stacked ? '1fr' : '1fr 1fr', gap: 14 }}>
                <Field label="Khi trùng (kho, khách hàng, ngày)" hint="Áp dụng cho các dòng đã tồn tại trong kho dữ liệu">
                  <Select value={conflict} onChange={e => setConflict(e.target.value)} options={[
                    { value: 'update', label: 'Ghi đè bằng giá trị mới' },
                    { value: 'keep',   label: 'Giữ giá trị hiện tại' },
                    { value: 'error',  label: 'Báo lỗi và dừng nhập' },
                  ]}/>
                </Field>
                <Field label="Ghi chú đợt nhập" required hint="Sẽ ghi vào nhật ký kiểm toán">
                  <Input value={note} onChange={e => setNote(e.target.value)} placeholder="VD: Đối soát đơn tháng 4 từ TMS"/>
                </Field>
                <div style={{ gridColumn: stacked ? 'auto' : '1 / span 2', display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 4, flexWrap: 'wrap', gap: 10 }}>
                  <span style={{ fontSize: 12, color: 'var(--bx-text-muted)' }}>
                    {totals.newC + totals.upd} dòng sẽ ghi vào kho dữ liệu · {totals.same} bỏ qua (không đổi) · {totals.errors} bị loại (lỗi)
                  </span>
                  <div style={{ display: 'flex', gap: 8 }}>
                    <Button variant="outline" onClick={() => { setStep(1); setFile(null); }}>Quay lại</Button>
                    <Button variant="primary" icon="rocket" disabled={!note || committing} onClick={commit}>
                      {committing ? 'Đang nhập…' : 'Nhập ' + (totals.newC + totals.upd) + ' dòng'}
                    </Button>
                  </div>
                </div>
              </div>
            </Card>
          </div>
        )}

        {step === 3 && (
          <Card style={{ marginTop: 16 }}>
            <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start', flexWrap: 'wrap' }}>
              <div style={{ width: 48, height: 48, borderRadius: 9999, background: 'var(--bx-success-bg)', color: 'var(--bx-success)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name="check" size={20}/>
              </div>
              <div style={{ flex: 1, minWidth: 240 }}>
                <h2 style={{ fontSize: 18, fontWeight: 600, color: 'var(--bx-text-heading)', margin: 0 }}>Đã nhập · {totals.newC + totals.upd} dòng vào kho dữ liệu lịch sử</h2>
                <div style={{ fontSize: 13, color: 'var(--bx-text-body)', marginTop: 6, lineHeight: 1.55 }}>
                  Engine dự báo sẽ sử dụng dữ liệu mới ở lượt huấn luyện gần nhất (chạy mỗi 6 giờ). Bạn có thể xem nhật ký nhập trong tab kiểm toán hoặc nhập tiếp đợt khác.
                </div>
                <div style={{ display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
                  <Button variant="primary" icon="forecast" onClick={() => navigate('/planner/forecast')}>Mở dự báo</Button>
                  <Button variant="outline" icon="refresh" onClick={() => { setStep(1); setFile(null); }}>Nhập đợt khác</Button>
                </div>

                <div style={{ marginTop: 18, padding: 12, background: 'var(--bx-surface-2)', borderRadius: 8, display: 'flex', gap: 24, fontSize: 12, flexWrap: 'wrap' }}>
                  <div><span style={{ color: 'var(--bx-text-muted)' }}>Mã đợt nhập</span> <b style={{ fontFamily: 'var(--bx-font-mono)' }}>{preview.previewId}</b></div>
                  <div><span style={{ color: 'var(--bx-text-muted)' }}>Mã tệp</span> <b style={{ fontFamily: 'var(--bx-font-mono)' }}>{preview.fileHash}</b></div>
                  <div><span style={{ color: 'var(--bx-text-muted)' }}>Người nhập</span> <b>linh.tran@boxme.tech</b></div>
                  <div><span style={{ color: 'var(--bx-text-muted)' }}>Thời điểm</span> <b style={{ fontFamily: 'var(--bx-font-mono)' }}>{fmt.dateTime(new Date().toISOString())}</b></div>
                </div>
              </div>
            </div>
          </Card>
        )}
      </div>
    </div>
  );
}

// ---------- Small helpers (prefixed `hi` / `Hi` to avoid name clashes) ----------
const hiTh = { textAlign: 'left', padding: '6px 8px', fontSize: 10, color: 'var(--bx-text-muted)', textTransform: 'uppercase', letterSpacing: '0.04em', fontWeight: 700, borderBottom: '1px solid var(--bx-border)' };
const hiTd = { padding: '8px 8px', borderBottom: '1px solid var(--bx-border-muted)' };

function HiMiniStat({ icon, label, value }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '10px 12px', background: 'var(--bx-surface-2)',
      borderRadius: 8, minWidth: 0,
    }}>
      <div style={{
        width: 28, height: 28, borderRadius: 8, background: '#fff',
        color: 'var(--bx-text-muted)', display: 'flex',
        alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <Icon name={icon} size={13}/>
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 10.5, color: 'var(--bx-text-muted)', textTransform: 'uppercase', letterSpacing: '0.04em', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{label}</div>
        <div style={{ fontSize: 12.5, color: 'var(--bx-text-dark)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{value}</div>
      </div>
    </div>
  );
}

function HiKV({ label, value, mono }) {
  return (
    <div>
      <div style={{ fontSize: 10.5, color: 'var(--bx-text-muted)', textTransform: 'uppercase', letterSpacing: '0.04em', fontWeight: 600 }}>{label}</div>
      <div style={{ fontSize: 13.5, color: 'var(--bx-text-dark)', fontWeight: 600, marginTop: 2, fontFamily: mono ? 'var(--bx-font-mono)' : 'var(--bx-font-sans)' }}>{value}</div>
    </div>
  );
}

Object.assign(window, { HistoryImportScreen });
