/**
 * Panel Grid Component
 *
 * Displays generated comic panels in a grid layout
 * Allows regeneration of individual panels
 */

import type { JSX } from "react";
import { useState, useCallback } from "react";
import {
  ImageIcon,
  RefreshCw,
  AlertCircle,
  Check,
  ChevronLeft,
  ChevronRight,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { useComicStore } from "@/store/comicStore";
import { generatePanelImage } from "@/services/falAiService";
import type { Panel, PanelImage } from "@/types";

interface PanelCardProps {
  panel: Panel;
  image: PanelImage | undefined;
  isGenerating: boolean;
  onGenerate: () => void;
  panelNumber: number;
}

function PanelCard({
  panel,
  image,
  isGenerating,
  onGenerate,
  panelNumber,
}: PanelCardProps): JSX.Element {

  return (
    <div className="border rounded-lg bg-card overflow-hidden flex flex-col">
      {/* Panel Header */}
      <div className="px-3 py-2 border-b bg-muted/30 flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="text-sm font-medium">Panel {panelNumber}</span>
          <span className="text-xs px-1.5 py-0.5 bg-secondary text-secondary-foreground rounded capitalize">
            {panel.shotType}
          </span>
        </div>
        {image && (
          <Check className="w-4 h-4 text-green-500" />
        )}
      </div>

      {/* Panel Image */}
      <div className="aspect-video bg-muted flex items-center justify-center relative flex-1 min-h-[150px]">
        {image ? (
          <img
            src={image.url}
            alt={`Panel ${panelNumber}`}
            className="w-full h-full object-contain"
          />
        ) : (
          <div className="text-center p-4">
            <ImageIcon className="w-10 h-10 text-muted-foreground mx-auto mb-2" />
            <p className="text-sm text-muted-foreground">No image generated</p>
          </div>
        )}

        {/* Generate Button Overlay */}
        {!image && !isGenerating && (
          <div className="absolute inset-0 flex items-center justify-center bg-black/50 opacity-0 hover:opacity-100 transition-opacity">
            <Button onClick={onGenerate} variant="secondary" size="sm">
              Generate
            </Button>
          </div>
        )}

        {isGenerating && (
          <div className="absolute inset-0 flex items-center justify-center bg-black/50">
            <RefreshCw className="w-8 h-8 text-white animate-spin" />
          </div>
        )}
      </div>

      {/* Panel Details */}
      <div className="px-3 py-2 border-t text-xs text-muted-foreground space-y-1">
        <p className="line-clamp-2">{panel.description}</p>
        {panel.charactersPresent.length > 0 && (
          <div className="flex flex-wrap gap-1">
            {panel.charactersPresent.map((charId) => (
              <span
                key={charId}
                className="px-1.5 py-0.5 bg-background border rounded"
              >
                {charId}
              </span>
            ))}
          </div>
        )}
      </div>

      {/* Actions */}
      {image && (
        <div className="px-3 py-2 border-t flex gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={onGenerate}
            disabled={isGenerating}
            className="flex-1"
          >
            <RefreshCw
              className={`w-3 h-3 mr-1 ${isGenerating ? "animate-spin" : ""}`}
            />
            Regenerate
          </Button>
        </div>
      )}
    </div>
  );
}

export function PanelGrid(): JSX.Element {
  const {
    script,
    characters,
    panelImages,
    setPanelImage,
    artStyle,
    project,
    setWorkflowStep,
    workflow,
    setWorkflowError,
  } = useComicStore();

  const [generatingId, setGeneratingId] = useState<string | null>(null);
  const [isGeneratingAll, setIsGeneratingAll] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(0);

  // Collect all panels from all pages
  const allPanels =
    script?.pages.flatMap((page, pageIdx) =>
      page.panels.map((panel) => ({
        ...panel,
        pageNumber: pageIdx + 1,
      })
    )) || [];

  const totalPanels = allPanels.length;
  const generatedCount = Object.keys(panelImages).length;
  const allGenerated = totalPanels > 0 && generatedCount === totalPanels;

  const handleGeneratePanel = useCallback(
    async (panel: Panel) => {
      setGeneratingId(panel.panelId);
      setError(null);

      try {
        const result = await generatePanelImage(
          panel,
          characters,
          artStyle,
          project.projectId
        );
        setPanelImage(panel.panelId, result);
      } catch (err) {
        const msg =
          err instanceof Error
            ? err.message
            : "Failed to generate panel image";
        setError(msg);
        setWorkflowError(msg);
      } finally {
        setGeneratingId(null);
      }
    },
    [characters, artStyle, project.projectId, setPanelImage, setWorkflowError]
  );

  const handleGenerateAll = useCallback(async () => {
    if (allPanels.length === 0) return;

    setIsGeneratingAll(true);
    setError(null);

    try {
      // Generate in batches of 3
      const batchSize = 3;
      for (let i = 0; i < allPanels.length; i += batchSize) {
        const batch = allPanels.slice(i, i + batchSize);

        const results = await Promise.allSettled(
          batch.map((panel) =>
            generatePanelImage(panel, characters, artStyle, project.projectId)
          )
        );

        results.forEach((result, idx) => {
          const panel = batch[idx];
          if (result.status === "fulfilled") {
            setPanelImage(panel.panelId, result.value);
          } else {
            console.error(
              `Failed to generate panel ${panel.panelId}:`,
              result.reason
            );
          }
        });

        // Small delay between batches
        if (i + batchSize < allPanels.length) {
          await new Promise((resolve) => setTimeout(resolve, 500));
        }
      }
    } catch (err) {
      const msg =
        err instanceof Error ? err.message : "Failed to generate panels";
      setError(msg);
      setWorkflowError(msg);
    } finally {
      setIsGeneratingAll(false);
    }
  }, [
    allPanels,
    characters,
    artStyle,
    project.projectId,
    setPanelImage,
    setWorkflowError,
  ]);

  const handleProceed = useCallback(() => {
    setWorkflowStep("layout");
  }, [setWorkflowStep]);

  // Calculate pages for pagination (if many panels)
  const panelsPerPage = 6;
  const totalPages = Math.ceil(allPanels.length / panelsPerPage);
  const displayedPanels = allPanels.slice(
    currentPage * panelsPerPage,
    (currentPage + 1) * panelsPerPage
  );

  if (!script) {
    return (
      <div className="flex items-center justify-center h-full">
        <p className="text-muted-foreground">
          No script available. Generate a script first.
        </p>
      </div>
    );
  }

  return (
    <div className="max-w-6xl mx-auto space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold flex items-center gap-2">
            <ImageIcon className="w-6 h-6" />
            Panel Generation
          </h2>
          <p className="text-muted-foreground">
            {generatedCount} of {totalPanels} panels generated
          </p>
        </div>

        <div className="flex gap-2">
          <Button
            variant="outline"
            onClick={handleGenerateAll}
            disabled={isGeneratingAll || allPanels.length === 0}
          >
            {isGeneratingAll ? (
              <>
                <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                Generating...
              </>
            ) : (
              "Generate All"
            )}
          </Button>
          <Button onClick={handleProceed} disabled={!allGenerated}>
            {allGenerated ? "Proceed to Layout" : "Generate All Panels First"}
          </Button>
        </div>
      </div>

      {/* Error Display */}
      {(error || workflow.error) && (
        <div className="bg-destructive/10 border border-destructive/30 text-destructive px-4 py-3 rounded-lg flex items-center gap-3">
          <AlertCircle className="w-5 h-5 shrink-0" />
          <p className="text-sm">{error || workflow.error}</p>
        </div>
      )}

      {/* Progress */}
      {totalPanels > 0 && (
        <div className="space-y-2">
          <div className="h-2 bg-muted rounded-full overflow-hidden">
            <div
              className="h-full bg-primary transition-all duration-500"
              style={{ width: `${(generatedCount / totalPanels) * 100}%` }}
            />
          </div>
          <p className="text-center text-sm text-muted-foreground">
            {allGenerated
              ? "All panels ready for layout!"
              : `${totalPanels - generatedCount} panels need to be generated`}
          </p>
        </div>
      )}

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-center gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}
            disabled={currentPage === 0}
          >
            <ChevronLeft className="w-4 h-4" />
          </Button>
          <span className="text-sm text-muted-foreground">
            Page {currentPage + 1} of {totalPages}
          </span>
          <Button
            variant="outline"
            size="sm"
            onClick={() =>
              setCurrentPage((p) => Math.min(totalPages - 1, p + 1))
            }
            disabled={currentPage === totalPages - 1}
          >
            <ChevronRight className="w-4 h-4" />
          </Button>
        </div>
      )}

      {/* Panel Grid */}
      {allPanels.length === 0 ? (
        <div className="text-center py-12 bg-muted/50 rounded-lg">
          <ImageIcon className="w-12 h-12 text-muted-foreground mx-auto mb-4" />
          <p className="text-muted-foreground">No panels found in the script.</p>
          <p className="text-sm text-muted-foreground mt-1">
            Go back and generate a script with panels first.
          </p>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {displayedPanels.map((panel, index) => (
            <PanelCard
              key={panel.panelId}
              panel={panel}
              image={panelImages[panel.panelId]}
              isGenerating={generatingId === panel.panelId}
              onGenerate={() => handleGeneratePanel(panel)}
              panelNumber={currentPage * panelsPerPage + index + 1}
            />
          ))}
        </div>
      )}
    </div>
  );
}
