// หน้ารายการ "แบบสอบถามความพึงพอใจหลังอบรม" — อัปโหลดไฟล์ export จาก Microsoft Forms
// คนละชุดกับ courses/training_evals (ที่เป็นการติดตามผลตนเอง/ผู้บังคับบัญชาประเมินภายหลัง)

// หัวข้อคอลัมน์ในไฟล์ export (Microsoft Forms) -> field ที่ backend รับ (camelCase)
// จับคู่ด้วยข้อความหัวคอลัมน์ (ตัดช่องว่าง/nbsp ส่วนเกินออกก่อนเทียบ) ทนทานต่อการสลับตำแหน่งคอลัมน์
const SATISFACTION_HEADER_MAP = {
  "รหัสพนักงาน": "empId",
  "ชื่อ": "firstName",
  "นามสกุล": "lastName",
  "ตำแหน่ง": "position",
  "ฝ่าย": "dept",
  "หลักสูตรนี้เกี่ยวข้องกับงานของท่านมากน้อยเพียงใด": "relevance",
  "ท่านประเมินความรู้หรือทักษะของตนเองในหัวข้อนี้อยู่ระดับใด": "selfKnowledge",
  "การสื่อสารและการประสานงาน : ก่อนการอบรม มีความชัดเจนในการแจ้งรายละเอียด เวลา สถานที่ การเตรียมความพร้อมก่อนการเข้ารับการฝึกอบรม": "orgComm",
  "ความพร้อมของสถานที่และระบบสนับสนุน : แสง เสียง อุณหภูมิ สิ่งอำนวยความสะดวกต่าง ๆ เหมาะสมต่อการฝึกอบรม": "orgFacility",
  "การดูแลและอำนวยความสะดวกระหว่างอบรม : มีการช่วยเหลือ ประสานงาน และแก้ปัญหาเฉพาะหน้าได้อย่างเหมาะสม": "orgSupport",
  "การบริหารเวลา : สามารถดำเนินการอบรมให้เป็นไปตามกำหนดการ ควบคุมเวลาเริ่ม–สิ้นสุดให้เป็นไปตามแผน": "orgTime",
  "ความพึงพอใจโดยรวมต่อการให้บริการของผู้จัดฝึกอบรม": "orgOverall",
  "ข้อเสนอแนะเพิ่มเติมเกี่ยวกับ กระบวนการจัดการฝึกอบรม": "orgFeedback",
  "วิทยากรมีความรู้และความเชี่ยวชาญในเนื้อหาที่สอนอย่างชัดเจน": "trainerKnowledge",
  "วิทยากรถ่ายทอดเนื้อหาได้เป็นระบบและมีลำดับขั้นตอนที่ดี": "trainerDelivery",
  "วิทยากรใช้ตัวอย่างหรือ Workshop ที่เหมาะสมกับระดับผู้เรียน": "trainerExamples",
  "วิทยากรบริหารเวลาในการสอนได้เหมาะสม ครบตามหัวข้อ": "trainerTime",
  "โดยภาพรวม ท่านพึงพอใจต่อวิทยากรในการอบรมครั้งนี้": "trainerOverall",
  "ข้อเสนอแนะเพิ่มเติมเกี่ยวกับวิทยากร": "trainerFeedback",
  "ท่านเข้าใจเนื้อหาโดยรวมในระดับใด": "understanding",
  "ระดับความรู้/ทักษะของท่านเพิ่มขึ้นมากน้อยเพียงใดหลังอบรม": "skillIncrease",
  "หลังอบรม ท่านมีความมั่นใจว่าสามารถนำความรู้ไปใช้กับงานจริงได้มากน้อยเพียงใด": "confidence",
  "ท่านตั้งใจจะนำความรู้ไปใช้กับเรื่องใดมากที่สุด (เลือก 1 ข้อ)": "applicationIntent",
  "สิ่งสำคัญที่สุดที่ท่านได้เรียนรู้จากการอบรมครั้งนี้คืออะไร": "keyLearning",
  "ท่านจะนำความรู้ที่ได้ไปใช้ในการทำงานอะไร": "willApplyTo",
  "ข้อเสนอแนะเพิ่มเติมอื่น ๆ": "otherFeedback",
};
const normHeader = (s) => String(s || "").replace(/ /g, " ").replace(/\s+/g, " ").trim();
const NORM_HEADER_MAP = Object.fromEntries(
  Object.entries(SATISFACTION_HEADER_MAP).map(([k, v]) => [normHeader(k), v])
);

// อ่านไฟล์ .xlsx ด้วย SheetJS (ทนทานกับไฟล์ export จาก Microsoft Forms มากกว่า ExcelJS ซึ่ง
// อ่าน docProps/core.xml ของไฟล์ประเภทนี้ไม่ได้ — ExcelJS ยังใช้สำหรับ export อยู่เหมือนเดิม)
// -> คืน { rows, unmatchedHeaders }
async function parseSatisfactionFile(file) {
  const XLSX = window.XLSX;
  if (!XLSX) throw new Error("ไม่พบ Excel library กรุณารีโหลดหน้า");
  const buf = await file.arrayBuffer();
  const wb = XLSX.read(buf, { type: "array" });
  const wsName = wb.SheetNames[0];
  const ws = wb.Sheets[wsName];
  if (!ws) throw new Error("ไม่พบชีตข้อมูลในไฟล์");

  const grid = XLSX.utils.sheet_to_json(ws, { header: 1, raw: false, defval: "" });
  if (!grid.length) throw new Error("ไฟล์ว่างเปล่า");

  const headerCells = grid[0];
  const colField = {}; // colIndex -> field
  const unmatched = [];
  headerCells.forEach((h, i) => {
    const norm = normHeader(h);
    if (!norm) return;
    const field = NORM_HEADER_MAP[norm];
    if (field) colField[i] = field;
    else unmatched.push(norm);
  });

  const rows = [];
  for (let r = 1; r < grid.length; r++) {
    const rowArr = grid[r];
    const obj = {};
    let hasAny = false;
    Object.entries(colField).forEach(([i, field]) => {
      const v = rowArr[Number(i)];
      if (v != null && String(v).trim() !== "") { obj[field] = String(v).trim(); hasAny = true; }
    });
    if (hasAny) rows.push(obj);
  }

  return { rows, unmatchedHeaders: unmatched };
}

const UploadSurveyModal = ({ open, onClose, onDataChange }) => {
  const { push } = useToast();
  const [file, setFile] = React.useState(null);
  const [courseName, setCourseName] = React.useState("");
  const [courseDate, setCourseDate] = React.useState("");
  const [parsing, setParsing] = React.useState(false);
  const [preview, setPreview] = React.useState(null); // { rows, unmatchedHeaders }
  const [submitting, setSubmitting] = React.useState(false);

  React.useEffect(() => {
    if (!open) { setFile(null); setCourseName(""); setCourseDate(""); setPreview(null); }
  }, [open]);

  const handleFile = async (f) => {
    setFile(f);
    setPreview(null);
    if (!f) return;
    if (!courseName) setCourseName(f.name.replace(/\.xlsx?$/i, ""));
    setParsing(true);
    try {
      const result = await parseSatisfactionFile(f);
      setPreview(result);
      if (!result.rows.length) push("ไม่พบแถวข้อมูลคำตอบในไฟล์นี้", { kind: "error" });
    } catch (e) {
      push(e.message || "อ่านไฟล์ไม่สำเร็จ", { kind: "error" });
    } finally {
      setParsing(false);
    }
  };

  const submit = async () => {
    if (!courseName.trim()) { push("กรุณากรอกชื่อหลักสูตร", { kind: "error" }); return; }
    if (!preview || !preview.rows.length) { push("กรุณาเลือกไฟล์ที่มีข้อมูลก่อน", { kind: "error" }); return; }
    setSubmitting(true);
    try {
      const res = await window.TRN_API.uploadSatisfactionSurvey({
        courseName: courseName.trim(),
        courseDate: courseDate || null,
        sourceFileName: file?.name || null,
        responses: preview.rows,
      });
      push(`อัปโหลดสำเร็จ (${res.people} คน)`, { kind: "success" });
      onDataChange?.();
      onClose();
    } catch (e) {
      push(e.message || "อัปโหลดไม่สำเร็จ", { kind: "error" });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose} maxWidth={560}>
      <div style={{ padding: "22px 24px" }}>
        <div style={{ fontWeight: 700, fontSize: 17, marginBottom: 4 }}>อัปโหลดผลสำรวจความพึงพอใจ</div>
        <div className="faint" style={{ fontSize: 12.5, marginBottom: 18 }}>
          ไฟล์ export จาก Microsoft Forms (.xlsx) — 1 ไฟล์ต่อ 1 หลักสูตร/รุ่น
        </div>

        <div style={{ marginBottom: 14 }}>
          <div className="faint" style={{ fontSize: 12, marginBottom: 6 }}>ชื่อหลักสูตร</div>
          <input className="input" value={courseName} onChange={e => setCourseName(e.target.value)} placeholder="เช่น การใช้งานโปรแกรม Excel ขั้นพัฒนา" />
        </div>
        <div style={{ marginBottom: 14 }}>
          <div className="faint" style={{ fontSize: 12, marginBottom: 6 }}>วันที่อบรม (ไม่บังคับ)</div>
          <input className="input" type="date" value={courseDate} onChange={e => setCourseDate(e.target.value)} />
        </div>
        <div style={{ marginBottom: 14 }}>
          <div className="faint" style={{ fontSize: 12, marginBottom: 6 }}>ไฟล์ผลสำรวจ (.xlsx)</div>
          <input type="file" accept=".xlsx" onChange={e => handleFile(e.target.files?.[0] || null)} />
        </div>

        {parsing && <div className="faint" style={{ fontSize: 13 }}>กำลังอ่านไฟล์...</div>}
        {preview && (
          <div style={{ borderRadius: 10, padding: "12px 14px", background: "var(--surface)", marginBottom: 14 }}>
            <div style={{ fontSize: 13 }}>พบข้อมูลคำตอบ <b style={{ color: "var(--teal)" }}>{preview.rows.length}</b> แถว</div>
            {preview.unmatchedHeaders.length > 0 && (
              <div className="faint" style={{ fontSize: 11.5, marginTop: 6 }}>
                คอลัมน์ที่ไม่ตรงกับรูปแบบที่รู้จัก (จะถูกข้าม): {preview.unmatchedHeaders.slice(0, 4).join(", ")}
                {preview.unmatchedHeaders.length > 4 ? ` +${preview.unmatchedHeaders.length - 4}` : ""}
              </div>
            )}
          </div>
        )}

        <div className="row gap-8" style={{ justifyContent: "flex-end", marginTop: 6 }}>
          <button className="btn btn-ghost btn-sm" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary btn-sm shine" disabled={submitting || !preview?.rows?.length} onClick={submit}>
            {submitting ? "กำลังอัปโหลด..." : "อัปโหลด"}
          </button>
        </div>
      </div>
    </Modal>
  );
};

const SatisfactionListScreen = ({ user, onOpenSurvey, onDashboard, onCourses, onLogout }) => {
  const [surveys, setSurveys] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [showUpload, setShowUpload] = React.useState(false);
  const [deleteTarget, setDeleteTarget] = React.useState(null);
  const { push } = useToast();

  const load = React.useCallback(() => {
    setLoading(true);
    window.TRN_API.listSatisfactionSurveys()
      .then(res => setSurveys(res.data || []))
      .catch(e => push(e.message || "โหลดไม่สำเร็จ", { kind: "error" }))
      .finally(() => setLoading(false));
  }, []);

  React.useEffect(() => { load(); }, [load]);

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      await window.TRN_API.deleteSatisfactionSurvey(deleteTarget.id);
      push("ลบผลสำรวจเรียบร้อย", { kind: "success" });
      setSurveys(p => p.filter(s => s.id !== deleteTarget.id));
    } catch (e) { push(e.message || "ลบไม่สำเร็จ", { kind: "error" }); }
    finally { setDeleteTarget(null); }
  };

  return (
    <div style={{ minHeight: "100vh", paddingBottom: 60 }}>
      <GlowBlob color="rgba(124,92,255,0.25)" x={-80} y={-60} size={500} opacity={0.2} />
      <GlowBlob color="rgba(0,212,168,0.25)" x="65vw" y="25vh" size={400} opacity={0.16} />

      <div style={{ padding: "16px 28px", display: "flex", alignItems: "center", justifyContent: "space-between", borderBottom: "1px solid var(--border)", backdropFilter: "blur(10px)", position: "sticky", top: 0, zIndex: 100, background: "var(--bg-1)" }}>
        <div className="row gap-12">
          <button className="btn btn-ghost btn-icon" onClick={onCourses} title="กลับ"><Icon name="chevron-l" size={16} /></button>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: "linear-gradient(135deg,#7c5cff,#00d4a8)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 13, color: "#fff", fontWeight: 700 }}>😊</div>
          <div><div style={{ fontWeight: 600, fontSize: 14 }}>ความพึงพอใจหลังอบรม</div><div className="faint" style={{ fontSize: 11 }}>Post-training Satisfaction Survey</div></div>
        </div>
        <div className="row gap-10">
          {user?.canEdit && (
            <button className="btn btn-primary btn-sm shine" onClick={() => setShowUpload(true)}><Icon name="excel" size={14} /> อัปโหลดผลสำรวจ</button>
          )}
          <button className="btn btn-ghost btn-sm" onClick={onCourses}><Icon name="briefcase" size={14} /> หลักสูตร</button>
          <button className="btn btn-ghost btn-sm" onClick={onDashboard}><Icon name="chart-bar" size={14} /> แดชบอร์ดหลัก</button>
          <div className="row gap-8" style={{ padding: "5px 10px", borderRadius: 8, background: "var(--surface)", border: "1px solid var(--border)" }}>
            <div style={{ width: 26, height: 26, borderRadius: "50%", background: "linear-gradient(135deg,#00d4a855,#7c5cff55)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontWeight: 600 }}>
              {user?.email?.[0]?.toUpperCase() || "U"}
            </div>
            <div style={{ fontSize: 12, fontWeight: 500 }}>{user?.name || user?.email}</div>
            <button className="btn btn-ghost btn-sm" onClick={onLogout} style={{ padding: "3px 6px" }}><Icon name="logout" size={13} /></button>
          </div>
        </div>
      </div>

      <div style={{ padding: "24px 28px 0", maxWidth: 1200, margin: "0 auto" }}>
        <div style={{ marginBottom: 18 }}>
          <div style={{ fontWeight: 700, fontSize: 20 }}>แบบสอบถามความพึงพอใจหลังอบรม</div>
          <div className="faint" style={{ fontSize: 13, marginTop: 2 }}>{surveys.length} หลักสูตร — อัปโหลดไฟล์ export จาก Microsoft Forms เพื่อสร้าง Dashboard อัตโนมัติ</div>
        </div>

        {loading ? (
          <div style={{ padding: 60, textAlign: "center" }}><LoadingSplash /></div>
        ) : surveys.length === 0 ? (
          <div className="glass" style={{ borderRadius: 14, padding: "60px 0", textAlign: "center" }}>
            <div className="faint" style={{ fontSize: 14, marginBottom: 14 }}>ยังไม่มีผลสำรวจ</div>
            {user?.canEdit && <button className="btn btn-primary shine" onClick={() => setShowUpload(true)}><Icon name="excel" size={14} /> อัปโหลดไฟล์แรก</button>}
          </div>
        ) : (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))", gap: 16 }}>
            {surveys.map(s => (
              <div key={s.id} className="glass" onClick={() => onOpenSurvey(s.id)}
                style={{ borderRadius: 14, padding: "18px 20px", cursor: "pointer", position: "relative", transition: "transform .12s, box-shadow .12s" }}
                onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.boxShadow = "0 8px 24px rgba(0,0,0,0.08)"; }}
                onMouseLeave={e => { e.currentTarget.style.transform = ""; e.currentTarget.style.boxShadow = ""; }}>
                <div className="row" style={{ justifyContent: "space-between", alignItems: "flex-start", gap: 8 }}>
                  <div style={{ fontWeight: 600, fontSize: 15, lineHeight: 1.4, flex: 1 }}>{s.course_name}</div>
                  {user?.canDelete && (
                    <button className="btn btn-ghost btn-sm" style={{ color: "var(--pink)", padding: "3px 6px", flexShrink: 0 }}
                      onClick={e => { e.stopPropagation(); setDeleteTarget(s); }}><Icon name="trash" size={13} /></button>
                  )}
                </div>
                <div className="faint" style={{ fontSize: 12, marginTop: 8, display: "flex", flexDirection: "column", gap: 4 }}>
                  {s.course_date && <div><Icon name="hourglass" size={12} /> อบรม {fmtThaiDate(s.course_date)}</div>}
                  <div><Icon name="download" size={12} /> อัปโหลด {relativeTime(s.created_at)} · {s.uploaded_by || "—"}</div>
                </div>
                <div style={{ marginTop: 14, paddingTop: 12, borderTop: "1px solid var(--border)" }}>
                  <span style={{ fontWeight: 700, fontSize: 18, color: "var(--purple)" }}>{s.people || 0}</span>
                  <span className="faint" style={{ fontSize: 12, marginLeft: 5 }}>คนตอบแบบสอบถาม</span>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <UploadSurveyModal open={showUpload} onClose={() => setShowUpload(false)} onDataChange={load} />
      <ConfirmDialog open={!!deleteTarget} title="ลบผลสำรวจ"
        message={`ลบผลสำรวจ "${deleteTarget?.course_name}" และคำตอบทั้งหมด (${deleteTarget?.people || 0} คน)?`}
        onConfirm={handleDelete} onCancel={() => setDeleteTarget(null)} danger />
    </div>
  );
};
window.SatisfactionListScreen = SatisfactionListScreen;
