// app/routes/app.dashboard.jsx — Live import progress dashboard
import { useEffect, useState, useRef, useCallback } from "react";
import { json } from "@remix-run/node";
import { useLoaderData, useNavigate } from "@remix-run/react";
import { Page, Layout, Card, Text, BlockStack, InlineStack, Badge, ProgressBar, Button, Spinner, Box, Divider } from "@shopify/polaris";
import { TitleBar } from "@shopify/app-bridge-react";
import { authenticate } from "../shopify.server";

const BACKEND = "https://backend.data4autos.com";
const POLL_INTERVAL = 3000;

export const loader = async ({ request }) => {
  const { session } = await authenticate.admin(request);
  return json({ shop: session.shop });
};

// ─── helpers ────────────────────────────────────────────────────────────────

function elapsed(startedAt) {
  if (!startedAt) return "—";
  const secs = Math.floor((Date.now() - new Date(startedAt).getTime()) / 1000);
  if (secs < 60) return `${secs}s`;
  const m = Math.floor(secs / 60), s = secs % 60;
  if (m < 60) return `${m}m ${s}s`;
  const h = Math.floor(m / 60), mm = m % 60;
  return `${h}h ${mm}m`;
}

function fmt(d) {
  if (!d) return "—";
  return new Date(d).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
}

function statusTone(status) {
  if (!status) return "subdued";
  if (status === "done") return "success";
  if (status === "error") return "critical";
  if (status === "cancelled") return "warning";
  if (status === "importing" || status === "fetching_products") return "info";
  return "subdued";
}

function statusLabel(status) {
  const map = {
    started: "Starting",
    fetching_products: "Fetching Products",
    importing: "Importing",
    done: "Completed",
    error: "Error",
    cancelled: "Cancelled",
    cancelling: "Cancelling…",
  };
  return map[status] || (status || "Unknown");
}

function stepLabel(step) {
  const map = {
    started: "Initialising",
    fetching_products: "Fetching products from Turn14",
    importing: "Creating / updating products in Shopify",
    completed: "Import complete",
    error: "Import stopped — error",
    cancelled: "Import cancelled",
  };
  return map[step] || step || "—";
}

function parseLogTone(line) {
  if (!line) return "subdued";
  if (line.includes("[PRODUCT-OK]") || line.includes("[IMPORT-DONE]") || line.includes("[FETCH-OK]")) return "success";
  if (line.includes("[PRODUCT-FAIL]") || line.includes("[ERROR]") || line.includes("[FETCH-FAIL]")) return "critical";
  if (line.includes("[SKIP]")) return "warning";
  if (line.includes("[PRODUCT]") || line.includes("[STATS]")) return "info";
  return "subdued";
}

function parseLogTitle(line) {
  if (!line) return "Log";
  if (line.includes("[PRODUCT-OK]")) return "Product created";
  if (line.includes("[PRODUCT-FAIL]")) return "Product failed";
  if (line.includes("[SKIP]")) return "Skipped duplicate";
  if (line.includes("[IMPORT-DONE]")) return "Import complete";
  if (line.includes("[IMPORT-START]")) return "Import started";
  if (line.includes("[FETCH-OK]")) return "Turn14 fetch success";
  if (line.includes("[FETCH-FAIL]")) return "Turn14 fetch failed";
  if (line.includes("[FETCH]")) return "Fetching from Turn14";
  if (line.includes("[STATS]")) return "Progress update";
  if (line.includes("[PRODUCT]")) return "Processing product";
  if (line.includes("[ERROR]")) return "Error";
  if (line.includes("[CANCEL]")) return "Cancelled";
  return "Activity";
}

const toneColors = {
  success: { bg: "#f0fdf4", border: "#bbf7d0", dot: "#16a34a", text: "#166534" },
  critical: { bg: "#fff1f2", border: "#fecdd3", dot: "#dc2626", text: "#991b1b" },
  warning:  { bg: "#fffbeb", border: "#fde68a", dot: "#d97706", text: "#92400e" },
  info:     { bg: "#eff6ff", border: "#bfdbfe", dot: "#2563eb", text: "#1e40af" },
  subdued:  { bg: "#f9fafb", border: "#e5e7eb", dot: "#9ca3af", text: "#6b7280" },
};

// ─── StatCard ────────────────────────────────────────────────────────────────
function StatCard({ label, value, sub, accent }) {
  const accents = {
    blue:   { bg: "#eff6ff", border: "#bfdbfe", val: "#1d4ed8" },
    green:  { bg: "#f0fdf4", border: "#bbf7d0", val: "#15803d" },
    red:    { bg: "#fff1f2", border: "#fecdd3", val: "#dc2626" },
    amber:  { bg: "#fffbeb", border: "#fde68a", val: "#b45309" },
    purple: { bg: "#faf5ff", border: "#e9d5ff", val: "#7c3aed" },
    slate:  { bg: "#f8fafc", border: "#e2e8f0", val: "#475569" },
  };
  const c = accents[accent] || accents.slate;
  return (
    <div style={{ background: c.bg, border: `1px solid ${c.border}`, borderRadius: 12, padding: "18px 20px", minWidth: 0 }}>
      <div style={{ fontSize: 12, fontWeight: 600, color: "#6b7280", textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 6 }}>{label}</div>
      <div style={{ fontSize: 28, fontWeight: 800, color: c.val, lineHeight: 1 }}>{value ?? "—"}</div>
      {sub && <div style={{ fontSize: 12, color: "#9ca3af", marginTop: 5 }}>{sub}</div>}
    </div>
  );
}

// ─── StageRow ─────────────────────────────────────────────────────────────────
function StageRow({ label, status, value, meta }) {
  const dotColor = status === "done" ? "#16a34a" : status === "active" ? "#2563eb" : status === "error" ? "#dc2626" : "#d1d5db";
  const textColor = status === "active" ? "#1d4ed8" : status === "done" ? "#166534" : "#6b7280";
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 0", borderBottom: "1px solid #f3f4f6" }}>
      <div style={{ width: 10, height: 10, borderRadius: "50%", background: dotColor, flexShrink: 0, boxShadow: status === "active" ? `0 0 0 3px ${dotColor}33` : "none" }} />
      <div style={{ flex: 1, fontSize: 14, fontWeight: status === "active" ? 700 : 500, color: textColor }}>{label}</div>
      {meta && <div style={{ fontSize: 12, color: "#9ca3af" }}>{meta}</div>}
      {value && (
        <div style={{ background: status === "done" ? "#f0fdf4" : status === "active" ? "#eff6ff" : "#f3f4f6", border: `1px solid ${status === "done" ? "#bbf7d0" : status === "active" ? "#bfdbfe" : "#e5e7eb"}`, borderRadius: 20, padding: "2px 10px", fontSize: 13, fontWeight: 700, color: status === "done" ? "#15803d" : status === "active" ? "#1d4ed8" : "#6b7280" }}>
          {value}
        </div>
      )}
    </div>
  );
}

// ─── LogEntry ────────────────────────────────────────────────────────────────
function LogEntry({ entry }) {
  const tone = parseLogTone(entry.line);
  const title = parseLogTitle(entry.line);
  const c = toneColors[tone];
  const cleanLine = entry.line.replace(/^\[[\w-]+\]\s*/, "");
  return (
    <div style={{ display: "flex", gap: 10, padding: "8px 0", borderBottom: "1px solid #f9fafb", alignItems: "flex-start" }}>
      <div style={{ width: 8, height: 8, borderRadius: "50%", background: c.dot, marginTop: 5, flexShrink: 0 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 12, fontWeight: 700, color: c.text }}>{title}</div>
        <div style={{ fontSize: 12, color: "#6b7280", wordBreak: "break-word", marginTop: 1 }}>{cleanLine}</div>
      </div>
      <div style={{ fontSize: 11, color: "#9ca3af", flexShrink: 0, paddingTop: 1 }}>{fmt(entry.at)}</div>
    </div>
  );
}

// ─── Main component ──────────────────────────────────────────────────────────
export default function Dashboard() {
  const { shop } = useLoaderData();
  const navigate = useNavigate();

  const [jobs, setJobs] = useState([]);
  const [selectedJobId, setSelectedJobId] = useState(null);
  const [job, setJob] = useState(null);
  const [loading, setLoading] = useState(true);
  const [tick, setTick] = useState(0);
  const [now, setNow] = useState(Date.now());
  const pollRef = useRef(null);

  // Fetch job list
  const fetchJobs = useCallback(async () => {
    try {
      const resp = await fetch(`${BACKEND}/jobs?shop=${encodeURIComponent(shop)}`);
      const data = await resp.json();
      const list = data.jobs || [];
      setJobs(list);
      if (!selectedJobId && list.length > 0) setSelectedJobId(list[0].id);
    } catch {}
  }, [shop, selectedJobId]);

  // Fetch selected job detail
  const fetchJob = useCallback(async (id) => {
    if (!id) return;
    try {
      const resp = await fetch(`${BACKEND}/jobs/${id}`);
      if (!resp.ok) return;
      const j = await resp.json();
      setJob(j);
    } catch {}
  }, []);

  // Initial load
  useEffect(() => {
    (async () => {
      setLoading(true);
      await fetchJobs();
      setLoading(false);
    })();
  }, []);

  // Select job when list arrives
  useEffect(() => {
    if (!selectedJobId && jobs.length > 0) setSelectedJobId(jobs[0].id);
  }, [jobs]);

  // Poll selected job
  useEffect(() => {
    if (!selectedJobId) return;
    fetchJob(selectedJobId);
    pollRef.current = setInterval(async () => {
      await fetchJob(selectedJobId);
      setTick(t => t + 1);
    }, POLL_INTERVAL);
    return () => clearInterval(pollRef.current);
  }, [selectedJobId]);

  // Elapsed timer
  useEffect(() => {
    const t = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(t);
  }, []);

  const handleCancel = async () => {
    if (!selectedJobId) return;
    await fetch(`${BACKEND}/jobs/${selectedJobId}/cancel`, { method: "POST" });
    fetchJob(selectedJobId);
  };

  const isRunning = job && (job.status === "importing" || job.status === "fetching_products" || job.status === "started");

  const s = job?.liveStats || { total: 0, processed: 0, created: 0, skipped: 0, failed: 0, remaining: 0, successRate: 0 };
  const progress = s.total > 0 ? Math.round((s.processed / s.total) * 100) : 0;
  const elapsedStr = job?.startedAt ? elapsed(job.startedAt) : "—";

  // Stage states
  const stageStatus = (stageName) => {
    if (!job) return "pending";
    if (job.status === "error" && job.step === stageName) return "error";
    if (job.step === stageName || job.status === stageName) return "active";
    const order = ["started", "fetching_products", "importing", "completed"];
    const jobIdx = order.indexOf(job.step || job.status);
    const stageIdx = order.indexOf(stageName);
    if (jobIdx > stageIdx) return "done";
    return "pending";
  };

  const recentLogs = [...(job?.logs || [])].reverse().slice(0, 10);

  return (
    <Page>
      <TitleBar title="Import Dashboard" />

      {/* ── Header ── */}
      <div style={{ background: "linear-gradient(135deg, #1e3a5f 0%, #2563eb 100%)", borderRadius: 16, padding: "28px 32px", marginBottom: 24, color: "#fff", display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 16 }}>
        <div>
          <div style={{ fontSize: 22, fontWeight: 800, marginBottom: 4 }}>📊 Import Dashboard</div>
          <div style={{ fontSize: 14, opacity: 0.8 }}>{shop}</div>
        </div>
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
          <button
            onClick={() => navigate("/app/managebrand")}
            style={{ background: "rgba(255,255,255,0.15)", border: "1px solid rgba(255,255,255,0.3)", borderRadius: 8, color: "#fff", padding: "8px 18px", cursor: "pointer", fontWeight: 600, fontSize: 14 }}
          >
            + New Import
          </button>
          {isRunning && (
            <button
              onClick={handleCancel}
              style={{ background: "#dc2626", border: "none", borderRadius: 8, color: "#fff", padding: "8px 18px", cursor: "pointer", fontWeight: 600, fontSize: 14 }}
            >
              Cancel Import
            </button>
          )}
        </div>
      </div>

      {loading ? (
        <Card><div style={{ padding: 48, textAlign: "center" }}><Spinner /><div style={{ marginTop: 12, color: "#6b7280" }}>Loading jobs…</div></div></Card>
      ) : jobs.length === 0 ? (
        <Card>
          <div style={{ padding: 64, textAlign: "center" }}>
            <div style={{ fontSize: 48, marginBottom: 12 }}>📦</div>
            <Text variant="headingMd" as="h2">No import jobs yet</Text>
            <div style={{ marginTop: 8, color: "#6b7280", marginBottom: 24 }}>Start an import from the Manage Brands page to see live progress here.</div>
            <Button variant="primary" onClick={() => navigate("/app/managebrand")}>Go to Manage Brands</Button>
          </div>
        </Card>
      ) : (
        <Layout>
          {/* ── Job selector sidebar ── */}
          {jobs.length > 1 && (
            <Layout.Section variant="oneThird">
              <Card>
                <div style={{ padding: "12px 16px 8px", borderBottom: "1px solid #f3f4f6" }}>
                  <Text variant="headingSm" as="h3" tone="subdued">RECENT IMPORTS</Text>
                </div>
                <div>
                  {jobs.slice(0, 10).map(j => (
                    <div
                      key={j.id}
                      onClick={() => setSelectedJobId(j.id)}
                      style={{ padding: "12px 16px", cursor: "pointer", borderBottom: "1px solid #f9fafb", background: j.id === selectedJobId ? "#eff6ff" : "transparent", borderLeft: j.id === selectedJobId ? "3px solid #2563eb" : "3px solid transparent" }}
                    >
                      <div style={{ fontWeight: 700, fontSize: 13, color: "#1f2937", marginBottom: 3 }}>{j.brandName || `Brand ${j.brandId}`}</div>
                      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                        <span style={{ fontSize: 11, color: toneColors[statusTone(j.status)].dot, fontWeight: 600 }}>● {statusLabel(j.status)}</span>
                        <span style={{ fontSize: 11, color: "#9ca3af" }}>{fmt(j.startedAt)}</span>
                      </div>
                    </div>
                  ))}
                </div>
              </Card>
            </Layout.Section>
          )}

          {/* ── Main job detail ── */}
          <Layout.Section>
            {job && (
              <BlockStack gap="400">

                {/* Status + Brand header */}
                <Card>
                  <BlockStack gap="300">
                    <InlineStack align="space-between" blockAlign="center" wrap={false}>
                      <BlockStack gap="100">
                        <Text variant="headingLg" as="h2">{job.brandName || `Brand ${job.brandId}`}</Text>
                        <Text tone="subdued" variant="bodySm">Job ID: {job.id}</Text>
                      </BlockStack>
                      <InlineStack gap="200" blockAlign="center">
                        {isRunning && <Spinner size="small" />}
                        <Badge tone={statusTone(job.status)}>{statusLabel(job.status)}</Badge>
                      </InlineStack>
                    </InlineStack>

                    <Divider />

                    {/* Progress bar */}
                    <BlockStack gap="100">
                      <InlineStack align="space-between">
                        <Text variant="bodySm" tone="subdued">{stepLabel(job.step)}</Text>
                        <Text variant="bodyMd" fontWeight="bold">{progress}%</Text>
                      </InlineStack>
                      <ProgressBar
                        progress={progress}
                        tone={job.status === "error" ? "critical" : job.status === "done" ? "success" : "highlight"}
                        size="medium"
                      />
                    </BlockStack>

                    {/* Timing row */}
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12 }}>
                      <div style={{ textAlign: "center", padding: "10px 8px", background: "#f9fafb", borderRadius: 8 }}>
                        <div style={{ fontSize: 11, color: "#9ca3af", fontWeight: 600, textTransform: "uppercase" }}>Started</div>
                        <div style={{ fontSize: 14, fontWeight: 700, color: "#374151", marginTop: 3 }}>{fmt(job.startedAt)}</div>
                      </div>
                      <div style={{ textAlign: "center", padding: "10px 8px", background: "#eff6ff", borderRadius: 8 }}>
                        <div style={{ fontSize: 11, color: "#9ca3af", fontWeight: 600, textTransform: "uppercase" }}>Elapsed</div>
                        <div style={{ fontSize: 14, fontWeight: 700, color: "#1d4ed8", marginTop: 3 }}>{isRunning ? elapsed(job.startedAt) : (job.durationSeconds ? `${job.durationSeconds}s` : elapsedStr)}</div>
                      </div>
                      <div style={{ textAlign: "center", padding: "10px 8px", background: "#f9fafb", borderRadius: 8 }}>
                        <div style={{ fontSize: 11, color: "#9ca3af", fontWeight: 600, textTransform: "uppercase" }}>Finished</div>
                        <div style={{ fontSize: 14, fontWeight: 700, color: "#374151", marginTop: 3 }}>{fmt(job.finishedAt)}</div>
                      </div>
                    </div>
                  </BlockStack>
                </Card>

                {/* Current product banner */}
                {job.currentProduct && (
                  <div style={{ background: "linear-gradient(135deg, #0f172a, #1e3a5f)", borderRadius: 12, padding: "16px 20px", color: "#fff", display: "flex", alignItems: "center", gap: 16 }}>
                    <Spinner size="small" />
                    <div>
                      <div style={{ fontSize: 11, opacity: 0.6, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em" }}>Currently importing</div>
                      <div style={{ fontSize: 16, fontWeight: 800, marginTop: 2 }}>{job.currentProduct.name}</div>
                      {job.currentProduct.partNumber && (
                        <div style={{ fontSize: 12, opacity: 0.7, marginTop: 1 }}>Part: {job.currentProduct.partNumber}</div>
                      )}
                      <div style={{ fontSize: 12, opacity: 0.6, marginTop: 1 }}>
                        Product {job.currentProduct.number} of {job.currentProduct.total}
                      </div>
                    </div>
                    <div style={{ marginLeft: "auto", textAlign: "right" }}>
                      <div style={{ fontSize: 32, fontWeight: 900, color: "#60a5fa" }}>{job.currentProduct.number}</div>
                      <div style={{ fontSize: 12, opacity: 0.5 }}>/ {job.currentProduct.total}</div>
                    </div>
                  </div>
                )}

                {/* Stats grid */}
                <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(150px, 1fr))", gap: 12 }}>
                  <StatCard label="Total Selected"  value={s.total}       accent="blue" />
                  <StatCard label="Processed"       value={s.processed}   accent="purple" sub={`${s.remaining} remaining`} />
                  <StatCard label="Created"         value={s.created}     accent="green" />
                  <StatCard label="Skipped"         value={s.skipped}     accent="amber" sub="already in store" />
                  <StatCard label="Failed"          value={s.failed}      accent="red" />
                  <StatCard label="Success Rate"    value={`${s.successRate}%`} accent={s.successRate >= 90 ? "green" : s.successRate >= 70 ? "amber" : "red"} />
                </div>

                {/* Stage progress board */}
                <Card>
                  <div style={{ padding: "4px 0" }}>
                    <div style={{ marginBottom: 12 }}>
                      <Text variant="headingSm" as="h3">Import Stages</Text>
                    </div>
                    <StageRow label="Fetch products from Turn14" status={stageStatus("fetching_products")} value={s.total > 0 ? `${s.total} found` : null} />
                    <StageRow label="Create / update products in Shopify" status={stageStatus("importing")} value={s.total > 0 ? s.label : null} meta={s.failed > 0 ? `${s.failed} failed` : null} />
                    <StageRow label="Import complete" status={stageStatus("completed")} value={job.status === "done" ? "Done" : null} />
                  </div>
                </Card>

                {/* Detail text */}
                {job.detail && (
                  <div style={{ background: "#f0f9ff", border: "1px solid #bae6fd", borderRadius: 10, padding: "12px 16px", fontSize: 14, color: "#0369a1", fontWeight: 500 }}>
                    ℹ️ {job.detail}
                  </div>
                )}

                {/* Error details */}
                {job.status === "error" && (
                  <div style={{ background: "#fff1f2", border: "1px solid #fecdd3", borderRadius: 10, padding: "16px" }}>
                    <div style={{ fontWeight: 700, color: "#dc2626", marginBottom: 6 }}>⛔ Import Error</div>
                    <div style={{ fontSize: 13, color: "#991b1b" }}>{job.detail}</div>
                  </div>
                )}

                {/* Per-product errors */}
                {job.errors?.length > 0 && (
                  <Card>
                    <div style={{ marginBottom: 10 }}>
                      <Text variant="headingSm" as="h3" tone="critical">Failed Products ({job.errors.length})</Text>
                    </div>
                    <div style={{ maxHeight: 220, overflowY: "auto" }}>
                      {job.errors.map((e, i) => (
                        <div key={i} style={{ padding: "8px 0", borderBottom: "1px solid #fef2f2", display: "flex", gap: 12 }}>
                          <div style={{ width: 6, height: 6, borderRadius: "50%", background: "#dc2626", marginTop: 6, flexShrink: 0 }} />
                          <div>
                            <div style={{ fontSize: 13, fontWeight: 600, color: "#374151" }}>#{e.index} {e.product}</div>
                            <div style={{ fontSize: 12, color: "#dc2626", marginTop: 2 }}>{e.error}</div>
                          </div>
                        </div>
                      ))}
                    </div>
                  </Card>
                )}

                {/* Completion summary */}
                {job.status === "done" && (
                  <div style={{ background: "linear-gradient(135deg, #f0fdf4, #dcfce7)", border: "1px solid #bbf7d0", borderRadius: 12, padding: "20px 24px" }}>
                    <div style={{ fontSize: 18, fontWeight: 800, color: "#15803d", marginBottom: 12 }}>✅ Import Completed</div>
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))", gap: 10 }}>
                      {[
                        { l: "Total products", v: s.total },
                        { l: "Created", v: s.created },
                        { l: "Skipped", v: s.skipped },
                        { l: "Failed", v: s.failed },
                        { l: "Success rate", v: `${s.successRate}%` },
                        { l: "Duration", v: job.durationSeconds ? `${job.durationSeconds}s` : "—" },
                      ].map(({ l, v }) => (
                        <div key={l} style={{ background: "#fff", borderRadius: 8, padding: "10px 12px", border: "1px solid #bbf7d0" }}>
                          <div style={{ fontSize: 11, color: "#6b7280", fontWeight: 600, textTransform: "uppercase" }}>{l}</div>
                          <div style={{ fontSize: 20, fontWeight: 800, color: "#15803d", marginTop: 2 }}>{v}</div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* Recent activity log */}
                <Card>
                  <div style={{ marginBottom: 10 }}>
                    <Text variant="headingSm" as="h3">Recent Activity</Text>
                  </div>
                  {recentLogs.length === 0 ? (
                    <div style={{ color: "#9ca3af", fontSize: 13, padding: "12px 0" }}>No activity yet — waiting for import to start…</div>
                  ) : (
                    recentLogs.map((entry, i) => <LogEntry key={i} entry={entry} />)
                  )}
                </Card>

              </BlockStack>
            )}
          </Layout.Section>
        </Layout>
      )}
    </Page>
  );
}
