"use client";

import { useMemo } from "react";
import { CheckCircle2, XCircle, AlertCircle } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";

// ── Pure score engine ──────────────────────────────────────────────────────────

function stripHtml(html: string): string {
  return html.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
}

function wordCount(text: string): number {
  return text.trim() ? text.trim().split(/\s+/).length : 0;
}

function hasLinks(html: string): boolean {
  return /<a[\s>]/i.test(html);
}

function keywordDensityPct(text: string, kw: string): number {
  if (!kw || !text) return 0;
  const escaped = kw.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  const matches = text.toLowerCase().match(new RegExp(escaped, "g"));
  const words = wordCount(text);
  return words > 0 ? ((matches?.length ?? 0) / words) * 100 : 0;
}

interface ComputeInput {
  focusKeyword: string;
  seoTitle: string;
  seoDescription: string;
  slug: string;
  contentHtml: string;
  excerpt: string;
  coverImage: string;
  title: string;
}

interface Check {
  label: string;
  pass: boolean;
  warn: boolean;
  weight: number;
}

function computeChecks(fields: ComputeInput): { checks: Check[]; score: number } {
  const { focusKeyword, seoTitle, seoDescription, slug, contentHtml, coverImage, title } = fields;
  const kw = focusKeyword.toLowerCase().trim();
  const effectiveTitle = (seoTitle || title).toLowerCase();
  const contentText = stripHtml(contentHtml);
  const firstSentence = contentText.split(/\.\s/)[0] ?? "";
  const density = keywordDensityPct(contentText, kw);
  const wc = wordCount(contentText);

  const raw: Omit<Check, "warn">[] = [
    { label: "Focus keyword in SEO title", pass: !!kw && effectiveTitle.includes(kw), weight: 15 },
    { label: "Focus keyword at start of SEO title", pass: !!kw && effectiveTitle.startsWith(kw), weight: 5 },
    { label: "Focus keyword in meta description", pass: !!kw && seoDescription.toLowerCase().includes(kw), weight: 15 },
    { label: "Focus keyword in URL slug", pass: !!kw && slug.replace(/-/g, " ").toLowerCase().includes(kw), weight: 10 },
    { label: "Focus keyword in opening paragraph", pass: !!kw && firstSentence.toLowerCase().includes(kw), weight: 10 },
    { label: "Keyword density is 1–3%", pass: density >= 1 && density <= 3, weight: 10 },
    { label: "SEO title is 50–60 characters", pass: (seoTitle || title).length >= 50 && (seoTitle || title).length <= 60, weight: 10 },
    { label: "Meta description is 120–160 characters", pass: seoDescription.length >= 120 && seoDescription.length <= 160, weight: 10 },
    { label: "Article is at least 300 words", pass: wc >= 300, weight: 5 },
    { label: "Cover image is set", pass: !!coverImage, weight: 5 },
    { label: "Content contains at least one link", pass: hasLinks(contentHtml), weight: 5 },
  ];

  const checks: Check[] = raw.map((c) => ({
    ...c,
    // Warn (orange) when there's partial progress but not passing
    warn: !c.pass && (
      (c.label.includes("density") && density > 0) ||
      (c.label.includes("SEO title is") && (seoTitle || title).length > 0 && (seoTitle || title).length < 50) ||
      (c.label.includes("Meta description") && seoDescription.length > 0 && seoDescription.length < 120) ||
      (c.label.includes("300 words") && wc > 0 && wc < 300)
    ),
  }));

  const score = checks.reduce((sum, c) => sum + (c.pass ? c.weight : 0), 0);
  return { checks, score };
}

// ── Sub-components ─────────────────────────────────────────────────────────────

function ScoreBadge({ score }: { score: number }) {
  const isGood = score >= 70;
  const isOk = score >= 40;
  const label = isGood ? "Good" : isOk ? "Needs work" : "Poor";
  const colorText = isGood ? "text-green-600" : isOk ? "text-amber-600" : "text-red-500";
  const colorBg = isGood ? "bg-green-500/10 border-green-500/20" : isOk ? "bg-amber-500/10 border-amber-500/20" : "bg-red-500/10 border-red-500/20";
  const barColor = isGood ? "[&>div]:bg-green-500" : isOk ? "[&>div]:bg-amber-500" : "[&>div]:bg-red-500";

  return (
    <div className={`flex items-center gap-3 p-3 rounded-lg border ${colorBg}`}>
      <div className={`text-3xl font-bold tabular-nums ${colorText}`}>{score}</div>
      <div className="flex-1 min-w-0">
        <p className={`text-sm font-semibold ${colorText}`}>{label}</p>
        <Progress value={score} className={`h-1.5 mt-1 ${barColor}`} />
      </div>
      <span className="text-xs text-muted-foreground">/ 100</span>
    </div>
  );
}

function SerpPreview({
  title, description, slug,
}: { title: string; description: string; slug: string }) {
  if (!title && !description) return null;
  return (
    <div className="p-3 bg-muted/50 rounded-lg space-y-0.5 text-sm">
      <p className="text-[10px] text-muted-foreground uppercase tracking-wider font-medium mb-1.5">Search Preview</p>
      <p className="text-blue-600 font-medium text-sm leading-snug truncate">{title || "Article Title"}</p>
      <p className="text-green-700 text-xs truncate">petrobasegroup.com › news › {slug || "article-slug"}</p>
      <p className="text-muted-foreground text-xs leading-relaxed line-clamp-2 mt-0.5">
        {description || "Meta description will appear here…"}
      </p>
    </div>
  );
}

// ── Main SeoPanel ──────────────────────────────────────────────────────────────

export interface SeoPanelProps {
  focusKeyword: string;
  seoTitle: string;
  seoDescription: string;
  slug: string;
  contentHtml: string;
  excerpt: string;
  coverImage: string;
  title: string;
  onFocusKeyword: (v: string) => void;
  onSeoTitle: (v: string) => void;
  onSeoDescription: (v: string) => void;
  onSlug: (v: string) => void;
}

export function SeoPanel(props: SeoPanelProps) {
  const {
    focusKeyword, seoTitle, seoDescription, slug, title,
    onFocusKeyword, onSeoTitle, onSeoDescription, onSlug,
  } = props;

  const { checks, score } = useMemo(
    () => computeChecks(props),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [props.focusKeyword, props.seoTitle, props.seoDescription, props.slug,
     props.contentHtml, props.excerpt, props.coverImage, props.title],
  );

  const seoTitleValue = seoTitle || title;

  return (
    <div className="space-y-4">
      <ScoreBadge score={score} />

      <SerpPreview
        title={seoTitleValue}
        description={seoDescription}
        slug={slug}
      />

      {/* Checklist */}
      <div className="space-y-1.5">
        {checks.map((c, i) => (
          <div key={i} className="flex items-start gap-2 text-xs">
            {c.pass ? (
              <CheckCircle2 size={13} className="text-green-500 mt-0.5 shrink-0" />
            ) : c.warn ? (
              <AlertCircle size={13} className="text-amber-500 mt-0.5 shrink-0" />
            ) : (
              <XCircle size={13} className="text-red-400 mt-0.5 shrink-0" />
            )}
            <span className={c.pass ? "text-foreground" : "text-muted-foreground"}>{c.label}</span>
          </div>
        ))}
      </div>

      {/* Fields */}
      <div className="space-y-3 pt-2 border-t border-border">
        {/* Focus keyword */}
        <div className="space-y-1.5">
          <Label className="text-xs font-medium">Focus Keyword</Label>
          <Input
            value={focusKeyword}
            onChange={(e) => onFocusKeyword(e.target.value)}
            placeholder="e.g. asset integrity inspection"
            className="h-8 text-xs"
          />
        </div>

        {/* SEO title */}
        <div className="space-y-1.5">
          <div className="flex items-center justify-between">
            <Label className="text-xs font-medium">SEO Title</Label>
            <span className={`text-[10px] tabular-nums ${seoTitle.length > 60 ? "text-red-500" : "text-muted-foreground"}`}>
              {seoTitle.length} / 60
            </span>
          </div>
          <Input
            value={seoTitle}
            onChange={(e) => onSeoTitle(e.target.value)}
            placeholder="Overrides article title in Google"
            className="h-8 text-xs"
          />
          <Progress
            value={Math.min((seoTitle.length / 60) * 100, 110)}
            className={`h-1 ${seoTitle.length > 60 ? "[&>div]:bg-red-500" : seoTitle.length >= 50 ? "[&>div]:bg-green-500" : "[&>div]:bg-amber-500"}`}
          />
        </div>

        {/* Meta description */}
        <div className="space-y-1.5">
          <div className="flex items-center justify-between">
            <Label className="text-xs font-medium">Meta Description</Label>
            <span className={`text-[10px] tabular-nums ${seoDescription.length > 160 ? "text-red-500" : "text-muted-foreground"}`}>
              {seoDescription.length} / 160
            </span>
          </div>
          <Textarea
            value={seoDescription}
            onChange={(e) => onSeoDescription(e.target.value)}
            placeholder="Summary shown below the title in search results (120–160 chars recommended)"
            rows={3}
            className="text-xs resize-none"
          />
          <Progress
            value={Math.min((seoDescription.length / 160) * 100, 110)}
            className={`h-1 ${seoDescription.length > 160 ? "[&>div]:bg-red-500" : seoDescription.length >= 120 ? "[&>div]:bg-green-500" : "[&>div]:bg-amber-500"}`}
          />
        </div>

        {/* Slug */}
        <div className="space-y-1.5">
          <Label className="text-xs font-medium">URL Slug</Label>
          <div className="flex items-center border border-input rounded-md overflow-hidden h-8 text-xs focus-within:ring-1 focus-within:ring-ring">
            <span className="px-2 text-muted-foreground bg-muted border-r border-input h-full flex items-center shrink-0 select-none">
              /news/
            </span>
            <input
              value={slug}
              onChange={(e) =>
                onSlug(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/--+/g, "-"))
              }
              placeholder="article-url-slug"
              className="flex-1 px-2 bg-transparent outline-none text-xs h-full"
            />
          </div>
        </div>
      </div>
    </div>
  );
}
