import { useEffect, useState } from "react";

const LEGACY_QUESTION_ID_MAP = {
  Ca1: "C1",
  Ca2: "C2",
  Ca3: "C3",
  He1: "H1",
  He2: "H2",
  He3: "H3",
  He4: "H4",
  He5: "H5",
};

const CATEGORY_META = {
  career: { label: "Career", title: "Nghề nghiệp", accent: "accent-career", shortLabel: "Career" },
  health: { label: "Health", title: "Sức khỏe", accent: "accent-health", shortLabel: "Health" },
  learning: { label: "Learning", title: "Học tập", accent: "accent-learning", shortLabel: "Learning" },
  happiness: { label: "Happiness", title: "Hạnh phúc", accent: "accent-happiness", shortLabel: "Happiness" },
  contribution: { label: "Impact", title: "Cống hiến", accent: "accent-contribution", shortLabel: "Impact" },
};

const SECTION_LABELS = {
  currentPortrait: "Chân dung hiện tại",
  nextAction: "Hành động tiếp theo",
  ...Object.fromEntries(Object.entries(CATEGORY_META).map(([key, value]) => [key, value.title])),
};

const RESULT_ORDER = ["career", "health", "learning", "happiness", "contribution"];
const CORE_SECTION_TASKS = [
  { section: "currentPortrait", url: "/api/bridgeup/recommendation/current-portrait" },
  { section: "nextAction", url: "/api/bridgeup/recommendation/next-action" },
];
const DEFAULT_SCORING_CONFIG = { careerSlopeCap: 0.85 };
const STREAM_STEP_MS = 8;
const INSIGHT_STREAM_STEP_MS = 2;

function sumScores(rawScores, ids) {
  return ids.reduce((total, id) => {
    const legacyId = Object.keys(LEGACY_QUESTION_ID_MAP).find((key) => LEGACY_QUESTION_ID_MAP[key] === id);
    return total + Number(rawScores[id] || rawScores[legacyId] || 0);
  }, 0);
}

function calculateCategoryScores(rawScores, scoringConfig = DEFAULT_SCORING_CONFIG) {
  const normalizeScore = (value, maxScore) => Math.round((Number(value || 0) / maxScore) * 100);
  const careerSlopeCap =
    typeof scoringConfig.careerSlopeCap === "number" ? scoringConfig.careerSlopeCap : DEFAULT_SCORING_CONFIG.careerSlopeCap;
  const careerRaw = Number(rawScores.C1 || rawScores.Ca1 || 0) + sumScores(rawScores, ["C2", "C3"]) * careerSlopeCap;

  return {
    career: Math.min(40, Number(careerRaw.toFixed(2))),
    health: normalizeScore(sumScores(rawScores, ["H1", "H2", "H3", "H4", "H5"]), 20),
    learning: normalizeScore(sumScores(rawScores, ["L1", "L2", "L3", "L4", "L5"]), 20),
    happiness: sumScores(rawScores, ["Ha1", "Ha2", "Ha3", "Ha4"]),
    contribution: Math.min(9, sumScores(rawScores, ["Co1", "Co2", "Co3"])),
  };
}

function formatScore(value) {
  return Math.round(Number(value || 0));
}

function toCategoryLabel(category) {
  return SECTION_LABELS[category] || category;
}

function createRecommendationSkeleton(scores) {
  return {
    currentPortrait: "",
    nextAction: "",
    dimensions: RESULT_ORDER.reduce((acc, key) => {
      acc[key] = { score: Number(scores[key] || 0), strength: "", weak: "", insight: "" };
      return acc;
    }, {}),
  };
}

function LoadingInline({ isActive, seconds }) {
  return (
    <span className={`task-loading${isActive ? " is-active" : ""}`}>
      <span className="task-spinner" aria-hidden="true" />
      {isActive ? `Đang phân tích • ${seconds}s` : "Đang chờ phân tích..."}
    </span>
  );
}

function renderTaskContent(primary, { isSubmitting, isActive, seconds, emptyText, error }) {
  if (primary) return primary;
  if (isSubmitting) return <LoadingInline isActive={isActive} seconds={seconds} />;
  if (error) return error;
  return emptyText;
}

function wait(ms) {
  return new Promise((resolve) => {
    window.setTimeout(resolve, ms);
  });
}

export default function BridgeupSurveyPage() {
  const [questions, setQuestions] = useState([]);
  const [current, setCurrent] = useState(0);
  const [answers, setAnswers] = useState({});
  const [rawScores, setRawScores] = useState({});
  const [scoringConfig, setScoringConfig] = useState(DEFAULT_SCORING_CONFIG);
  const [recommendation, setRecommendation] = useState(null);
  const [scoreSummary, setScoreSummary] = useState(null);
  const [activeSections, setActiveSections] = useState({});
  const [sectionErrors, setSectionErrors] = useState({});
  const [analysisSeconds, setAnalysisSeconds] = useState(0);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [error, setError] = useState("");
  const [loadingConfig, setLoadingConfig] = useState(true);
  const [warmingUp, setWarmingUp] = useState(true);

  useEffect(() => {
    let cancelled = false;

    async function warmUpAi() {
      try {
        const response = await fetch("/api/bridgeup/warmup");
        if (!response.ok) throw new Error("Warmup request failed");
      } catch {
        if (!cancelled) setWarmingUp(false);
        return;
      }
      if (!cancelled) setWarmingUp(false);
    }

    async function loadSurveyConfig() {
      try {
        const response = await fetch("/api/bridgeup/survey-config");
        if (!response.ok) throw new Error("Config request failed");

        const config = await response.json();
        if (cancelled) return;

        setQuestions(config.questions || []);
        setScoringConfig({ ...DEFAULT_SCORING_CONFIG, ...(config.scoring || {}) });
      } catch {
        if (!cancelled) setError("Không tải được khảo sát. Vui lòng thử lại.");
      } finally {
        if (!cancelled) setLoadingConfig(false);
      }
    }

    warmUpAi();
    loadSurveyConfig();
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!isSubmitting || Object.keys(activeSections).length === 0) {
      setAnalysisSeconds(0);
      return undefined;
    }

    setAnalysisSeconds(0);
    const intervalId = window.setInterval(() => {
      setAnalysisSeconds((prev) => prev + 1);
    }, 1000);

    return () => window.clearInterval(intervalId);
  }, [isSubmitting, activeSections]);

  const currentQuestion = questions[current];
  const hasQuestions = questions.length > 0;
  const isLastQuestion = current === questions.length - 1;
  const hasAnsweredCurrentQuestion = Boolean(currentQuestion && answers[currentQuestion.id]);
  const progress = hasQuestions ? ((current + 1) / questions.length) * 100 : 0;
  const showDashboard = Boolean(scoreSummary || recommendation || isSubmitting);

  function markSectionActive(section, active) {
    setActiveSections((prev) => {
      if (active) return { ...prev, [section]: true };
      if (!prev[section]) return prev;
      const next = { ...prev };
      delete next[section];
      return next;
    });
  }

  async function postRecommendationSection(url, body, section) {
    markSectionActive(section, true);

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });

      if (!response.ok) {
        let message = `${section} request failed`;
        try {
          const errorPayload = await response.json();
          message = errorPayload.message || message;
        } catch {}
        throw new Error(message);
      }

      const payload = await response.json();
      return payload.data;
    } finally {
      markSectionActive(section, false);
    }
  }

  async function submitSurvey(nextRawScores = rawScores, nextAnswers = answers) {
    const scores = calculateCategoryScores(nextRawScores, scoringConfig);
    const requestBody = {
      answers: nextAnswers,
      rawScores: nextRawScores,
      scores,
      scoring: scoringConfig,
    };

    setIsSubmitting(true);
    setScoreSummary(scores);
    setRecommendation(createRecommendationSkeleton(scores));
    setActiveSections({});
    setSectionErrors({});
    setError("");

    try {
      const nextSectionErrors = {};
      let failedCount = 0;
      const totalTasks = CORE_SECTION_TASKS.length + RESULT_ORDER.length;
      const avoidHints = { strength: [], weak: [] };

      async function streamPlainSection(section, text) {
        const tokens = String(text || "").split(/(\s+)/).filter((token) => token.length > 0);
        if (!tokens.length) {
          setRecommendation((prev) => (prev ? { ...prev, [section]: String(text || "") } : prev));
          return;
        }

        let merged = "";
        for (const token of tokens) {
          merged += token;
          setRecommendation((prev) => (prev ? { ...prev, [section]: merged } : prev));
          await wait(STREAM_STEP_MS);
        }
      }

      async function streamDimensionSection(key, data) {
        const score = Number(data?.score || 0);
        setRecommendation((prev) => {
          if (!prev) return prev;
          return {
            ...prev,
            dimensions: {
              ...prev.dimensions,
              [key]: {
                ...prev.dimensions[key],
                score,
              },
            },
          };
        });

        for (const field of ["strength", "weak", "insight"]) {
          const tokens = String(data?.[field] || "").split(/(\s+)/).filter((token) => token.length > 0);
          if (!tokens.length) continue;

          let merged = "";
          for (const token of tokens) {
            merged += token;
            setRecommendation((prev) => {
              if (!prev) return prev;
              return {
                ...prev,
                dimensions: {
                  ...prev.dimensions,
                  [key]: {
                    ...prev.dimensions[key],
                    [field]: merged,
                  },
                },
              };
            });
            await wait(field === "insight" ? INSIGHT_STREAM_STEP_MS : STREAM_STEP_MS);
          }
        }
      }

      for (const { section, url } of CORE_SECTION_TASKS) {
        try {
          const data = await postRecommendationSection(url, requestBody, section);
          await streamPlainSection(section, data);
        } catch (sectionError) {
          failedCount += 1;
          nextSectionErrors[section] = sectionError?.message || "Tải phân tích thất bại.";
        }
      }

      for (const key of RESULT_ORDER) {
        try {
          const payload = {
            ...requestBody,
            avoidHints: {
              strength: [...avoidHints.strength],
              weak: [...avoidHints.weak],
            },
          };
          const data = await postRecommendationSection(`/api/bridgeup/recommendation/dimension/${key}`, payload, key);
          await streamDimensionSection(key, data);

          if (data?.strength) avoidHints.strength.push(data.strength);
          if (data?.weak) avoidHints.weak.push(data.weak);
        } catch (sectionError) {
          failedCount += 1;
          nextSectionErrors[key] = sectionError?.message || "Tải phân tích thất bại.";
        }
      }

      setSectionErrors(nextSectionErrors);

      if (failedCount === totalTasks) throw new Error("All recommendation tasks failed");
      if (failedCount > 0) setError("Một vài phần phân tích chưa tải xong. Bạn có thể thử lại khảo sát.");
    } catch {
      setError("Không thể lấy phản hồi từ AI.");
    } finally {
      setIsSubmitting(false);
    }
  }

  function selectOption(option) {
    if (!currentQuestion || isSubmitting) return;

    const nextAnswers = { ...answers, [currentQuestion.id]: option };
    const nextRawScores = { ...rawScores, [currentQuestion.id]: option.score };

    setAnswers(nextAnswers);
    setRawScores(nextRawScores);
    setError("");

    if (isLastQuestion) {
      submitSurvey(nextRawScores, nextAnswers);
      return;
    }

    setCurrent((prev) => prev + 1);
  }

  function goPrev() {
    if (current > 0 && !isSubmitting) setCurrent((prev) => prev - 1);
  }

  function goNext() {
    if (current < questions.length - 1 && !isSubmitting && hasAnsweredCurrentQuestion) {
      setCurrent((prev) => prev + 1);
    }
  }

  function restartSurvey() {
    setCurrent(0);
    setAnswers({});
    setRawScores({});
    setRecommendation(null);
    setScoreSummary(null);
    setActiveSections({});
    setSectionErrors({});
    setAnalysisSeconds(0);
    setIsSubmitting(false);
    setError("");
  }

  return (
    <section className="section page-banner bridgeup-demo-page bridgeup-modern">
      <div className="container bridgeup-shell">
        <main className="bridgeup-module page-shell">
          <section className="survey-card">
            {!showDashboard ? (
              <>
                <div className="hero-band">
                  <p className="eyebrow">BridgeUp AI Coach</p>
                  <h1>GrowCap Recommendation</h1>
                  <p className="hero-copy">
                    BridgeUp giúp bạn nhìn rõ 5 đỉnh phát triển cốt lõi: nghề nghiệp, sức khỏe, học tập,
                    hạnh phúc và cống hiến. Trả lời đủ khảo sát để nhận phân tích từ mô hình.
                  </p>
                </div>

                <div className="progress-track" aria-hidden="true">
                  <div className="progress-fill" style={{ width: `${progress}%` }} />
                </div>

                {loadingConfig || warmingUp ? (
                  <div className="state-card">
                    {loadingConfig ? "Đang tải khảo sát..." : "Đang khởi động AI để chuẩn bị phân tích..."}
                  </div>
                ) : error && !hasQuestions ? (
                  <div className="state-card">{error}</div>
                ) : (
                  <section className="question-panel">
                    <div className="question-meta">
                      <span>{`Câu ${current + 1}/${questions.length}`}</span>
                      <span>{toCategoryLabel(currentQuestion?.category || "")}</span>
                    </div>
                    <h2>{currentQuestion?.question}</h2>

                    <div className="option-grid">
                      {currentQuestion?.options.map((option) => {
                        const selected = answers[currentQuestion.id]?.label === option.label;

                        return (
                          <button
                            key={`${currentQuestion.id}-${option.label}`}
                            type="button"
                            className={`option-card${selected ? " selected" : ""}`}
                            onClick={() => selectOption(option)}
                            disabled={isSubmitting}
                          >
                            <span>{option.label}</span>
                          </button>
                        );
                      })}
                    </div>

                    <div className="nav-row">
                      <button type="button" className="nav-btn ghost" onClick={goPrev} disabled={current === 0 || isSubmitting}>
                        Back
                      </button>
                      <button
                        type="button"
                        className="nav-btn"
                        onClick={goNext}
                        disabled={isLastQuestion || isSubmitting || !hasAnsweredCurrentQuestion}
                      >
                        Next
                      </button>
                    </div>
                  </section>
                )}
              </>
            ) : (
              <section className="dashboard-shell">
                <header className="dashboard-header">
                  <div>
                    <p className="eyebrow">BridgeUp Result Canvas</p>
                    <h1>Growth Dashboard</h1>
                    <p className="dashboard-copy">
                      Hệ thống tổng hợp điểm, chân dung hiện tại, hành động ưu tiên và insight cho từng đỉnh phát triển.
                    </p>
                  </div>
                  <button type="button" className="nav-btn dashboard-cta ghost" onClick={restartSurvey}>
                    Làm lại khảo sát
                  </button>
                </header>

                <section className="dashboard-summary-grid">
                  <article className="result-card feature-card">
                    <p className="section-kicker">Chân dung hiện tại</p>
                    <p className="summary-text">
                      {renderTaskContent(recommendation?.currentPortrait, {
                        isSubmitting,
                        isActive: Boolean(activeSections.currentPortrait),
                        seconds: analysisSeconds,
                        emptyText: "Chưa có dữ liệu.",
                        error: sectionErrors.currentPortrait || "",
                      })}
                    </p>
                  </article>

                  <article className="result-card feature-card feature-card-alt">
                    <p className="section-kicker">Hành động tiếp theo</p>
                    <p className="summary-text">
                      {renderTaskContent(recommendation?.nextAction, {
                        isSubmitting,
                        isActive: Boolean(activeSections.nextAction),
                        seconds: analysisSeconds,
                        emptyText: "Chưa có dữ liệu.",
                        error: sectionErrors.nextAction || "",
                      })}
                    </p>
                  </article>
                </section>

                <section className="score-strip">
                  {RESULT_ORDER.map((key) => {
                    const meta = CATEGORY_META[key];
                    const item = recommendation?.dimensions?.[key];
                    const fallbackScore = scoreSummary?.[key];

                    return (
                      <article key={key} className="score-chip">
                        <span className="score-chip-label">{meta.shortLabel}</span>
                        <strong>{formatScore(item?.score ?? fallbackScore)}</strong>
                        <span className={`score-chip-line ${meta.accent}`} />
                      </article>
                    );
                  })}
                </section>

                <section className="dashboard-grid">
                  {RESULT_ORDER.map((key) => {
                    const meta = CATEGORY_META[key];
                    const item = recommendation?.dimensions?.[key];
                    const fallbackScore = scoreSummary?.[key];
                    const isActive = Boolean(activeSections[key]);

                    return (
                      <article key={key} className={`result-card dimension-card ${meta.accent}`}>
                        <div className="dimension-head">
                          <div>
                            <p className="section-kicker">{meta.label}</p>
                            <h3>{meta.title}</h3>
                          </div>
                          <div className="dimension-score">
                            <span>Score</span>
                            <strong>{formatScore(item?.score ?? fallbackScore)}</strong>
                          </div>
                        </div>

                        <div className="metric-stack">
                          <div className="metric-block">
                            <span className="metric-label">Strength</span>
                            <p>
                              {renderTaskContent(item?.strength, {
                                isSubmitting,
                                isActive,
                                seconds: analysisSeconds,
                                emptyText: "Chưa có dữ liệu.",
                                error: sectionErrors[key] || "",
                              })}
                            </p>
                          </div>

                          <div className="metric-block">
                            <span className="metric-label">Weakness</span>
                            <p>
                              {renderTaskContent(item?.weak, {
                                isSubmitting,
                                isActive,
                                seconds: analysisSeconds,
                                emptyText: "Chưa có dữ liệu.",
                                error: sectionErrors[key] || "",
                              })}
                            </p>
                          </div>

                          <div className="metric-block">
                            <span className="metric-label">Insight</span>
                            <p>
                              {renderTaskContent(item?.insight, {
                                isSubmitting,
                                isActive,
                                seconds: analysisSeconds,
                                emptyText: "Chưa có dữ liệu.",
                                error: sectionErrors[key] || "",
                              })}
                            </p>
                          </div>
                        </div>
                      </article>
                    );
                  })}
                </section>

                {error && <div className="state-card inline-error">{error}</div>}
              </section>
            )}
          </section>
        </main>
      </div>
    </section>
  );
}







