const UNDERGRAD_YEARS = ["Freshman", "Sophomore", "Junior", "Senior"];
const GRAD_YEARS = ["1st Year", "2nd Year"];

// Profile view
function ProfileView({ currentUser, setCurrentUser }) {
  const [name, setName] = React.useState(currentUser.name || "");
  const [studentType, setStudentType] = React.useState(currentUser.studentType || "undergraduate");
  const [major, setMajor] = React.useState(currentUser.major && currentUser.major !== "Not set" ? currentUser.major : "");
  const [year, setYear] = React.useState(currentUser.year && currentUser.year !== "Not set" ? currentUser.year : "");
  const [expectedGrad, setExpectedGrad] = React.useState(currentUser.expectedGrad && currentUser.expectedGrad !== "Not set" ? currentUser.expectedGrad : "");
  const [completed, setCompleted] = React.useState(currentUser.completedCourses || []);
  const [newCourse, setNewCourse] = React.useState("");
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState(false);
  const [courseSaving, setCourseSaving] = React.useState(false);
  const [results, setResults] = React.useState([]);
  const [resultsOpen, setResultsOpen] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  const [uploadResult, setUploadResult] = React.useState(null); // { ok, text }
  const searchTimer = React.useRef(null);
  const fileInputRef = React.useRef(null);

  const runSearch = (value) => {
    setNewCourse(value);
    if (searchTimer.current) clearTimeout(searchTimer.current);
    if (!value.trim()) { setResults([]); return; }
    searchTimer.current = setTimeout(async () => {
      try {
        const token = localStorage.getItem("token");
        const res = await fetch(`${window.API_BASE}/api/courses/search?q=${encodeURIComponent(value)}`, {
          headers: { "Authorization": "Bearer " + token },
        });
        const data = await res.json();
        setResults(Array.isArray(data) ? data : []);
      } catch (e) {
        setResults([]);
      }
    }, 200);
  };

  const applyProfileResponse = (data) => {
    const parts = (data.name || "").trim().split(/\s+/);
    const initials = parts.length >= 2
      ? parts[0][0] + parts[parts.length - 1][0]
      : (parts[0] || "?")[0];
    setCurrentUser({
      ...currentUser,
      name: data.name,
      initials: initials.toUpperCase(),
      studentType: data.student_type || "undergraduate",
      major: data.major,
      year: data.year,
      expectedGrad: data.expected_grad,
      completedCourses: data.completed_courses || [],
    });
  };

  // Completed courses save immediately on add/remove — degree progress should
  // update right away, not only after a separate "Save changes" click.
  const saveCourses = async (nextCompleted) => {
    setCourseSaving(true);
    try {
      const res = await fetch(`${window.API_BASE}/api/profile`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
          "Authorization": "Bearer " + localStorage.getItem("token"),
        },
        body: JSON.stringify({ completed_courses: nextCompleted }),
      });
      const data = await res.json();
      if (res.ok) applyProfileResponse(data);
    } catch (e) {
      console.error("Failed to save completed courses", e);
    } finally {
      setCourseSaving(false);
    }
  };

  const addCourse = (explicitCode) => {
    const code = (explicitCode || newCourse).trim().toUpperCase();
    if (!code || completed.includes(code)) return;
    const next = [...completed, code];
    setCompleted(next);
    setNewCourse("");
    setResults([]);
    setResultsOpen(false);
    saveCourses(next);
  };

  const removeCourse = (code) => {
    const next = completed.filter(c => c !== code);
    setCompleted(next);
    saveCourses(next);
  };

  // Works for both undergrad and grad students — the parser is DegreeWorks-format-based,
  // not major-specific. Merges completed courses (never overwrites) and only fills
  // major/year if the student hasn't already set them.
  const handleTranscriptClick = () => { if (fileInputRef.current) fileInputRef.current.click(); };

  const handleTranscriptFile = async (e) => {
    const file = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!file) return;

    setUploading(true);
    setUploadResult(null);
    try {
      const token = localStorage.getItem("token");
      const formData = new FormData();
      formData.append("file", file);
      const res = await fetch(`${window.API_BASE}/api/parse-degreeworks`, {
        method: "POST",
        headers: { "Authorization": "Bearer " + token },
        body: formData,
      });
      const data = await res.json();
      if (data.error) throw new Error(data.error);

      const existing = completed.map(c => c.toUpperCase());
      const parsed = (data.completed_courses || []).map(c => c.toUpperCase());
      const merged = Array.from(new Set([...existing, ...parsed]));
      const newlyAdded = parsed.filter(c => !existing.includes(c));

      const body = { completed_courses: merged };
      if (data.major && !major) body.major = data.major;
      if (data.year && !year) body.year = data.year;

      const profileRes = await fetch(`${window.API_BASE}/api/profile`, {
        method: "PUT",
        headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
        body: JSON.stringify(body),
      });
      const profileData = await profileRes.json();
      if (profileRes.ok) {
        applyProfileResponse(profileData);
        setCompleted(profileData.completed_courses || merged);
        if (body.major && profileData.major) setMajor(profileData.major);
        if (body.year && profileData.year) setYear(profileData.year);
      }

      const parts = [];
      if (newlyAdded.length) parts.push(`added ${newlyAdded.length} newly completed course${newlyAdded.length === 1 ? "" : "s"}`);
      if (body.major) parts.push(`set your ${studentType === "graduate" ? "program" : "major"} to ${data.major}`);
      if (body.year) parts.push(`set your year to ${data.year}`);

      setUploadResult({
        ok: true,
        text: parts.length
          ? `Read ${file.name} and ${parts.join(", ")}.`
          : merged.length
            ? `Read ${file.name} — your profile already matches, nothing new to add.`
            : `Read ${file.name} but couldn't find any recognizable course history in it. Try attaching your official DegreeWorks audit PDF.`,
      });
    } catch (err) {
      setUploadResult({
        ok: false,
        text: "Couldn't read that file: " + (err.message || "unknown error") + ". Try a text-based PDF export of your DegreeWorks audit.",
      });
    } finally {
      setUploading(false);
    }
  };

  const handleSave = async () => {
    setSaving(true);
    setSaved(false);
    try {
      const res = await fetch(`${window.API_BASE}/api/profile`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
          "Authorization": "Bearer " + localStorage.getItem("token"),
        },
        body: JSON.stringify({
          name,
          student_type: studentType,
          major,
          year,
          expected_grad: expectedGrad,
          completed_courses: completed,
        }),
      });
      const data = await res.json();
      if (res.ok) {
        applyProfileResponse(data);
        setSaved(true);
        setTimeout(() => setSaved(false), 3000);
      }
    } catch (e) {
      console.error("Failed to save profile", e);
    } finally {
      setSaving(false);
    }
  };

  const handleCancel = () => {
    setName(currentUser.name || "");
    setStudentType(currentUser.studentType || "undergraduate");
    setMajor(currentUser.major && currentUser.major !== "Not set" ? currentUser.major : "");
    setYear(currentUser.year && currentUser.year !== "Not set" ? currentUser.year : "");
    setExpectedGrad(currentUser.expectedGrad && currentUser.expectedGrad !== "Not set" ? currentUser.expectedGrad : "");
    setCompleted(currentUser.completedCourses || []);
  };

  return (
    <div className="view-wrap">
      <div className="view-head">
        <div>
          <h2>Your <em>profile</em></h2>
          <p>Keep this up to date — your advisor uses it to personalize every recommendation.</p>
        </div>
        <div className="view-actions">
          <button className="btn" onClick={handleCancel}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={saving}>
            {saving ? "Saving..." : saved ? "Saved ✓" : "Save changes"}
          </button>
        </div>
      </div>

      <div className="profile-grid">
        <div className="profile-side">
          <div className="big-ava">{currentUser.initials}</div>
          <h4>{currentUser.name}</h4>
          <div className="sub">{[year, major].filter(Boolean).join(" · ") || "Profile incomplete"}</div>
          <div className="id">
            ID · {currentUser.id}<br/>
            {currentUser.email}
          </div>
        </div>

        <div className="profile-form">
          <div className="field-row">
            <div className="field">
              <label>Full name</label>
              <input value={name} onChange={e => setName(e.target.value)} placeholder="Your full name" />
            </div>
            <div className="field">
              <label>UofSC email</label>
              <input defaultValue={currentUser.email} disabled />
            </div>
          </div>

          <div className="field-row">
            <div className="field">
              <label>Student type</label>
              <select
                value={studentType}
                onChange={e => {
                  const next = e.target.value;
                  setStudentType(next);
                  // Major/Year lists are different for undergrad vs. grad — a value
                  // that was valid under the old type won't necessarily exist in the new one.
                  const validMajors = next === "graduate" ? GRAD_PROGRAMS : MAJORS;
                  if (!validMajors.includes(major)) setMajor("");
                  const validYears = next === "graduate" ? GRAD_YEARS : UNDERGRAD_YEARS;
                  if (!validYears.includes(year)) setYear("");
                }}
              >
                <option value="undergraduate">Undergraduate</option>
                <option value="graduate">Graduate</option>
              </select>
            </div>
            <div className="field">
              <label>Year</label>
              <select value={year} onChange={e => setYear(e.target.value)}>
                <option value="">Select year...</option>
                {(studentType === "graduate" ? GRAD_YEARS : UNDERGRAD_YEARS).map(y => <option key={y}>{y}</option>)}
              </select>
            </div>
          </div>

          <div className="field-row">
            <div className="field" style={{flex: "0 0 100%"}}>
              <label>{studentType === "graduate" ? "Graduate program" : "Major"}</label>
              <select value={major} onChange={e => setMajor(e.target.value)}>
                <option value="">Select {studentType === "graduate" ? "program" : "major"}...</option>
                {(studentType === "graduate" ? GRAD_PROGRAMS : MAJORS).map(m => <option key={m}>{m}</option>)}
              </select>
            </div>
          </div>

          <div className="field-row">
            <div className="field">
              <label>Expected graduation</label>
              <select value={expectedGrad} onChange={e => setExpectedGrad(e.target.value)}>
                <option value="">Select...</option>
                <option>Spring 2026</option>
                <option>Fall 2026</option>
                <option>Spring 2027</option>
                <option>Fall 2027</option>
                <option>Spring 2028</option>
                <option>Fall 2028</option>
                <option>Spring 2029</option>
              </select>
            </div>
          </div>

          <div className="field">
            <label>Completed courses · {completed.length} {courseSaving && <small style={{color:"var(--ink-4)", fontWeight: 400}}>· saving…</small>}</label>
            <div className="completed-list">
              {completed.map(c => (
                <span className="completed-chip" key={c}>
                  <b>{c}</b>
                  <span className="x" onClick={() => removeCourse(c)}>×</span>
                </span>
              ))}
            </div>
            <div style={{display:"flex", gap:"8px", marginTop:"8px", position:"relative"}}>
              <div style={{flex:1, position:"relative"}}>
                <input
                  placeholder="Add course e.g. ACCT 225"
                  value={newCourse}
                  onChange={e => { runSearch(e.target.value); setResultsOpen(true); }}
                  onFocus={() => setResultsOpen(true)}
                  onBlur={() => setTimeout(() => setResultsOpen(false), 150)}
                  onKeyDown={e => e.key === "Enter" && addCourse()}
                  style={{width:"100%", padding:"8px 12px", border:"1px solid var(--line-2)", borderRadius:"var(--r-sm)", fontSize:"13px", background:"var(--paper)"}}
                />
                {resultsOpen && results.length > 0 && (
                  <div style={{
                    position:"absolute", top:"calc(100% + 4px)", left:0, right:0, zIndex:20,
                    background:"var(--card)", border:"1px solid var(--line)", borderRadius:"var(--r-sm)",
                    boxShadow:"0 8px 24px -8px rgba(0,0,0,0.25)", maxHeight:260, overflowY:"auto",
                    display:"flex", flexDirection:"column", padding:4,
                  }}>
                    {results.map(r => (
                      <div
                        key={r.code}
                        onMouseDown={() => addCourse(r.code)}
                        style={{cursor:"pointer", fontSize:12, padding:"6px 8px", borderRadius:4}}
                        onMouseEnter={(e) => e.currentTarget.style.background = "var(--card-2)"}
                        onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}
                      >
                        <span className="code">{r.code}</span> — {r.title}
                      </div>
                    ))}
                  </div>
                )}
              </div>
              <button className="btn primary" onClick={() => addCourse()}>Add</button>
            </div>
            <small style={{color:"var(--ink-4)", display:"block", marginTop:6}}>Saves immediately — updates your Degree Progress right away.</small>
          </div>

          <div className="field">
            <label>Upload transcript</label>
            <input
              ref={fileInputRef}
              type="file"
              accept="application/pdf"
              style={{ display: "none" }}
              onChange={handleTranscriptFile}
            />
            <button
              type="button"
              onClick={handleTranscriptClick}
              disabled={uploading}
              style={{
                width: "100%", display: "flex", flexDirection: "column", alignItems: "center", gap: 6,
                padding: "18px 16px", border: "1.5px dashed var(--line-2)", borderRadius: "var(--r-md)",
                background: "var(--paper)", color: "var(--ink-3)", cursor: uploading ? "default" : "pointer",
                transition: "border-color 0.15s",
              }}
              onMouseEnter={(e) => { if (!uploading) e.currentTarget.style.borderColor = "var(--accent)"; }}
              onMouseLeave={(e) => { e.currentTarget.style.borderColor = "var(--line-2)"; }}
            >
              {uploading ? (
                <React.Fragment>
                  <span className="tool-spinner" />
                  <span style={{ fontSize: 13 }}>Reading transcript…</span>
                </React.Fragment>
              ) : (
                <React.Fragment>
                  <I.paperclip />
                  <span style={{ fontSize: 13, fontWeight: 600, color: "var(--ink-2)" }}>Upload DegreeWorks transcript (PDF)</span>
                  <span style={{ fontSize: 11.5 }}>
                    Auto-fills completed courses{studentType === "graduate" ? " and program" : " and major"} if not already set
                  </span>
                </React.Fragment>
              )}
            </button>
            {uploadResult && (
              <small style={{ display: "block", marginTop: 6, color: uploadResult.ok ? "var(--ink-3)" : "#a83a32" }}>
                {uploadResult.ok ? "✓ " : ""}{uploadResult.text}
              </small>
            )}
          </div>

          {saved && (
            <div style={{padding:"10px 14px", background:"#e6f4ea", border:"1px solid #a8d5b0", borderRadius:"var(--r-sm)", color:"#2d6a4f", fontSize:"13px"}}>
              ✓ Profile saved — your advisor will use this in the next conversation.
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

window.ProfileView = ProfileView;
