"use client";

import { Film, Loader2, Pencil, RefreshCw, Save, X } from "lucide-react";
import { useSearchParams } from "next/navigation";
import { Suspense, useCallback, useEffect, useMemo, useState } from "react";
import { DashboardLayout } from "@/components/layout/dashboard-layout";
import { PageHeader } from "@/components/layout/page-header";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import { getGenerationPayload } from "@/lib/client/generation-payload";
import {
  fetchAIConfig,
  fetchGeneratedPosts,
  regeneratePost,
  updatePostCaption,
} from "@/lib/client/generation-api";
import { QuickPublishPanel } from "@/components/publishing/quick-publish-panel";
import type { GeneratedPost } from "@/types/workflow";
import { selectActiveProject } from "@/hooks/use-projects-hydrated";
import { useProjectsStore } from "@/store/projects-store";

type MediaFilter = "all" | "with-video" | "published";

function hasGeneratedVideo(post: GeneratedPost): boolean {
  return post.videoStatus === "generated" && Boolean(post.videoUrl);
}

function GeneratedPostsContent() {
  const activeProject = useProjectsStore(selectActiveProject);
  const accounts = useProjectsStore((s) => s.getActiveData()?.accounts ?? []);
  const searchParams = useSearchParams();
  const highlight = searchParams.get("highlight");

  const [posts, setPosts] = useState<GeneratedPost[]>([]);
  const [aiConfig, setAiConfig] = useState<{ provider: string; model: string } | null>(null);
  const [loading, setLoading] = useState(true);
  const [actionId, setActionId] = useState<string | null>(null);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editCaption, setEditCaption] = useState("");
  const [error, setError] = useState("");
  const [mediaFilter, setMediaFilter] = useState<MediaFilter>("all");

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [list, config] = await Promise.all([
        fetchGeneratedPosts(activeProject?.id, activeProject?.name),
        fetchAIConfig(),
      ]);
      setPosts(list);
      setAiConfig(config);
    } finally {
      setLoading(false);
    }
  }, [activeProject?.id, activeProject?.name]);

  useEffect(() => {
    void load();
  }, [load]);

  const videoCount = useMemo(() => posts.filter(hasGeneratedVideo).length, [posts]);

  const filteredPosts = useMemo(() => {
    if (mediaFilter === "with-video") return posts.filter(hasGeneratedVideo);
    if (mediaFilter === "published") return posts.filter((p) => p.status === "published");
    return posts;
  }, [posts, mediaFilter]);

  const handleRegenerate = async (post: GeneratedPost) => {
    if (!activeProject?.id) return;
    setActionId(post.id);
    setError("");
    try {
      const payload = getGenerationPayload(post.sequencePostId, "specific");
      if (!payload) {
        setError("Complete project setup before regenerating.");
        return;
      }
      const newPost = await regeneratePost(post.id, payload);
      await load();
      // Prefer API payload so UI never stays on a stale MariaDB/list race.
      setPosts((prev) => {
        const idx = prev.findIndex((p) => p.id === newPost.id);
        if (idx === -1) return [newPost, ...prev];
        const next = [...prev];
        next[idx] = { ...next[idx], ...newPost };
        return next;
      });
      setEditingId(null);
      window.location.hash = newPost.id;
    } catch (err) {
      setError(err instanceof Error ? err.message : "Regenerate failed");
    } finally {
      setActionId(null);
    }
  };

  const handleSaveEdit = async (id: string) => {
    setActionId(id);
    try {
      await updatePostCaption(id, editCaption);
      setEditingId(null);
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Save failed");
    } finally {
      setActionId(null);
    }
  };

  const handlePublishComplete = async () => {
    await load();
  };

  return (
    <DashboardLayout>
      <PageHeader
        title="Post Review"
        subtitle="Edit drafts if needed — cron auto-publishes directly (no approve step)"
      />
      <div className="flex-1 px-8 pb-8 pt-2">
        {aiConfig && (
          <p className="mb-4 text-xs text-gray-500">
            AI: <strong>{aiConfig.provider}</strong> / {aiConfig.model}
            {videoCount > 0 && (
              <>
                {" "}
                · <Film className="inline h-3 w-3" /> {videoCount} video
                {videoCount === 1 ? "" : "s"} ready
              </>
            )}
          </p>
        )}

        <div className="mb-4 flex flex-wrap gap-2">
          {(
            [
              ["all", `All (${posts.length})`],
              ["with-video", `With video (${videoCount})`],
              ["published", `Published (${posts.filter((p) => p.status === "published").length})`],
            ] as const
          ).map(([key, label]) => (
            <Button
              key={key}
              type="button"
              size="sm"
              variant={mediaFilter === key ? "primary" : "secondary"}
              onClick={() => setMediaFilter(key)}
            >
              {label}
            </Button>
          ))}
        </div>

        {activeProject?.status === "paused" && (
          <div className="mb-4 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
            Project is paused — publishing is disabled.
          </div>
        )}

        {error && <p className="mb-4 text-sm text-red-600">{error}</p>}

        {loading ? (
          <div className="flex justify-center py-16">
            <Loader2 className="h-8 w-8 animate-spin text-brand-600" />
          </div>
        ) : filteredPosts.length === 0 ? (
          <Card>
            <p className="text-center text-sm text-gray-500">
              {mediaFilter === "with-video"
                ? "No videos yet. Videos are created when FFmpeg is enabled (VIDEO_PROVIDER=ffmpeg) during generation."
                : mediaFilter === "published"
                  ? "No published posts yet."
                  : "No generated posts yet. Go to Live Generation or enable Loop Post Sequence in Automation."}
            </p>
          </Card>
        ) : (
          <div className="space-y-4">
            {filteredPosts.map((post) => (
              <Card
                key={post.id}
                id={post.id}
                className={cn(
                  highlight === post.id && "ring-2 ring-brand-600/30",
                )}
              >
                <div className="flex flex-col gap-4 lg:flex-row">
                  <div className="min-w-0 flex-1 space-y-3">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="text-sm font-semibold text-gray-900">{post.title}</span>
                      <span className="rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-600">
                        v{post.version ?? 1}
                      </span>
                      <span
                        className={cn(
                          "rounded-full px-2 py-0.5 text-xs font-medium",
                          post.status === "published"
                            ? "bg-green-100 text-green-700"
                            : post.status === "approved"
                              ? "bg-blue-100 text-blue-700"
                              : post.status === "draft"
                                ? "bg-emerald-100 text-emerald-700"
                                : "bg-gray-100 text-gray-600",
                        )}
                      >
                        {post.status === "draft" ? "queued" : post.status}
                      </span>
                      {post.imageApproved && (
                        <span className="rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-700">
                          image approved
                        </span>
                      )}
                      <span className="text-xs text-gray-400">
                        {post.provider} · {post.model}
                      </span>
                      {post.aiCostUsd != null && (
                        <span className="rounded bg-emerald-50 px-2 py-0.5 text-xs font-medium text-emerald-700">
                          AI cost: ${post.aiCostUsd.toFixed(4)}
                        </span>
                      )}
                    </div>

                    {editingId === post.id ? (
                      <div className="space-y-2">
                        <Textarea
                          rows={8}
                          value={editCaption}
                          onChange={(e) => setEditCaption(e.target.value)}
                          className="font-mono text-sm"
                        />
                        <div className="flex gap-2">
                          <Button
                            type="button"
                            size="sm"
                            onClick={() => void handleSaveEdit(post.id)}
                            disabled={actionId !== null}
                          >
                            <Save className="h-4 w-4" />
                            Save edit
                          </Button>
                          <Button
                            type="button"
                            size="sm"
                            variant="ghost"
                            onClick={() => setEditingId(null)}
                          >
                            <X className="h-4 w-4" />
                            Cancel
                          </Button>
                        </div>
                      </div>
                    ) : (
                      <p className="whitespace-pre-wrap text-sm leading-relaxed text-gray-700">
                        {post.caption}
                      </p>
                    )}

                    <div className="flex flex-wrap gap-2">
                      {post.platforms.map((p) => (
                        <span
                          key={p}
                          className="rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-600"
                        >
                          {p}
                        </span>
                      ))}
                    </div>
                    {post.engagementScore !== null && (
                      <p className="text-xs text-gray-500">
                        Engagement score:{" "}
                        <span className="font-semibold text-green-600">
                          {post.engagementScore}
                        </span>
                      </p>
                    )}
                    {(post.imageProvider || post.imageWarning) && (
                      <p className="text-xs text-gray-500">
                        Image:{" "}
                        <span className="font-semibold text-gray-700">
                          {post.imageProvider ?? "unknown"}
                        </span>
                        {post.imageProviderChain ? ` (${post.imageProviderChain})` : ""}
                        {post.mediaAssetId ? ` · ${post.mediaAssetId}` : ""}
                        {post.imageWarning ? (
                          <span className="block text-amber-600">{post.imageWarning}</span>
                        ) : null}
                      </p>
                    )}
                    {post.qualityReport && (
                      <p className="text-xs text-gray-500">
                        QA {post.qualityReport.scores.overall}/10{" "}
                        <span
                          className={
                            post.qualityReport.passed
                              ? "font-semibold text-green-600"
                              : "font-semibold text-amber-600"
                          }
                        >
                          {post.qualityReport.passed ? "passed" : "needs improvement"}
                        </span>
                        {post.bannerLayoutId ? ` · ${post.bannerLayoutId}` : ""}
                        {post.regenerationCount
                          ? ` · regen ×${post.regenerationCount}`
                          : ""}
                      </p>
                    )}
                    {post.aiUsage && post.aiUsage.calls.length > 0 && (
                      <details className="text-xs text-gray-500">
                        <summary className="cursor-pointer font-medium text-gray-600">
                          AI usage breakdown ({post.aiUsage.calls.length} calls · $
                          {post.aiCostUsd?.toFixed(4) ?? "0"})
                        </summary>
                        <ul className="mt-1 space-y-0.5 pl-2">
                          {post.aiUsage.calls.map((call, i) => (
                            <li key={i}>
                              {call.operation}: {call.provider}/{call.model} — $
                              {call.estimatedCostUsd.toFixed(4)}
                              {call.inputTokens != null
                                ? ` (${call.inputTokens}+${call.outputTokens ?? 0} tok)`
                                : ""}
                            </li>
                          ))}
                        </ul>
                      </details>
                    )}
                    {post.publishedAt && (
                      <p className="text-xs text-gray-400">
                        Published: {new Date(post.publishedAt).toLocaleString()}
                      </p>
                    )}
                    {post.videoStatus && post.videoStatus !== "generated" && (
                      <p className="text-xs text-amber-600">
                        Video: {post.videoStatus}
                        {post.videoWarning ? ` — ${post.videoWarning}` : ""}
                      </p>
                    )}
                  </div>
                  <div className="flex shrink-0 flex-col gap-2">
                    {post.imageUrl ? (
                      <img
                        src={post.imageUrl}
                        alt=""
                        className="h-40 w-40 rounded-lg object-cover"
                      />
                    ) : (
                      <div className="flex h-40 w-40 items-center justify-center rounded-lg bg-gradient-to-br from-blue-400 to-blue-200 text-xs text-white/80">
                        No image
                      </div>
                    )}
                    {hasGeneratedVideo(post) && post.videoUrl && (
                      <div className="w-40 space-y-1">
                        <p className="text-[10px] font-medium uppercase tracking-wide text-gray-500">
                          Video
                        </p>
                        <video
                          src={post.videoUrl}
                          controls
                          playsInline
                          preload="metadata"
                          poster={post.imageUrl ?? undefined}
                          className="h-40 w-40 rounded-lg bg-black object-cover"
                        />
                        {post.videoDurationSeconds && (
                          <p className="text-[10px] text-gray-400">
                            {post.videoDurationSeconds}s · {post.videoResolution}
                          </p>
                        )}
                      </div>
                    )}
                  </div>
                </div>
                <div className="mt-4 flex flex-wrap justify-end gap-2 border-t border-gray-100 pt-4">
                  {post.status === "draft" && editingId !== post.id && (
                    <Button
                      type="button"
                      size="sm"
                      variant="ghost"
                      disabled={actionId !== null}
                      onClick={() => {
                        setEditingId(post.id);
                        setEditCaption(post.caption);
                      }}
                    >
                      <Pencil className="h-4 w-4" />
                      Edit
                    </Button>
                  )}
                  {post.status !== "published" && (
                    <Button
                      type="button"
                      size="sm"
                      variant="ghost"
                      disabled={actionId !== null || activeProject?.status === "paused"}
                      onClick={() => void handleRegenerate(post)}
                    >
                      {actionId === post.id ? (
                        <Loader2 className="h-4 w-4 animate-spin" />
                      ) : (
                        <RefreshCw className="h-4 w-4" />
                      )}
                      Regenerate
                    </Button>
                  )}
                </div>
                {post.status !== "published" && activeProject && (
                  <QuickPublishPanel
                    className="mt-4"
                    post={post}
                    accounts={accounts}
                    projectStatus={activeProject.status}
                    onPublished={() => void handlePublishComplete()}
                  />
                )}
              </Card>
            ))}
          </div>
        )}
      </div>
    </DashboardLayout>
  );
}

export default function GeneratedPostsPage() {
  return (
    <Suspense
      fallback={
        <div className="flex min-h-screen items-center justify-center">
          <Loader2 className="h-8 w-8 animate-spin text-brand-600" />
        </div>
      }
    >
      <GeneratedPostsContent />
    </Suspense>
  );
}
