import { useEffect, useMemo, useState } from "react";
import {
  Layers,
  Plus,
  Trash2,
  ArrowUp,
  ArrowDown,
  Star,
  Save,
  RefreshCw,
  Eye,
  EyeOff,
  Loader2,
  Search,
} from "lucide-react";
import { createClient } from "@metagptx/web-sdk";
import CmsLayout from "./CmsLayout";
import { PageHeader, SectionCard, Field, TextInput, Select, Badge } from "./ui";

// --- Types ---
type Plan = {
  id?: number;
  service_type: string;
  name: string;
  price: number;
  currency?: string;
  billing_cycle?: string;
  features?: string; // JSON-encoded list<string>
  cta_label?: string;
  cta_url?: string;
  is_featured?: boolean;
  is_active?: boolean;
  sort_order?: number;
  tagline?: string;
  // local-only draft flag
  _dirty?: boolean;
  _new?: boolean;
};

const SERVICE_TYPES: Array<{ value: string; label: string }> = [
  { value: "shared-hosting", label: "Shared Hosting" },
  { value: "wordpress-hosting", label: "WordPress Hosting" },
  { value: "whatsapp-api", label: "WhatsApp API" },
  { value: "uptime-monitor", label: "Uptime Monitor" },
  { value: "cloud-vps", label: "Cloud VPS" },
  { value: "dedicated", label: "Dedicated Servers" },
  { value: "business-email", label: "Business Email" },
  { value: "sd-wan", label: "SD-WAN" },
  { value: "managed-it", label: "Managed IT" },
];

const client = createClient();

function parseFeatures(raw?: string): string[] {
  if (!raw) return [];
  try {
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed.map(String) : [];
  } catch {
    // fallback: split by newline or comma
    return String(raw)
      .split(/\r?\n|,/)
      .map((s) => s.trim())
      .filter(Boolean);
  }
}

function toFeaturesJson(list: string[]): string {
  return JSON.stringify(list.filter((s) => s.trim().length > 0));
}

export default function CmsPlans() {
  const [plans, setPlans] = useState<Plan[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [filter, setFilter] = useState<string>("all");
  const [search, setSearch] = useState("");
  const [savingId, setSavingId] = useState<number | "new" | null>(null);
  const [message, setMessage] = useState<{ tone: "ok" | "err"; text: string } | null>(null);

  const load = async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await client.entities.plans.queryAll({
        sort: "sort_order",
        limit: 500,
      });
      const items = (res?.data?.items ?? []) as Plan[];
      setPlans(items);
    } catch (e) {
      // queryAll may not be available if create_only=false; fallback to /all endpoint via apiCall
      try {
        const r = await client.apiCall.invoke({
          url: "/api/v1/entities/plans/all",
          method: "GET",
          data: { sort: "sort_order", limit: 500 },
        });
        const items = (r?.data?.items ?? []) as Plan[];
        setPlans(items);
      } catch (err: unknown) {
        const msg = err instanceof Error ? err.message : String(err);
        setError("Failed to load plans: " + msg);
      }
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
  }, []);

  const visible = useMemo(() => {
    return plans.filter((p) => {
      if (filter !== "all" && p.service_type !== filter) return false;
      if (search) {
        const s = search.toLowerCase();
        if (
          !(p.name?.toLowerCase().includes(s) ||
            p.tagline?.toLowerCase().includes(s) ||
            p.service_type?.toLowerCase().includes(s))
        ) {
          return false;
        }
      }
      return true;
    });
  }, [plans, filter, search]);

  const groupCounts = useMemo(() => {
    const c: Record<string, number> = {};
    plans.forEach((p) => {
      c[p.service_type] = (c[p.service_type] ?? 0) + 1;
    });
    return c;
  }, [plans]);

  const updateLocal = (idx: number, patch: Partial<Plan>) => {
    setPlans((prev) =>
      prev.map((p, i) => (i === idx ? { ...p, ...patch, _dirty: true } : p)),
    );
  };

  const addPlan = () => {
    const serviceType = filter === "all" ? "shared-hosting" : filter;
    const existing = plans.filter((p) => p.service_type === serviceType);
    const nextOrder = existing.length
      ? Math.max(...existing.map((p) => p.sort_order ?? 0)) + 1
      : 1;
    setPlans((prev) => [
      ...prev,
      {
        service_type: serviceType,
        name: "New Plan",
        price: 0,
        currency: "USD",
        billing_cycle: "monthly",
        features: "[]",
        cta_label: "Get Started",
        cta_url: "",
        is_featured: false,
        is_active: true,
        sort_order: nextOrder,
        tagline: "",
        _new: true,
        _dirty: true,
      },
    ]);
    setMessage({ tone: "ok", text: "New draft plan added. Fill the details and click Save." });
  };

  const savePlan = async (idx: number) => {
    const plan = plans[idx];
    if (!plan) return;
    setSavingId(plan.id ?? "new");
    setMessage(null);
    try {
      const payload = {
        service_type: plan.service_type,
        name: plan.name,
        price: Number(plan.price) || 0,
        currency: plan.currency || "USD",
        billing_cycle: plan.billing_cycle || "monthly",
        features: plan.features || "[]",
        cta_label: plan.cta_label || "",
        cta_url: plan.cta_url || "",
        is_featured: !!plan.is_featured,
        is_active: plan.is_active !== false,
        sort_order: Number(plan.sort_order) || 0,
        tagline: plan.tagline || "",
      };

      if (plan._new || !plan.id) {
        const res = await client.entities.plans.create({ data: payload });
        const created = res?.data as Plan;
        setPlans((prev) => prev.map((p, i) => (i === idx ? { ...created, _dirty: false, _new: false } : p)));
        setMessage({ tone: "ok", text: `Plan "${payload.name}" created successfully.` });
      } else {
        const res = await client.entities.plans.update({
          id: String(plan.id),
          data: payload,
        });
        const updated = res?.data as Plan;
        setPlans((prev) =>
          prev.map((p, i) => (i === idx ? { ...updated, _dirty: false } : p)),
        );
        setMessage({ tone: "ok", text: `Plan "${payload.name}" saved.` });
      }
    } catch (e: unknown) {
      const msg = e instanceof Error ? e.message : String(e);
      setMessage({ tone: "err", text: "Save failed: " + msg });
    } finally {
      setSavingId(null);
    }
  };

  const deletePlan = async (idx: number) => {
    const plan = plans[idx];
    if (!plan) return;
    if (!window.confirm(`Delete plan "${plan.name}"? This cannot be undone.`)) return;
    if (plan._new || !plan.id) {
      setPlans((prev) => prev.filter((_, i) => i !== idx));
      return;
    }
    try {
      await client.entities.plans.delete({ id: String(plan.id) });
      setPlans((prev) => prev.filter((_, i) => i !== idx));
      setMessage({ tone: "ok", text: "Plan deleted." });
    } catch (e: unknown) {
      const msg = e instanceof Error ? e.message : String(e);
      setMessage({ tone: "err", text: "Delete failed: " + msg });
    }
  };

  const movePlan = (idx: number, dir: -1 | 1) => {
    const plan = plans[idx];
    if (!plan) return;
    // Swap sort_order with neighbor in same service_type
    const siblings = plans
      .map((p, i) => ({ p, i }))
      .filter((x) => x.p.service_type === plan.service_type)
      .sort((a, b) => (a.p.sort_order ?? 0) - (b.p.sort_order ?? 0));
    const pos = siblings.findIndex((x) => x.i === idx);
    const neighbor = siblings[pos + dir];
    if (!neighbor) return;
    const a = plan.sort_order ?? 0;
    const b = neighbor.p.sort_order ?? 0;
    setPlans((prev) =>
      prev.map((p, i) => {
        if (i === idx) return { ...p, sort_order: b, _dirty: true };
        if (i === neighbor.i) return { ...p, sort_order: a, _dirty: true };
        return p;
      }),
    );
  };

  const dirtyCount = plans.filter((p) => p._dirty).length;

  return (
    <CmsLayout>
      <PageHeader
        icon={<Layers className="w-6 h-6" />}
        title="Plan Management"
        description="Create, edit and publish pricing plans for every DoItEasy service. Changes are applied directly to the live site."
      />

      {message && (
        <div
          className={`mb-4 rounded-xl px-4 py-3 text-sm font-medium border ${
            message.tone === "ok"
              ? "bg-emerald-50 border-emerald-200 text-emerald-800"
              : "bg-red-50 border-red-200 text-red-800"
          }`}
        >
          {message.text}
        </div>
      )}

      {/* Toolbar */}
      <div className="bg-white rounded-2xl shadow-sm border border-slate-200 p-4 md:p-5 mb-6">
        <div className="flex flex-col lg:flex-row gap-3 lg:items-center lg:justify-between">
          <div className="flex flex-wrap gap-2">
            <button
              onClick={() => setFilter("all")}
              className={`px-3 py-1.5 rounded-full text-xs font-semibold border transition ${
                filter === "all"
                  ? "bg-[#0b6e3e] border-[#0b6e3e] text-white"
                  : "bg-white border-slate-300 text-slate-700 hover:border-[#0b6e3e]"
              }`}
            >
              All ({plans.length})
            </button>
            {SERVICE_TYPES.map((s) => (
              <button
                key={s.value}
                onClick={() => setFilter(s.value)}
                className={`px-3 py-1.5 rounded-full text-xs font-semibold border transition ${
                  filter === s.value
                    ? "bg-[#0b6e3e] border-[#0b6e3e] text-white"
                    : "bg-white border-slate-300 text-slate-700 hover:border-[#0b6e3e]"
                }`}
              >
                {s.label}
                {groupCounts[s.value] ? (
                  <span className="ml-1 opacity-70">({groupCounts[s.value]})</span>
                ) : null}
              </button>
            ))}
          </div>
          <div className="flex gap-2 items-center">
            <div className="relative">
              <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
              <input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Search plans…"
                className="pl-9 pr-3 py-2 rounded-lg border border-slate-300 text-sm focus:outline-none focus:ring-2 focus:ring-[#0b6e3e] w-56"
              />
            </div>
            <button
              onClick={load}
              className="px-3 py-2 rounded-lg border border-slate-300 text-slate-700 text-sm font-semibold hover:bg-slate-50 inline-flex items-center gap-1.5"
              title="Reload from server"
            >
              <RefreshCw className="w-4 h-4" /> Reload
            </button>
            <button
              onClick={addPlan}
              className="px-3 py-2 rounded-lg bg-[#0b6e3e] text-white text-sm font-bold hover:bg-[#0a8048] inline-flex items-center gap-1.5"
            >
              <Plus className="w-4 h-4" /> New Plan
            </button>
          </div>
        </div>
        {dirtyCount > 0 && (
          <div className="mt-3 text-xs text-amber-700 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2">
            You have {dirtyCount} unsaved change{dirtyCount > 1 ? "s" : ""}. Click Save on each plan to publish.
          </div>
        )}
      </div>

      {/* Plans list */}
      {loading ? (
        <div className="bg-white rounded-2xl border border-slate-200 p-16 text-center text-slate-500">
          <Loader2 className="w-8 h-8 animate-spin mx-auto mb-3 text-[#0b6e3e]" />
          Loading plans…
        </div>
      ) : error ? (
        <div className="bg-red-50 border border-red-200 rounded-2xl p-8 text-red-800">{error}</div>
      ) : visible.length === 0 ? (
        <div className="bg-white rounded-2xl border border-slate-200 p-16 text-center text-slate-500">
          <Layers className="w-10 h-10 mx-auto mb-3 text-slate-300" />
          <div className="font-semibold text-slate-700">No plans found</div>
          <p className="text-sm mt-1">Click "New Plan" to create one.</p>
        </div>
      ) : (
        <div className="space-y-4">
          {visible.map((plan) => {
            const idx = plans.indexOf(plan);
            const features = parseFeatures(plan.features);
            const serviceLabel =
              SERVICE_TYPES.find((s) => s.value === plan.service_type)?.label ?? plan.service_type;
            return (
              <SectionCard
                key={plan.id ?? `new-${idx}`}
                title={plan.name || "Untitled plan"}
                description={`${serviceLabel} · $${Number(plan.price || 0).toFixed(2)}/${plan.billing_cycle || "monthly"}`}
                actions={
                  <div className="flex items-center gap-1.5 flex-wrap">
                    {plan.is_featured && <Badge tone="yellow">★ Featured</Badge>}
                    {plan.is_active === false ? (
                      <Badge tone="red">Hidden</Badge>
                    ) : (
                      <Badge tone="green">Live</Badge>
                    )}
                    {plan._new && <Badge tone="blue">Draft</Badge>}
                    {plan._dirty && !plan._new && <Badge tone="yellow">Unsaved</Badge>}
                    <button
                      onClick={() => movePlan(idx, -1)}
                      className="p-1.5 rounded hover:bg-slate-100 text-slate-600"
                      aria-label="Move up"
                      title="Move up"
                    >
                      <ArrowUp className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() => movePlan(idx, 1)}
                      className="p-1.5 rounded hover:bg-slate-100 text-slate-600"
                      aria-label="Move down"
                      title="Move down"
                    >
                      <ArrowDown className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() =>
                        updateLocal(idx, { is_featured: !plan.is_featured })
                      }
                      className={`p-1.5 rounded ${plan.is_featured ? "bg-amber-100 text-amber-700" : "hover:bg-amber-50 text-slate-600"}`}
                      aria-label="Toggle featured"
                      title="Toggle featured"
                    >
                      <Star className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() =>
                        updateLocal(idx, { is_active: !(plan.is_active !== false) })
                      }
                      className="p-1.5 rounded hover:bg-slate-100 text-slate-600"
                      aria-label="Toggle visibility"
                      title={plan.is_active !== false ? "Hide from site" : "Publish"}
                    >
                      {plan.is_active !== false ? (
                        <Eye className="w-4 h-4" />
                      ) : (
                        <EyeOff className="w-4 h-4" />
                      )}
                    </button>
                    <button
                      onClick={() => savePlan(idx)}
                      disabled={savingId !== null}
                      className="px-3 py-1.5 rounded-lg bg-[#0b6e3e] text-white text-xs font-bold hover:bg-[#0a8048] disabled:opacity-60 inline-flex items-center gap-1"
                    >
                      {savingId === (plan.id ?? "new") ? (
                        <Loader2 className="w-3.5 h-3.5 animate-spin" />
                      ) : (
                        <Save className="w-3.5 h-3.5" />
                      )}
                      Save
                    </button>
                    <button
                      onClick={() => deletePlan(idx)}
                      className="p-1.5 rounded hover:bg-red-100 text-red-600"
                      aria-label="Delete"
                      title="Delete"
                    >
                      <Trash2 className="w-4 h-4" />
                    </button>
                  </div>
                }
              >
                <div className="grid md:grid-cols-3 gap-4">
                  <Field label="Service" required>
                    <Select
                      value={plan.service_type}
                      onChange={(e) => updateLocal(idx, { service_type: e.target.value })}
                    >
                      {SERVICE_TYPES.map((s) => (
                        <option key={s.value} value={s.value}>
                          {s.label}
                        </option>
                      ))}
                    </Select>
                  </Field>
                  <Field label="Plan name" required>
                    <TextInput
                      value={plan.name || ""}
                      onChange={(e) => updateLocal(idx, { name: e.target.value })}
                    />
                  </Field>
                  <Field label="Tagline / subtitle">
                    <TextInput
                      value={plan.tagline || ""}
                      onChange={(e) => updateLocal(idx, { tagline: e.target.value })}
                      placeholder="e.g. Best for growing teams"
                    />
                  </Field>

                  <Field label="Price" required hint="Numeric, no currency symbol">
                    <TextInput
                      type="number"
                      step="0.01"
                      value={plan.price ?? 0}
                      onChange={(e) => updateLocal(idx, { price: Number(e.target.value) })}
                    />
                  </Field>
                  <Field label="Currency">
                    <TextInput
                      value={plan.currency || "USD"}
                      onChange={(e) => updateLocal(idx, { currency: e.target.value.toUpperCase() })}
                      maxLength={3}
                    />
                  </Field>
                  <Field label="Billing cycle">
                    <Select
                      value={plan.billing_cycle || "monthly"}
                      onChange={(e) => updateLocal(idx, { billing_cycle: e.target.value })}
                    >
                      <option value="monthly">Monthly</option>
                      <option value="yearly">Yearly</option>
                      <option value="one-time">One-time</option>
                      <option value="quote">Quote / Contact</option>
                    </Select>
                  </Field>

                  <Field label="CTA button label">
                    <TextInput
                      value={plan.cta_label || ""}
                      onChange={(e) => updateLocal(idx, { cta_label: e.target.value })}
                      placeholder="Order Now"
                    />
                  </Field>
                  <Field label="CTA URL" hint="Leave empty to open quote form">
                    <TextInput
                      value={plan.cta_url || ""}
                      onChange={(e) => updateLocal(idx, { cta_url: e.target.value })}
                      placeholder="/register or https://..."
                    />
                  </Field>
                  <Field label="Sort order" hint="Ascending">
                    <TextInput
                      type="number"
                      value={plan.sort_order ?? 0}
                      onChange={(e) => updateLocal(idx, { sort_order: Number(e.target.value) })}
                    />
                  </Field>
                </div>

                <Field
                  label="Features"
                  hint="One per line. These appear as checkmark bullet points on the site."
                >
                  <textarea
                    value={features.join("\n")}
                    onChange={(e) =>
                      updateLocal(idx, {
                        features: toFeaturesJson(e.target.value.split("\n")),
                      })
                    }
                    rows={6}
                    className="w-full px-3 py-2.5 rounded-lg border border-slate-300 bg-white text-slate-900 text-sm focus:outline-none focus:ring-2 focus:ring-[#0b6e3e] font-mono"
                    placeholder={"200 monitors\n30-second check interval\nEmail + SMS + Slack"}
                  />
                </Field>

                {/* Mini preview */}
                <div className="mt-2 rounded-xl border border-slate-200 bg-slate-50 p-4">
                  <div className="text-xs uppercase tracking-widest text-slate-500 font-bold mb-2">
                    Live preview
                  </div>
                  <div
                    className={`rounded-xl p-5 border max-w-sm ${
                      plan.is_featured
                        ? "bg-[#063019] text-white border-[#0b6e3e] shadow-lg"
                        : "bg-white text-slate-900 border-slate-200"
                    }`}
                  >
                    {plan.is_featured && (
                      <div className="text-[10px] uppercase tracking-widest font-bold mb-1 text-[#f5c400]">
                        Most Popular
                      </div>
                    )}
                    <div className="text-lg font-extrabold">{plan.name || "Plan name"}</div>
                    {plan.tagline && (
                      <div
                        className={`text-xs mt-0.5 ${plan.is_featured ? "text-slate-300" : "text-slate-500"}`}
                      >
                        {plan.tagline}
                      </div>
                    )}
                    <div className="mt-3">
                      <span className="text-3xl font-extrabold">
                        ${Number(plan.price || 0).toFixed(2)}
                      </span>
                      <span
                        className={`text-xs ml-1 ${plan.is_featured ? "text-slate-300" : "text-slate-500"}`}
                      >
                        /{plan.billing_cycle || "mo"}
                      </span>
                    </div>
                    <ul
                      className={`mt-3 space-y-1 text-xs ${plan.is_featured ? "text-slate-200" : "text-slate-600"}`}
                    >
                      {features.slice(0, 6).map((f, i) => (
                        <li key={i}>• {f}</li>
                      ))}
                      {features.length === 0 && <li className="italic opacity-70">No features yet.</li>}
                    </ul>
                    <div
                      className={`mt-4 inline-block px-4 py-2 rounded-lg text-xs font-bold ${
                        plan.is_featured ? "bg-[#f5c400] text-[#063019]" : "bg-[#0b6e3e] text-white"
                      }`}
                    >
                      {plan.cta_label || "Order Now"}
                    </div>
                  </div>
                </div>
              </SectionCard>
            );
          })}
        </div>
      )}
    </CmsLayout>
  );
}