const { useState } = React;

const formatCurrency = (val) =>
  new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 }).format(val);

function calculateMonthly(price, downPct, rate) {
  const principal = price * (1 - downPct / 100);
  if (principal <= 0) return 0;
  const monthlyRate = rate / 100 / 12;
  if (monthlyRate === 0) return principal / 360;
  return (principal * monthlyRate * Math.pow(1 + monthlyRate, 360)) / (Math.pow(1 + monthlyRate, 360) - 1);
}

function SliderInput({ label, value, onChange, min, max, step, format, suffix, unit }) {
  const [localText, setLocalText] = useState(null);
  const pct = ((value - min) / (max - min)) * 100;

  return (
    <div style={{ marginBottom: 24 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
        <label style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a", fontFamily: "'Karla', sans-serif" }}>{label}</label>
        <div style={{ display: "flex", alignItems: "baseline", gap: 4 }}>
          {unit === "prefix" && <span style={{ fontSize: 18, color: "#555", fontFamily: "'Libre Baskerville', serif" }}>$</span>}
          <input
            type="text"
            value={localText !== null ? localText : (format ? format(value) : value)}
            onFocus={() => setLocalText(String(value))}
            onBlur={() => {
              const num = parseFloat(localText);
              if (!isNaN(num)) onChange(Math.min(max, Math.max(min, num)));
              setLocalText(null);
            }}
            onChange={(e) => setLocalText(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") e.target.blur();
            }}
            style={{
              fontSize: 26,
              fontFamily: "'Libre Baskerville', serif",
              fontWeight: 400,
              color: "#1a1a1a",
              background: "transparent",
              border: "none",
              borderBottom: "1.5px solid #ddd",
              outline: "none",
              textAlign: "right",
              width: unit === "prefix" ? 170 : 80,
              padding: "2px 0",
              transition: "border-color 0.2s",
            }}
          />
          {suffix && <span style={{ fontSize: 16, color: "#888", fontFamily: "'Karla', sans-serif" }}>{suffix}</span>}
        </div>
      </div>
      <div style={{ position: "relative", height: 32, display: "flex", alignItems: "center" }}>
        <div style={{ position: "absolute", left: 0, right: 0, height: 3, background: "#e8e8e8", borderRadius: 2 }} />
        <div style={{ position: "absolute", left: 0, width: `${pct}%`, height: 3, background: "linear-gradient(90deg, #2a2a2a, #555)", borderRadius: 2 }} />
        <input
          type="range"
          min={min}
          max={max}
          step={step}
          value={value}
          onChange={(e) => onChange(parseFloat(e.target.value))}
          style={{
            position: "absolute",
            width: "100%",
            height: 32,
            opacity: 0,
            cursor: "pointer",
            margin: 0,
          }}
        />
        <div
          style={{
            position: "absolute",
            left: `${pct}%`,
            transform: "translateX(-50%)",
            width: 18,
            height: 18,
            borderRadius: "50%",
            background: "#1a1a1a",
            boxShadow: "0 2px 8px rgba(0,0,0,0.18)",
            pointerEvents: "none",
            transition: "box-shadow 0.2s",
          }}
        />
      </div>
      <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6, fontSize: 10, color: "#bbb", fontFamily: "'Karla', sans-serif" }}>
        <span>{unit === "prefix" ? formatCurrency(min) : `${min}${suffix || ""}`}</span>
        <span>{unit === "prefix" ? formatCurrency(max) : `${max}${suffix || ""}`}</span>
      </div>
    </div>
  );
}

function MortgageCalculator() {
  const [price, setPrice] = useState(4000000);
  const [downPct, setDownPct] = useState(20);
  const [rate, setRate] = useState(6);
  const [monthlyFees, setMonthlyFees] = useState(4400);
  const [tableIncludeFees, setTableIncludeFees] = useState(true);

  const monthly = calculateMonthly(price, downPct, rate);
  const principal = price * (1 - downPct / 100);
  const totalInterest = monthly * 360 - principal;
  const totalMonthly = monthly + monthlyFees;

  const prices = [];
  for (let p = 3400000; p <= 4100000; p += 50000) prices.push(p);
  const rates = [];
  for (let r = 5.25; r <= 6.25; r = Math.round((r + 0.125) * 1000) / 1000) rates.push(r);

  const isActivePrice = (p) => p === price;
  const isActiveRate = (r) => Math.abs(r - rate) < 0.001;

  return (
    <div style={{ minHeight: "100vh", display: "flex", alignItems: "flex-start", justifyContent: "center", fontFamily: "'Karla', sans-serif", padding: "16px 24px" }}>
      <link href="https://fonts.googleapis.com/css2?family=Karla:wght@400;500;600&family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet" />
      <div style={{ width: "100%", maxWidth: 860 }}>
        <div style={{ marginBottom: 28, textAlign: "center" }}>
          <h1 style={{ fontFamily: "'Libre Baskerville', serif", fontSize: 32, fontWeight: 400, color: "#1a1a1a", margin: 0, lineHeight: 1.1 }}>
            Mortgage Calculator
          </h1>
          <p style={{ fontSize: 12, color: "#aaa", marginTop: 4, letterSpacing: "0.05em" }}>30-year fixed rate</p>
        </div>

        <div style={{ maxWidth: 480, margin: "0 auto" }}>
          <SliderInput label="Purchase Price" value={price} onChange={setPrice} min={2000000} max={10000000} step={50000} format={(v) => v.toLocaleString()} unit="prefix" />
          
          <div style={{ marginBottom: 24 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
              <label style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a" }}>Down Payment</label>
              <div style={{ display: "flex", alignItems: "baseline", gap: 4 }}>
                <input
                  type="text"
                  value={downPct}
                  onChange={(e) => {
                    const num = parseFloat(e.target.value);
                    if (!isNaN(num)) setDownPct(Math.min(100, Math.max(0, num)));
                    else if (e.target.value === "") setDownPct(0);
                  }}
                  style={{
                    fontSize: 26,
                    fontFamily: "'Libre Baskerville', serif",
                    color: "#1a1a1a",
                    background: "transparent",
                    border: "none",
                    borderBottom: "1.5px solid #ddd",
                    outline: "none",
                    textAlign: "right",
                    width: 60,
                    padding: "2px 0",
                  }}
                />
                <span style={{ fontSize: 16, color: "#888" }}>%</span>
              </div>
            </div>
            <p style={{ fontSize: 12, color: "#aaa", margin: 0 }}>
              {formatCurrency(price * downPct / 100)} down · {formatCurrency(principal)} loan
            </p>
          </div>

          <SliderInput label="Interest Rate" value={rate} onChange={setRate} min={1} max={12} step={0.125} suffix="%" format={(v) => v.toFixed(3)} />

          <SliderInput label="Monthly Fees" value={monthlyFees} onChange={setMonthlyFees} min={1000} max={10000} step={100} format={(v) => v.toLocaleString()} unit="prefix" />

          <div style={{
            marginTop: 8,
            padding: "20px 0",
            borderTop: "1px solid #e8e8e8",
            display: "flex",
            gap: 0,
          }}>
            <div style={{ flex: 1, textAlign: "center", borderRight: "1px solid #e8e8e8" }}>
              <p style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a", margin: "0 0 8px 0" }}>Monthly Mortgage</p>
              <p style={{
                fontFamily: "'Libre Baskerville', serif",
                fontSize: 36,
                fontWeight: 400,
                color: "#1a1a1a",
                margin: 0,
                lineHeight: 1,
              }}>
                {formatCurrency(monthly)}
              </p>
              <div style={{ display: "flex", justifyContent: "center", gap: 24, marginTop: 12, fontSize: 11, color: "#aaa" }}>
                <div>
                  <span style={{ color: "#888", fontWeight: 500 }}>Total Interest</span>
                  <br />{formatCurrency(totalInterest)}
                </div>
                <div>
                  <span style={{ color: "#888", fontWeight: 500 }}>Total Cost</span>
                  <br />{formatCurrency(monthly * 360)}
                </div>
              </div>
            </div>
            <div style={{ flex: 1, textAlign: "center" }}>
              <p style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a", margin: "0 0 8px 0" }}>Total Monthly</p>
              <p style={{
                fontFamily: "'Libre Baskerville', serif",
                fontSize: 36,
                fontWeight: 400,
                color: "#1a1a1a",
                margin: 0,
                lineHeight: 1,
              }}>
                {formatCurrency(totalMonthly)}
              </p>
              <div style={{ marginTop: 12, fontSize: 11, color: "#aaa" }}>
                <span style={{ color: "#888", fontWeight: 500 }}>Mortgage + Fees</span>
                <br />{formatCurrency(monthly)} + {formatCurrency(monthlyFees)}
              </div>
            </div>
          </div>
        </div>

        {/* Sensitivity Table */}
        <div style={{ marginTop: 28, paddingTop: 24, borderTop: "1px solid #e8e8e8" }}>
          <p style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a", margin: "0 0 6px 0", textAlign: "center" }}>
            Sensitivity Table
          </p>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 12, margin: "0 0 16px 0" }}>
            <p style={{ fontSize: 12, color: "#bbb", margin: 0 }}>
              {tableIncludeFees ? "Total monthly" : "Mortgage only"} at {downPct}% down
            </p>
            <button
              onClick={() => setTableIncludeFees(!tableIncludeFees)}
              style={{
                display: "flex",
                alignItems: "center",
                gap: 6,
                padding: "4px 10px",
                fontSize: 10,
                fontWeight: 600,
                fontFamily: "'Karla', sans-serif",
                letterSpacing: "0.05em",
                color: tableIncludeFees ? "#fff" : "#666",
                background: tableIncludeFees ? "#1a1a1a" : "#f0f0f0",
                border: "none",
                borderRadius: 12,
                cursor: "pointer",
                transition: "all 0.2s",
              }}
            >
              {tableIncludeFees ? "Incl. Fees" : "+ Fees"}
            </button>
          </div>
          <div style={{ overflowX: "auto" }}>
            <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: "'Karla', sans-serif", fontSize: 12 }}>
              <thead>
                <tr>
                  <th style={{
                    padding: "8px 10px",
                    textAlign: "left",
                    fontSize: 10,
                    fontWeight: 600,
                    color: "#999",
                    letterSpacing: "0.05em",
                    borderBottom: "2px solid #e0e0e0",
                    position: "sticky",
                    left: 0,
                    background: "white",
                  }}>
                    Price \ Rate
                  </th>
                  {rates.map((r) => (
                    <th key={r} style={{
                      padding: "8px 8px",
                      textAlign: "right",
                      fontSize: 10,
                      fontWeight: 600,
                      color: isActiveRate(r) ? "#1a1a1a" : "#999",
                      letterSpacing: "0.03em",
                      borderBottom: "2px solid #e0e0e0",
                      background: isActiveRate(r) ? "#f5f5f0" : "transparent",
                    }}>
                      {r % 0.25 === 0 ? r.toFixed(2) : r.toFixed(3)}%
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {prices.map((p) => (
                  <tr key={p}>
                    <td style={{
                      padding: "7px 10px",
                      fontWeight: isActivePrice(p) ? 600 : 400,
                      color: isActivePrice(p) ? "#1a1a1a" : "#777",
                      borderBottom: "1px solid #f0f0f0",
                      whiteSpace: "nowrap",
                      position: "sticky",
                      left: 0,
                      background: isActivePrice(p) ? "#f5f5f0" : "white",
                      fontSize: 11,
                    }}>
                      {formatCurrency(p)}
                    </td>
                    {rates.map((r) => {
                      const val = calculateMonthly(p, downPct, r) + (tableIncludeFees ? monthlyFees : 0);
                      const highlight = isActivePrice(p) && isActiveRate(r);
                      const rowHL = isActivePrice(p);
                      const colHL = isActiveRate(r);
                      return (
                        <td key={r} style={{
                          padding: "7px 8px",
                          textAlign: "right",
                          fontFamily: "'Libre Baskerville', serif",
                          fontSize: 12,
                          color: highlight ? "#fff" : rowHL || colHL ? "#1a1a1a" : "#666",
                          fontWeight: highlight ? 700 : 400,
                          background: highlight ? "#1a1a1a" : rowHL || colHL ? "#f5f5f0" : "transparent",
                          borderBottom: "1px solid #f0f0f0",
                          borderRadius: highlight ? 4 : 0,
                          whiteSpace: "nowrap",
                        }}>
                          {formatCurrency(Math.round(val))}
                        </td>
                      );
                    })}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        {/* Closing Costs Table */}
        <div style={{ marginTop: 28, paddingTop: 24, borderTop: "1px solid #e8e8e8", maxWidth: 560, margin: "28px auto 0" }}>
          <p style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.12em", textTransform: "uppercase", color: "#8a8a8a", margin: "0 0 6px 0", textAlign: "center" }}>
            Cash Required at Close
          </p>
          <p style={{ fontSize: 12, color: "#bbb", margin: "0 0 20px 0", textAlign: "center" }}>
            Estimated NYC condo closing costs
          </p>
          {(() => {
            const loanAmount = price * (1 - downPct / 100);
            const downPayment = price * downPct / 100;
            const mansionTax = (() => {
              if (price < 1000000) return 0;
              if (price < 2000000) return price * 0.01;
              if (price < 3000000) return price * 0.0125;
              if (price < 5000000) return price * 0.0150;
              if (price < 10000000) return price * 0.0225;
              if (price < 15000000) return price * 0.0325;
              if (price < 20000000) return price * 0.0350;
              if (price < 25000000) return price * 0.0375;
              return price * 0.039;
            })();
            const mortgageRecordingTax = loanAmount >= 500000 ? loanAmount * 0.01925 : loanAmount * 0.018;
            const titleInsurance = price * 0.0045;
            const attorneyFees = 5000;
            const bankFees = 3500;
            const recordingFees = 750;
            const misc = 1500;
            const closingCostsTotal = mansionTax + mortgageRecordingTax + titleInsurance + attorneyFees + bankFees + recordingFees + misc;
            const totalCash = downPayment + closingCostsTotal;

            const rows = [
              { label: "Mansion Tax", amount: mansionTax, note: `NY state, progressive scale` },
              { label: "Mortgage Recording Tax", amount: mortgageRecordingTax, note: `1.925% of loan (over $500K)` },
              { label: "Title Insurance", amount: titleInsurance, note: `~0.45% of purchase price` },
              { label: "Buyer's Attorney", amount: attorneyFees, note: "Flat fee" },
              { label: "Bank Fees & Appraisal", amount: bankFees, note: "Lender charges" },
              { label: "Recording Fees", amount: recordingFees, note: "Deed & mortgage filing" },
              { label: "Miscellaneous", amount: misc, note: "Inspections, adjustments" },
            ];

            return (
              <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: "'Karla', sans-serif", fontSize: 13 }}>
                <tbody>
                  {rows.map((row, i) => (
                    <tr key={i}>
                      <td style={{ padding: "8px 10px", color: "#555", borderBottom: "1px solid #f0f0f0" }}>
                        {row.label}
                      </td>
                      <td style={{ padding: "8px 10px", color: "#aaa", fontSize: 11, borderBottom: "1px solid #f0f0f0" }}>
                        {row.note}
                      </td>
                      <td style={{ padding: "8px 10px", textAlign: "right", fontFamily: "'Libre Baskerville', serif", color: "#333", borderBottom: "1px solid #f0f0f0", whiteSpace: "nowrap" }}>
                        {formatCurrency(Math.round(row.amount))}
                      </td>
                    </tr>
                  ))}
                  <tr>
                    <td style={{ padding: "12px 10px 8px", fontWeight: 600, color: "#1a1a1a", borderTop: "2px solid #333", fontSize: 12, letterSpacing: "0.03em" }}>
                      CLOSING COSTS SUBTOTAL
                    </td>
                    <td style={{ padding: "12px 10px 8px", borderTop: "2px solid #333" }} />
                    <td style={{ padding: "12px 10px 8px", textAlign: "right", fontFamily: "'Libre Baskerville', serif", color: "#1a1a1a", fontWeight: 700, borderTop: "2px solid #333", fontSize: 15, whiteSpace: "nowrap" }}>
                      {formatCurrency(Math.round(closingCostsTotal))}
                    </td>
                  </tr>
                  <tr>
                    <td style={{ padding: "8px 10px", color: "#555" }}>
                      Down Payment
                    </td>
                    <td style={{ padding: "8px 10px", color: "#aaa", fontSize: 11 }}>
                      {downPct}% of purchase price
                    </td>
                    <td style={{ padding: "8px 10px", textAlign: "right", fontFamily: "'Libre Baskerville', serif", color: "#333", whiteSpace: "nowrap" }}>
                      {formatCurrency(Math.round(downPayment))}
                    </td>
                  </tr>
                  <tr>
                    <td style={{ padding: "14px 10px 10px", fontWeight: 700, color: "#1a1a1a", borderTop: "2px solid #1a1a1a", fontSize: 13, letterSpacing: "0.03em" }}>
                      TOTAL CASH AT CLOSE
                    </td>
                    <td style={{ padding: "14px 10px 10px", borderTop: "2px solid #1a1a1a" }} />
                    <td style={{ padding: "14px 10px 10px", textAlign: "right", fontFamily: "'Libre Baskerville', serif", color: "#1a1a1a", fontWeight: 700, borderTop: "2px solid #1a1a1a", fontSize: 20, whiteSpace: "nowrap" }}>
                      {formatCurrency(Math.round(totalCash))}
                    </td>
                  </tr>
                </tbody>
              </table>
            );
          })()}
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<MortgageCalculator />);
