import { useRef, useState, useEffect } from "react";
import { supabase } from "./supabaseClient";

import ReactMarkdown from "react-markdown";

const getEnv = (key) => {
  if (typeof window !== "undefined" && window.__ENV__ && window.__ENV__[key]) {
    return window.__ENV__[key];
  }
  return import.meta.env[key];
};

const API_BASE_URL = getEnv("VITE_API_BASE_URL") || "/api";

const Panel = ({ title, subtitle, children }) => (
  <div className="card">
    <div className="card-head">
      <div>
        <h2>{title}</h2>
        {subtitle ? <p className="card-subtitle">{subtitle}</p> : null}
      </div>
    </div>
    {children}
  </div>
);

const ProgressStrip = ({ statusText }) => (
  <pre className="result" style={{ whiteSpace: "pre-wrap" }}>
    {statusText || "Waiting for run..."}
  </pre>
);

export default function App() {
  const [view, setView] = useState("login"); // login | signup | otp | app
  const [emailDisplay, setEmailDisplay] = useState("");
  const [session, setSession] = useState(null);
  const [status, setStatus] = useState("");
  const [forceRefresh, setForceRefresh] = useState(false);
  const [urlValue, setUrlValue] = useState("");
  const [jobResult, setJobResult] = useState(null);
  const [systemPrompt, setSystemPrompt] = useState("");
  const [siteName, setSiteName] = useState("Bot");
  const [progressValue, setProgressValue] = useState(0);
  const [progressText, setProgressText] = useState("Idle");
  const [otpEmail, setOtpEmail] = useState("");
  const [firstNameDisplay, setFirstNameDisplay] = useState("");
  const [resetStatus, setResetStatus] = useState("");
  const [resetEmail, setResetEmail] = useState("");
  const [resetSent, setResetSent] = useState(false);
  const [resetOtpEntered, setResetOtpEntered] = useState(false);
  const [resetOtpValue, setResetOtpValue] = useState("");
  const [isRunning, setIsRunning] = useState(false);
  const [isAuthLoading, setIsAuthLoading] = useState(false);
  const resetEmailRef = useRef(null);
  const resetOtpRef = useRef(null);
  const resetNewPassRef = useRef(null);
  const resetNewPassConfirmRef = useRef(null);
  const [signupPassword, setSignupPassword] = useState("");
  const [summaryVisible, setSummaryVisible] = useState(false);
  const [summaryData, setSummaryData] = useState({ pages: 0, searches: 0 });
  const [isSessionChecking, setIsSessionChecking] = useState(true); // [NEW] Loading state for initial session check

  // [NEW] Check for existing session on mount
  useEffect(() => {
    // 1. Get initial session
    supabase.auth.getSession().then(({ data: { session } }) => {
      if (session) {
        setSession(session);
        setEmailDisplay(session.user?.email || "");
        const fn = session.user?.user_metadata?.first_name;
        setFirstNameDisplay(fn || (session.user?.email ? session.user.email.split("@")[0] : ""));
        setView("app");
        setStatus("Restored session.");
      }
      setIsSessionChecking(false);
    });

    // 2. Listen for changes (login, logout, auto-refresh)
    const {
      data: { subscription },
    } = supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session);
      if (session) {
        setEmailDisplay(session.user?.email || "");
        const fn = session.user?.user_metadata?.first_name;
        setFirstNameDisplay(fn || (session.user?.email ? session.user.email.split("@")[0] : ""));
        // Only switch to app if we were in a login/signup flow to avoid disrupting user
        setView((prev) => (prev === "login" || prev === "signup" || prev === "otp" || prev === "reset" ? "app" : prev));
      } else {
        // If logged out
        setView("login");
        setEmailDisplay("");
        setFirstNameDisplay("");
      }
    });

    return () => subscription.unsubscribe();
  }, []);

  // Refs to avoid re-rendering while typing (prevents cursor jump/blur)
  const loginEmailRef = useRef(null);
  const loginPassRef = useRef(null);
  const signupFirstRef = useRef(null);
  const signupLastRef = useRef(null);
  const signupEmailRef = useRef(null);
  const signupPassRef = useRef(null);
  const otpEmailRef = useRef(null);
  const otpPassRef = useRef(null);
  const otpCodeRef = useRef(null);
  const urlInputRef = useRef(null);

  const handleSignup = async () => {
    const email = signupEmailRef.current?.value?.trim() || "";
    const password = signupPassRef.current?.value || "";
    const first = signupFirstRef.current?.value?.trim() || "";
    const last = signupLastRef.current?.value?.trim() || "";
    setStatus("Signing up...");
    setSignupPassword(password);
    const { error } = await supabase.auth.signUp({
      email,
      password,
      options: { data: { first_name: first, last_name: last } },
    });
    if (error) {
      setStatus(`Signup failed: ${error.message}`);
    } else {
      setFirstNameDisplay(first || "");
      setStatus("Signup initiated. Check your email for OTP.");
      setOtpEmail(email);
      setView("otp");
    }
  };

  const handleVerifyOtp = async () => {
    const otp = otpCodeRef.current?.value?.trim() || "";
    setStatus("Verifying OTP...");
    const { error } = await supabase.auth.verifyOtp({
      email: otpEmail,
      token: otp,
      type: "signup",
    });
    if (error) {
      setStatus(`OTP failed: ${error.message}`);
    } else {
      const { data: loginData, error: loginError } =
        await supabase.auth.signInWithPassword({
          email: otpEmail,
          password: signupPassRef.current?.value || signupPassword || "",
        });
      if (loginError) {
        setStatus(`Verified; now log in. ${loginError.message}`);
        setView("login");
      } else {
        setSession(loginData.session);
        setEmailDisplay(loginData.session?.user?.email || otpEmail);
        const fn = loginData.session?.user?.user_metadata?.first_name;
        setFirstNameDisplay(fn || firstNameDisplay || "");
        setStatus("Account confirmed and logged in.");
        setView("app");
      }
    }
  };

  const handleLogin = async () => {
    if (isAuthLoading) return;
    setIsAuthLoading(true);
    const email = loginEmailRef.current?.value?.trim() || "";
    const password = loginPassRef.current?.value || "";
    setStatus("Logging in...");
    const { data, error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });
    if (error) {
      setStatus(`Login failed: ${error.message}`);
      setIsAuthLoading(false);
    } else {
      setView("app"); // jump to app immediately on success
      setSession(data.session);
      setEmailDisplay(data.session?.user?.email || email);
      const fn = data.session?.user?.user_metadata?.first_name;
      setFirstNameDisplay(fn || firstNameDisplay || (email ? email.split("@")[0] : ""));
      setStatus("Logged in.");
      setIsAuthLoading(false);
    }
  };

  const handleLogout = async () => {
    await supabase.auth.signOut();
    setSession(null);
    setJobResult(null);
    setSystemPrompt("");
    setEmailDisplay("");
    setChatMessages([]);
    if (chatInputRef.current) chatInputRef.current.value = "";
    setProgressValue(0);
    setProgressText("Idle");
    setStatus("Logged out.");
    setView("login");
  };

  const handleSendReset = async () => {
    const email =
      resetEmailRef.current?.value?.trim() ||
      resetEmail ||
      loginEmailRef.current?.value?.trim() ||
      "";
    if (!email) {
      setResetStatus("Enter an email to reset.");
      return;
    }
    setResetEmail(email);
    setResetOtpEntered(false);
    setResetOtpValue("");
    setResetStatus("Sending reset OTP...");
    const { error } = await supabase.auth.resetPasswordForEmail(email);
    if (error) setResetStatus(`Failed: ${error.message}`);
    else {
      setResetStatus("Reset OTP sent. Check your email.");
      setResetSent(true);
    }
  };

  const handleVerifyResetOtp = () => {
    const otp = resetOtpRef.current?.value?.trim() || "";
    if (!otp) {
      setResetStatus("Enter the OTP you received.");
      return;
    }
    setResetOtpValue(otp);
    setResetOtpEntered(true);
    setResetStatus("OTP captured. Enter new password.");
  };

  const handleConfirmReset = async () => {
    const email =
      resetEmailRef.current?.value?.trim() ||
      resetEmail ||
      loginEmailRef.current?.value?.trim() ||
      "";
    const otp = resetOtpValue;
    const newPass = resetNewPassRef.current?.value || "";
    const newPassConfirm = resetNewPassConfirmRef.current?.value || "";
    if (!email || !otp || !newPass) {
      setResetStatus("Enter OTP and new password.");
      return;
    }
    if (newPass !== newPassConfirm) {
      setResetStatus("New password and confirm password do not match.");
      return;
    }
    setResetEmail(email);
    setResetStatus("Resetting password...");
    const { data: verifyData, error: verifyError } = await supabase.auth.verifyOtp({
      email,
      token: otp,
      type: "recovery",
    });
    if (verifyError) {
      setResetStatus(`Failed: ${verifyError.message}`);
      return;
    }

    // After OTP verification, update the password
    const { error: updateError } = await supabase.auth.updateUser({
      password: newPass,
    });
    if (updateError) {
      setResetStatus(`Failed: ${updateError.message}`);
      return;
    }

    setResetStatus("Password reset. You can log in now.");
    setResetSent(false);
    setResetOtpEntered(false);
    setResetOtpValue("");
    if (resetNewPassRef.current) resetNewPassRef.current.value = "";
    if (resetNewPassConfirmRef.current) resetNewPassConfirmRef.current.value = "";
    setView("login");
  };

  const runJob = async () => {
    const targetUrl = (urlInputRef.current?.value || "").trim();
    if (!targetUrl) {
      setStatus("Please enter a URL.");
      return;
    }
    setIsRunning(true);
    setStatus("Submitting job...");
    setJobResult(null);
    setSystemPrompt("");
    setChatMessages([]);
    if (chatInputRef.current) chatInputRef.current.value = "";
    setProgressValue(10);
    setProgressText("Starting...");
    setSummaryVisible(false);
    try {
      const resp = await fetch(`${API_BASE_URL}/jobs/run`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          url: targetUrl,
          force_refresh: forceRefresh,
          user_id: session?.user?.id
        }),
      });
      if (!resp.ok) {
        const msg = await resp.text();
        throw new Error(msg || `HTTP ${resp.status}`);
      }
      const json = await resp.json();
      setJobResult(json);
      const statusText = json?.stats?.status_text || "Completed.";
      setStatus("Job completed.");
      setSystemPrompt(json?.stats?.system_prompt || "");
      setSiteName(json?.stats?.name || "Bot");
      setJobResult((prev) => ({ ...prev, status_text: statusText }));
      setProgressText(statusText);
      const match = statusText.match(/Progress:\s*([0-9]{1,3})%/i);
      setProgressValue(match ? Math.min(100, Math.max(0, parseInt(match[1], 10))) : 100);
      setSummaryData({
        pages: json?.stats?.pages_scraped ?? 0,
        searches: json?.stats?.searches_run ?? 0,
      });
      setSummaryVisible(true);
      setTimeout(() => setSummaryVisible(false), 5000);
    } catch (err) {
      console.error("Job failed", err);
      setStatus(`Job failed: ${err.message} | API: ${API_BASE_URL}`);
      setProgressText("Failed");
      setProgressValue(0);
    } finally {
      setIsRunning(false);
    }
  };

  const renderHeader = () => (
    <header className="hero">
      <div>
        <h1>ChatSmith</h1>
        <p className="muted">
          {firstNameDisplay
            ? `Welcome, ${firstNameDisplay}`
            : emailDisplay
              ? `Welcome, ${emailDisplay.split("@")[0]}`
              : "Welcome"}
        </p>
        <p className="hero-subtitle">AI-powered chatbot generator for any website.</p>
      </div>
      <div className="status">{status}</div>
    </header>
  );

  const renderLoginCard = () => (
    <Panel title="Login" subtitle="AI-powered chatbot generator for any website.">
      <input
        placeholder="Email"
        ref={loginEmailRef}
        defaultValue=""
      />
      <input
        placeholder="Password"
        type="password"
        ref={loginPassRef}
        defaultValue=""
      />
      <button onClick={handleLogin} disabled={isAuthLoading} className={isAuthLoading ? "loading" : ""}>
        {isAuthLoading ? "Logging in..." : "Log In"}
      </button>
      <p className="link" onClick={() => setView("signup")}>
        Don’t have an account? Sign up
      </p>
      <div className="muted small" style={{ marginTop: 8, cursor: "pointer" }} onClick={() => setView("reset")}>
        Forgot password?
      </div>
    </Panel>
  );

  const renderSignupCard = () => (
    <Panel title="Sign Up" subtitle="Create your account and start building.">
      <input
        placeholder="First name"
        ref={signupFirstRef}
        defaultValue=""
      />
      <input placeholder="Last name" ref={signupLastRef} defaultValue="" />
      <input placeholder="Email" ref={signupEmailRef} defaultValue="" />
      <input placeholder="Password" type="password" ref={signupPassRef} defaultValue="" />
      <button onClick={handleSignup}>Sign Up</button>
      <p className="link" onClick={() => setView("login")}>
        Back to login
      </p>
    </Panel>
  );

  const renderResetCard = () => (
    <Panel title="Reset Password" subtitle="Securely recover access with OTP.">
      {!resetSent && (
        <>
          <input
            placeholder="Email for reset"
            ref={resetEmailRef}
            defaultValue=""
          />
          <button onClick={handleSendReset}>Send reset OTP</button>
        </>
      )}
      {resetSent && !resetOtpEntered && (
        <>
          <input
            placeholder="Reset OTP"
            ref={resetOtpRef}
            defaultValue=""
          />
          <button onClick={handleVerifyResetOtp}>Verify OTP</button>
        </>
      )}
      {resetSent && resetOtpEntered && (
        <>
          <div className="muted small">OTP captured. Enter new password.</div>
          <input
            placeholder="New password"
            type="password"
            ref={resetNewPassRef}
            defaultValue=""
          />
          <input
            placeholder="Confirm new password"
            type="password"
            ref={resetNewPassConfirmRef}
            defaultValue=""
          />
          <button onClick={handleConfirmReset}>Confirm reset</button>
        </>
      )}
      <div className="status">{resetStatus}</div>
      <p className="link" onClick={() => setView("login")}>
        Back to login
      </p>
    </Panel>
  );

  const renderOtpCard = () => (
    <Panel title="Enter OTP" subtitle="Check your inbox for the 6-digit code.">
      <div className="muted small">OTP sent to: {otpEmail || "your email"}</div>
      <input placeholder="OTP code" ref={otpCodeRef} defaultValue="" />
      <button onClick={handleVerifyOtp}>Verify OTP & Login</button>
      <p className="link" onClick={() => setView("login")}>
        Back to login
      </p>
    </Panel>
  );

  const renderAppCards = () => (
    <div className="grid single-column">
      <Panel title="Generate Chatbot" subtitle="Paste a URL and generate a chatbot instantly.">
        <label className="label">Website URL</label>
        <input
          placeholder="https://example.com"
          defaultValue={urlValue}
          ref={urlInputRef}
          autoCorrect="off"
          autoCapitalize="none"
          spellCheck={false}
          onChange={(e) => setUrlValue(e.target.value)}
        />
        <label className="checkbox">
          <input type="checkbox" checked={forceRefresh} onChange={(e) => setForceRefresh(e.target.checked)} />
          Force refresh
        </label>
        <button className={isRunning ? "loading" : ""} onClick={runJob} disabled={isRunning}>
          {isRunning ? "Running..." : "Run"}
        </button>
        <p className="muted small generate-desc">Paste a URL and generate a chatbot instantly. Scrape → gap detection → targeted search → knowledge base.</p>

        <div className="progress-container">
          <div className="progress-bar" style={{ width: `${progressValue}%` }} />
        </div>

        {systemPrompt && (
          <>
            <hr style={{ border: "1px solid rgba(255,255,255,0.06)" }} />
            {summaryVisible ? (
              <div className="card summary-card">
                <h3>Summary</h3>
                <p className="muted small">Pages scraped: {summaryData.pages}</p>
                <p className="muted small">Web searches: {summaryData.searches}</p>
              </div>
            ) : (
              <>
                <div className="muted small">Chatbot: {siteName}</div>
                <div className="chat-box">
                  {chatMessages.length === 0 && <div className="muted">Ask anything about the scraped site.</div>}
                  {chatMessages.map((m, idx) => (
                    <div key={idx} className={`chat-msg ${m.role}`}>
                      <strong>{m.role === "user" ? "You" : siteName}:</strong>
                      <div className="md-content">
                        <ReactMarkdown>{m.content}</ReactMarkdown>
                      </div>
                    </div>
                  ))}
                </div>
                <textarea
                  rows={4}
                  placeholder="Type your question..."
                  ref={chatInputRef}
                  defaultValue=""
                />
                <button onClick={sendChat}>Send</button>
                <div className="status">{chatStatus}</div>
              </>
            )}
          </>
        )}
      </Panel>

      <div className="logout-row">
        <button className="link logout-small" onClick={handleLogout}>Log out</button>
      </div>
    </div>
  );

  const [chatMessages, setChatMessages] = useState([]);
  const chatInputRef = useRef(null);
  const [chatStatus, setChatStatus] = useState("");

  const sendChat = async () => {
    const text = chatInputRef.current?.value || "";
    if (!text.trim()) return;
    const newMessages = [...chatMessages, { role: "user", content: text }];
    setChatMessages(newMessages);
    if (chatInputRef.current) chatInputRef.current.value = "";
    setChatStatus("Thinking...");
    try {
      const resp = await fetch(`${API_BASE_URL}/chat`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          system_prompt: systemPrompt,
          messages: newMessages,
          user_id: session?.user?.id
        }),
      });
      if (!resp.ok) {
        const msg = await resp.text();
        throw new Error(msg || `HTTP ${resp.status}`);
      }
      const json = await resp.json();
      const assistantMsg = json?.message;
      setChatMessages([...newMessages, assistantMsg]);
      setChatStatus("Ready");
    } catch (err) {
      console.error("Chat failed", err);
      setChatStatus(`Chat failed: ${err.message}`);
    }
  };

  return (
    <div className="app-shell">
      {renderHeader()}

      {isSessionChecking ? (
        <div className="auth-page">
          <div className="auth-stage">
            <div className="auth-card-wrap">
              <Panel title="Loading..." subtitle="Checking authentication status...">
                <div style={{ textAlign: "center", padding: "20px" }}>
                  <div className="loading" style={{ margin: "0 auto" }}></div>
                </div>
              </Panel>
            </div>
          </div>
        </div>
      ) : (
        <>
          {view === "login" && (
            <div className="auth-page">
              <div className="auth-stage">
                <div className="auth-card-wrap">
                  {renderLoginCard()}
                </div>
              </div>
            </div>
          )}

          {view === "signup" && (
            <div className="auth-page">
              <div className="auth-stage">
                <div className="auth-card-wrap">
                  {renderSignupCard()}
                </div>
              </div>
            </div>
          )}

          {view === "reset" && (
            <div className="auth-page">
              <div className="auth-stage">
                <div className="auth-card-wrap">
                  {renderResetCard()}
                </div>
              </div>
            </div>
          )}

          {view === "otp" && (
            <div className="auth-page">
              <div className="auth-stage">
                <div className="auth-card-wrap">
                  {renderOtpCard()}
                </div>
              </div>
            </div>
          )}

          {view === "app" && (
            <div className="main-page">
              <div className="main-card-wrap">
                {renderAppCards()}
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
}
