/**
 * Script Viewer Component - Professional Mode
 * 
 * Displays the generated comic script with JSON editing capabilities
 * Allows professionals to review and modify the script before proceeding
 */

import type { JSX } from 'react';
import { useState, useCallback } from 'react';
import { BookOpen, Users, LayoutGrid, ChevronDown, ChevronRight, AlertCircle, Check } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useComicStore } from '@/store/comicStore';
import { validateAndNormalizeScript } from '@/services/deepseekService';
import type { Character, Page } from '@/types';

interface ScriptSectionProps {
  title: string;
  icon: React.ComponentType<{ className?: string }>;
  children: React.ReactNode;
  defaultOpen?: boolean;
}

function ScriptSection({ title, icon: Icon, children, defaultOpen = true }: ScriptSectionProps): JSX.Element {
  const [isOpen, setIsOpen] = useState(defaultOpen);

  return (
    <div className="border rounded-lg bg-card">
      <button
        onClick={() => setIsOpen(!isOpen)}
        className="w-full flex items-center justify-between p-4 hover:bg-muted/50 transition-colors"
      >
        <div className="flex items-center gap-2">
          <Icon className="w-5 h-5 text-primary" />
          <h3 className="font-semibold">{title}</h3>
        </div>
        {isOpen ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
      </button>
      {isOpen && (
        <div className="p-4 pt-0 border-t">
          {children}
        </div>
      )}
    </div>
  );
}

function CharacterCard({ character }: { character: Character }): JSX.Element {
  return (
    <div className="p-3 bg-muted/50 rounded-lg space-y-2">
      <div className="flex items-center justify-between">
        <h4 className="font-medium">{character.name}</h4>
        <span className="text-xs px-2 py-1 bg-primary/10 text-primary rounded-full capitalize">
          {character.role}
        </span>
      </div>
      <p className="text-sm text-muted-foreground line-clamp-2">
        {character.description}
      </p>
      <div className="text-xs text-muted-foreground">
        First appearance: {character.firstAppearancePanel || 'TBD'}
      </div>
    </div>
  );
}

function PanelCard({ panel }: { panel: Page['panels'][0] }): JSX.Element {
  return (
    <div className="p-3 bg-muted/50 rounded-lg space-y-2">
      <div className="flex items-center justify-between">
        <span className="font-medium">Panel {panel.panelNumber}</span>
        <span className="text-xs px-2 py-1 bg-secondary text-secondary-foreground rounded-full capitalize">
          {panel.shotType}
        </span>
      </div>
      <p className="text-sm text-muted-foreground">
        {panel.description}
      </p>
      {panel.charactersPresent.length > 0 && (
        <div className="flex flex-wrap gap-1">
          {panel.charactersPresent.map((charId) => (
            <span key={charId} className="text-xs px-2 py-0.5 bg-background border rounded">
              {charId}
            </span>
          ))}
        </div>
      )}
      {panel.dialogue.length > 0 && (
        <div className="space-y-1 pt-2 border-t">
          {panel.dialogue.map((d, i) => (
            <div key={i} className="text-sm">
              <span className="font-medium text-primary">{d.speakerId}:</span>
              <span className="ml-2 italic">"{d.text}"</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export function ScriptViewer(): JSX.Element {
  const { 
    script, 
    userMode,
    setScript,
    setWorkflowStep,
    setCharacters,
  } = useComicStore();

  const [isEditing, setIsEditing] = useState(false);
  const [editedJson, setEditedJson] = useState('');
  const [jsonError, setJsonError] = useState<string | null>(null);

  const handleEdit = useCallback(() => {
    if (script) {
      setEditedJson(JSON.stringify(script, null, 2));
      setIsEditing(true);
      setJsonError(null);
    }
  }, [script]);

  const handleSave = useCallback(() => {
    try {
      const parsed = JSON.parse(editedJson);
      const validated = validateAndNormalizeScript(parsed);
      setScript(validated);
      setCharacters(validated.characters);
      setIsEditing(false);
      setJsonError(null);
    } catch (error) {
      setJsonError(error instanceof Error ? error.message : 'Invalid JSON');
    }
  }, [editedJson, setScript, setCharacters]);

  const handleProceed = useCallback(() => {
    setWorkflowStep('character-setup');
  }, [setWorkflowStep]);

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

  const totalPanels = script.pages.reduce((acc, page) => acc + page.panels.length, 0);

  return (
    <div className="max-w-4xl mx-auto space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold">{script.title}</h2>
          <p className="text-muted-foreground">
            {script.pages.length} pages • {totalPanels} panels • {script.characters.length} characters
          </p>
        </div>
        <div className="flex gap-2">
          {userMode === 'professional' && (
            <Button
              variant={isEditing ? "default" : "outline"}
              onClick={isEditing ? handleSave : handleEdit}
            >
              {isEditing ? (
                <>
                  <Check className="w-4 h-4 mr-2" />
                  Save Changes
                </>
              ) : (
                'Edit JSON'
              )}
            </Button>
          )}
          <Button onClick={handleProceed}>
            Proceed to Characters
          </Button>
        </div>
      </div>

      {/* Synopsis */}
      <div className="p-4 bg-muted/50 rounded-lg border">
        <h3 className="font-semibold mb-2">Synopsis</h3>
        <p className="text-muted-foreground">{script.synopsis}</p>
      </div>

      {/* JSON Editor (Professional Mode) */}
      {isEditing && userMode === 'professional' && (
        <div className="space-y-2">
          {jsonError && (
            <div className="flex items-center gap-2 text-destructive text-sm">
              <AlertCircle className="w-4 h-4" />
              {jsonError}
            </div>
          )}
          <textarea
            value={editedJson}
            onChange={(e) => setEditedJson(e.target.value)}
            className="w-full h-96 p-4 font-mono text-sm bg-muted rounded-lg border focus:outline-none focus:ring-2 focus:ring-ring"
            spellCheck={false}
          />
        </div>
      )}

      {/* Structured View */}
      {!isEditing && (
        <div className="space-y-4">
          {/* Characters Section */}
          <ScriptSection title="Characters" icon={Users}>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {script.characters.map((character) => (
                <CharacterCard key={character.id} character={character} />
              ))}
            </div>
          </ScriptSection>

          {/* Pages Section */}
          <ScriptSection title="Pages & Panels" icon={LayoutGrid}>
            <div className="space-y-4">
              {script.pages.map((page) => (
                <div key={page.pageNumber} className="space-y-2">
                  <h4 className="font-medium flex items-center gap-2">
                    <BookOpen className="w-4 h-4" />
                    Page {page.pageNumber}
                    <span className="text-xs px-2 py-0.5 bg-secondary text-secondary-foreground rounded-full capitalize">
                      {page.layoutType}
                    </span>
                  </h4>
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
                    {page.panels.map((panel) => (
                      <PanelCard 
                        key={panel.panelId} 
                        panel={panel}
                      />
                    ))}
                  </div>
                </div>
              ))}
            </div>
          </ScriptSection>
        </div>
      )}
    </div>
  );
}
