import React, { useRef, useState } from 'react';
import { ArrowLeft, ArrowRight, CheckCircle2, FileText, Link2, Paperclip, PlusCircle, RefreshCw, StickyNote, Trash2 } from 'lucide-react';
import { motion } from 'framer-motion';
import { supabase } from '../services/supabase';
import { useAuth } from '../context/useAuth';
import type { UiMode } from '../services/uiMode';
import { getApiUrl } from '../services/runtimeConfig';

type ProjectSource =
  | {
      id: string;
      kind: 'link';
      label: string;
      url: string;
    }
  | {
      id: string;
      kind: 'note';
      label: string;
      content: string;
    }
  | {
      id: string;
      kind: 'file';
      label: string;
      fileName: string;
      mimeType: string;
      size: number;
      content?: string;
      extracted: boolean;
    };

const supportedTextMimeTypes = new Set([
  'text/plain',
  'text/markdown',
  'text/csv',
  'application/json',
]);

const formatFileSize = (size: number) => {
  if (size < 1024) return `${size} B`;
  if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`;
  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
};

const buildContextPayload = (baseContext: string, sources: ProjectSource[]) => {
  const sections: string[] = [];

  const trimmedContext = baseContext.trim();
  if (trimmedContext) {
    sections.push(trimmedContext);
  }

  if (sources.length) {
    const sourceLines = sources.flatMap((source, index) => {
      if (source.kind === 'link') {
        return [`${index + 1}. [${source.label}](${source.url})`];
      }

      if (source.kind === 'note') {
        return [
          `${index + 1}. ${source.label}`,
          source.content,
        ];
      }

      const metadata = `${source.fileName} (${source.mimeType || 'unknown'}, ${formatFileSize(source.size)})`;
      if (source.extracted && source.content) {
        return [
          `${index + 1}. ${source.label} - ${metadata}`,
          source.content,
        ];
      }

      return [`${index + 1}. ${source.label} - ${metadata}`];
    });

    sections.push(`Project Sources:\n${sourceLines.join('\n\n')}`);
  }

  return sections.join('\n\n').trim();
};

const FieldHelp: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (
  <aside className="field-help">
    <strong>{title}</strong>
    <p>{children}</p>
  </aside>
);

const wizardSteps = [
  {
    title: 'Basics',
    description: 'Name the workspace and describe the business outcome. Agents use this to understand what success looks like.'
  },
  {
    title: 'Context',
    description: 'Add constraints, acceptance criteria, tone, risks, and assumptions. Good context reduces generic task plans.'
  },
  {
    title: 'Sources',
    description: 'Attach links, notes, or files that should influence planning. This step is optional when the description is enough.'
  },
  {
    title: 'Review',
    description: 'Check the setup before creating the project. You will generate tasks from the project page after creation.'
  },
  {
    title: 'Magic Generation',
    description: 'Describe your project in natural language and attach reference docs. AI will pre-configure the workspace for you.'
  }
];

const expertAccessStep = {
  title: 'Workspace',
  description: 'Decide whether this project is personal or belongs to a team workspace.'
};

const NewProject: React.FC<{ uiMode: UiMode; initialData?: any; onCreated?: () => void }> = ({ uiMode, initialData, onCreated }) => {
  const { user } = useAuth();
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [context, setContext] = useState('');
  const [sourceLabel, setSourceLabel] = useState('');
  const [sourceUrl, setSourceUrl] = useState('');
  const [noteLabel, setNoteLabel] = useState('');
  const [noteContent, setNoteContent] = useState('');
  const [sources, setSources] = useState<ProjectSource[]>([]);
  const [isPublic, setIsPublic] = useState(false);
  const [teams, setTeams] = useState<{ id: string; name: string }[]>([]);
  const [selectedTeamId, setSelectedTeamId] = useState<string | null>(null);
  const [showAdvancedSources, setShowAdvancedSources] = useState(uiMode === 'expert');
  const [wizardStep, setWizardStep] = useState(0);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [aiPrompt, setAiPrompt] = useState('');
  const [isGenerating, setIsGenerating] = useState(false);
  const [generationFiles, setGenerationFiles] = useState<File[]>([]);
  
  React.useEffect(() => {
    if (uiMode === 'expert') {
      fetchTeams();
    }
  }, [uiMode]);

  // Hydrate from Magic Bar / external data
  React.useEffect(() => {
    if (initialData) {
      if (initialData.name) setName(initialData.name);
      if (initialData.description) setDescription(initialData.description);
      if (initialData.context) setContext(initialData.context);
      if (initialData.sources && Array.isArray(initialData.sources)) {
        const aiSources: ProjectSource[] = initialData.sources.map((s: any) => ({
          id: crypto.randomUUID(),
          ...s
        }));
        setSources(aiSources);
      }
      // If we have initial data, jump to step 0 of the wizard (Basics) 
      // but ensure we are in the wizard view
      setWizardStep(0);
    }
  }, [initialData]);

  const handleAiGenerate = async () => {
    if (!aiPrompt.trim()) return;
    setIsGenerating(true);
    setMessage('AI is analyzing your request and documents...');

    try {
      const formData = new FormData();
      formData.append('prompt', aiPrompt);
      generationFiles.forEach(file => {
        formData.append('files', file);
      });

      const response = await fetch(`${getApiUrl()}/generator/generate-project`, {
        method: 'POST',
        body: formData
      });

      if (!response.ok) throw new Error('AI generation failed');
      
      const data = await response.json();
      
      setName(data.name || '');
      setDescription(data.description || '');
      setContext(data.context || '');
      
      if (data.sources && Array.isArray(data.sources)) {
        const aiSources: ProjectSource[] = data.sources.map((s: any) => ({
          id: crypto.randomUUID(),
          ...s
        }));
        setSources(prev => [...prev, ...aiSources]);
      }

      setMessage('Success! AI has drafted your project. Review the fields in the next steps.');
      setWizardStep(1);
    } catch (err: any) {
      console.error('AI Generation Error:', err);
      setMessage(`AI Error: ${err.message}`);
    } finally {
      setIsGenerating(false);
    }
  };

  const fetchTeams = async () => {
    try {
      const { data, error } = await supabase.from('teams').select('id, name');
      if (error) throw error;
      setTeams(data || []);
    } catch (err) {
      console.error('Failed to fetch teams:', err);
    }
  };
  const isWizard = true;
  const projectWizardSteps = uiMode === 'expert'
    ? [wizardSteps[4], wizardSteps[0], wizardSteps[1], wizardSteps[2], expertAccessStep, wizardSteps[3]]
    : [wizardSteps[4], wizardSteps[0], wizardSteps[1], wizardSteps[2], wizardSteps[3]];
  const reviewStepIndex = projectWizardSteps.length - 1;
  const accessStepIndex = uiMode === 'expert' ? 4 : -1;
  const currentWizardStep = projectWizardSteps[wizardStep] ?? projectWizardSteps[0];
  const isFirstWizardStep = wizardStep === 0;
  const isLastWizardStep = wizardStep === reviewStepIndex;

  const appendSource = (source: ProjectSource) => {
    setSources((current) => [...current, source]);
  };

  const handleAddLink = () => {
    if (!sourceUrl.trim()) {
      setMessage('Add a valid link before saving it.');
      return;
    }

    appendSource({
      id: crypto.randomUUID(),
      kind: 'link',
      label: sourceLabel.trim() || sourceUrl.trim(),
      url: sourceUrl.trim(),
    });

    setSourceLabel('');
    setSourceUrl('');
    setMessage(null);
  };

  const handleAddNote = () => {
    if (!noteContent.trim()) {
      setMessage('Write some note content before saving it.');
      return;
    }

    appendSource({
      id: crypto.randomUUID(),
      kind: 'note',
      label: noteLabel.trim() || 'Inline note',
      content: noteContent.trim(),
    });

    setNoteLabel('');
    setNoteContent('');
    setMessage(null);
  };

  const handleFileSelection = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files ?? []);
    const nextSources: ProjectSource[] = [];

    for (const file of files) {
      const canExtractText =
        supportedTextMimeTypes.has(file.type) ||
        /\.(md|txt|csv|json)$/i.test(file.name);

      let content: string | undefined;
      if (canExtractText) {
        content = (await file.text()).slice(0, 12000);
      }

      nextSources.push({
        id: crypto.randomUUID(),
        kind: 'file',
        label: file.name,
        fileName: file.name,
        mimeType: file.type,
        size: file.size,
        content,
        extracted: Boolean(content),
      });
    }

    if (nextSources.length) {
      setSources((current) => [...current, ...nextSources]);
      setMessage(null);
    }

    event.target.value = '';
  };

  const removeSource = (id: string) => {
    setSources((current) => current.filter((source) => source.id !== id));
  };

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!user) {
      setMessage('You must be signed in to create a project.');
      return;
    }

    setSaving(true);
    setMessage(null);

    const contextPayload = buildContextPayload(context, sources);

    const { error } = await supabase.from('projects').insert({
      name,
      description,
      context: contextPayload,
      owner_id: user.id,
      team_id: selectedTeamId,
      is_public: isPublic,
      status: 'active'
    });

    if (error) {
      setMessage(error.message);
    } else {
      setName('');
      setDescription('');
      setContext('');
      setSourceLabel('');
      setSourceUrl('');
      setNoteLabel('');
      setNoteContent('');
      setSources([]);
      setIsPublic(false);
      setWizardStep(0);
      setMessage('Project created successfully.');
      window.setTimeout(() => onCreated?.(), 500);
    }

    setSaving(false);
  };

  return (
    <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="form-panel form-panel-wide">
      <div className="panel-heading">
        <PlusCircle size={32} color="var(--accent)" />
        <div>
          <h2>Create Project</h2>
          <p style={{ color: 'var(--text-dim)', fontSize: '0.9rem' }}>
            {uiMode === 'guided'
              ? 'Describe the goal, add relevant context, and create the workspace.'
              : 'Start a workspace for agents, tasks, context, and reviews.'}
          </p>
        </div>
      </div>

      <form className="glass-panel project-form" onSubmit={handleSubmit}>
        {isWizard && (
          <div className="wizard-panel">
            <div className="wizard-steps" aria-label="Create project steps">
              {projectWizardSteps.map((step, index) => (
                <button
                  key={step.title}
                  className={`wizard-step ${wizardStep === index ? 'active' : ''} ${wizardStep > index ? 'complete' : ''}`}
                  type="button"
                  onClick={() => setWizardStep(index)}
                >
                  <span>{index + 1}</span>
                  {step.title}
                </button>
              ))}
            </div>
            <div className="wizard-explanation">
              <strong>{currentWizardStep.title}</strong>
              <p>{currentWizardStep.description}</p>
            </div>
          </div>
        )}

        {wizardStep === 0 && (
          <motion.div initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} className="wizard-form">
            <div className="form-group">
              <label>What would you like to build?</label>
              <textarea 
                placeholder='e.g., "Make me a security audit project for a Fintech app. Use the attached compliance docs as reference. I need to focus on OWASP Top 10."'
                value={aiPrompt}
                onChange={(e) => setAiPrompt(e.target.value)}
                style={{ height: '160px', resize: 'none' }}
              />
            </div>
            
            <div className="form-group">
              <label>Reference Documents (Optional)</label>
              <div 
                className="drop-zone"
                onDragOver={(e) => e.preventDefault()}
                onDrop={(e) => {
                  e.preventDefault();
                  const dropped = Array.from(e.dataTransfer.files);
                  setGenerationFiles(prev => [...prev, ...dropped]);
                }}
                onClick={() => {
                   const input = document.createElement('input');
                   input.type = 'file';
                   input.multiple = true;
                   input.onchange = (e) => {
                     const selected = Array.from((e.target as HTMLInputElement).files || []);
                     setGenerationFiles(prev => [...prev, ...selected]);
                   };
                   input.click();
                }}
                style={{
                  border: '2px dashed var(--border)',
                  borderRadius: 'var(--radius-md)',
                  padding: 'var(--space-xl)',
                  textAlign: 'center',
                  cursor: 'pointer',
                  background: 'rgba(255,255,255,0.02)'
                }}
              >
                <Paperclip size={24} style={{ marginBottom: '8px', opacity: 0.5 }} />
                <p style={{ margin: 0 }}>Click or drag files to use as AI context</p>
                <span style={{ fontSize: '0.8rem', opacity: 0.6 }}>Supports PDF, Text, Markdown, JSON</span>
              </div>
              
              {generationFiles.length > 0 && (
                <div style={{ marginTop: 'var(--space-md)', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                  {generationFiles.map((f, i) => (
                    <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: 'rgba(255,255,255,0.04)', padding: '8px 12px', borderRadius: '4px' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '0.9rem' }}>
                        <FileText size={14} />
                        <span>{f.name}</span>
                      </div>
                      <button 
                        className="btn-icon" 
                        onClick={() => setGenerationFiles(prev => prev.filter((_, idx) => idx !== i))}
                        style={{ color: 'var(--danger)' }}
                      >
                        <Trash2 size={14} />
                      </button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            <div style={{ marginTop: 'var(--space-xl)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <button className="btn btn-glass" type="button" onClick={() => setWizardStep(1)}>
                Skip to manual setup
              </button>
              <button 
                className="btn btn-primary" 
                type="button"
                onClick={handleAiGenerate}
                disabled={!aiPrompt.trim() || isGenerating}
              >
                {isGenerating ? <RefreshCw className="spin" size={18} /> : <PlusCircle size={18} />}
                {isGenerating ? 'Generating...' : 'Generate Project Structure'}
              </button>
            </div>
          </motion.div>
        )}

        {wizardStep === 1 && (
        <>
        <div className="field-with-help">
          <label>
            <span>Project Name</span>
            <input value={name} onChange={(event) => setName(event.target.value)} required placeholder="Customer onboarding automation" />
          </label>
          <FieldHelp title="What this controls">
            This becomes the workspace title shown on the dashboard, task pages, reports, and spatial view. Use a short outcome-oriented name.
          </FieldHelp>
        </div>

        <div className="field-with-help">
          <label>
            <span>Description</span>
            <textarea value={description} onChange={(event) => setDescription(event.target.value)} placeholder="What should this project accomplish?" rows={4} />
          </label>
          <FieldHelp title="How agents use it">
            The planner reads this as the main objective when decomposing work. Include the desired result, audience, and success criteria.
          </FieldHelp>
        </div>
        </>
        )}

        {wizardStep === 2 && (
        <div className="field-with-help">
          <label>
            <span>Context</span>
            <textarea value={context} onChange={(event) => setContext(event.target.value)} placeholder="Business constraints, preferred tone, source links, acceptance criteria..." rows={6} />
          </label>
          <FieldHelp title="When to add context">
            Add constraints, assumptions, tone, links, examples, acceptance criteria, and known risks. This reduces generic agent output.
          </FieldHelp>
        </div>
        )}

        {wizardStep === 3 && (
        <div className="default-agent-panel project-sources-panel" style={{ gap: 'var(--space-lg)' }}>
          <div className="settings-section-title">
            <Paperclip size={20} color="var(--accent)" />
            <h3>Project Sources</h3>
          </div>
          <div className="field-with-help field-with-help-compact">
            <div>
              {uiMode === 'guided' && !showAdvancedSources && (
                <>
                  <p style={{ color: 'var(--text-dim)', fontSize: '0.9rem' }}>
                    Add the links, notes, or files that should shape the plan. Skip this if the description already contains enough context.
                  </p>
                  <button className="btn btn-glass" type="button" onClick={() => setShowAdvancedSources(true)}>
                    <Paperclip size={16} />
                    Add Sources
                  </button>
                </>
              )}

              {(uiMode === 'expert' || showAdvancedSources) && (
                <>
                  <div className="responsive-two-col">
                    <label>
                      <span>Link Label</span>
                      <input value={sourceLabel} onChange={(event) => setSourceLabel(event.target.value)} placeholder="Market report" />
                    </label>
                    <label>
                      <span>Link URL</span>
                      <input value={sourceUrl} onChange={(event) => setSourceUrl(event.target.value)} placeholder="https://..." />
                    </label>
                  </div>
                  <button className="btn btn-glass" type="button" onClick={handleAddLink}>
                    <Link2 size={16} />
                    Add Link
                  </button>

                  <label>
                    <span>Quick Note</span>
                    <input value={noteLabel} onChange={(event) => setNoteLabel(event.target.value)} placeholder="Stakeholder note" />
                  </label>
                  <label>
                    <span>Note Content</span>
                    <textarea value={noteContent} onChange={(event) => setNoteContent(event.target.value)} rows={3} placeholder="Paste text, markdown, requirements, or snippets..." />
                  </label>
                  <button className="btn btn-glass" type="button" onClick={handleAddNote}>
                    <StickyNote size={16} />
                    Add Text
                  </button>

                  <input
                    ref={fileInputRef}
                    type="file"
                    multiple
                    accept=".pdf,.md,.txt,.doc,.docx,.xls,.xlsx,.csv,.json,.rtf"
                    onChange={handleFileSelection}
                    style={{ display: 'none' }}
                  />
                  <button className="btn btn-glass" type="button" onClick={() => fileInputRef.current?.click()}>
                    <Paperclip size={16} />
                    Add Files
                  </button>

                  <p style={{ color: 'var(--text-dim)', fontSize: '0.85rem', marginTop: '-0.25rem' }}>
                    Text and markdown files are embedded into project context. PDF, Word, and Excel files are stored as named references in the context.
                  </p>
                </>
              )}
            </div>
            <FieldHelp title="What sources do">
              Sources are appended to the project context before agents plan work. Use links for references, notes for stakeholder input, and files for specs or datasets.
            </FieldHelp>
          </div>

          {sources.length > 0 && (
            <div className="task-list">
              {sources.map((source) => (
                <div key={source.id} className="task-row">
                  <div style={{ flex: 1 }}>
                    <strong>{source.label}</strong>
                    <p>
                      {source.kind === 'link' && source.url}
                      {source.kind === 'note' && source.content}
                      {source.kind === 'file' && `${source.fileName} - ${formatFileSize(source.size)}${source.extracted ? ' - text imported' : ' - reference only'}`}
                    </p>
                  </div>
                  <button className="btn btn-glass btn-sm" type="button" onClick={() => removeSource(source.id)}>
                    <Trash2 size={14} />
                    Remove
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
        )}

        {uiMode === 'expert' && wizardStep === accessStepIndex && (
          <div className="expert-access-fields" style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-lg)' }}>
            <div className="field-with-help">
              <label>
                <span>Team Workspace (Optional)</span>
                <select 
                  className="glass-input" 
                  value={selectedTeamId || ''} 
                  onChange={(e) => setSelectedTeamId(e.target.value || null)}
                >
                  <option value="">Personal Project (No Team)</option>
                  {teams.map(team => (
                    <option key={team.id} value={team.id}>{team.name}</option>
                  ))}
                </select>
              </label>
              <FieldHelp title="Shared Context">
                Projects assigned to a team are visible to all team members according to their roles (admin, editor, viewer).
              </FieldHelp>
            </div>

            <div className="field-with-help">
              <label className="toggle-row">
                <input type="checkbox" checked={isPublic} onChange={(event) => setIsPublic(event.target.checked)} />
                <span>Make project visible to all authenticated users (Public)</span>
              </label>
              <FieldHelp title="Global Visibility">
                Public projects can be read by any authenticated user in the entire platform. Use this for open templates or public datasets.
              </FieldHelp>
            </div>
          </div>
        )}

        {wizardStep === reviewStepIndex && (
          <div className="wizard-review">
            <div>
              <span>Project name</span>
              <strong>{name.trim() || 'Missing project name'}</strong>
            </div>
            <div>
              <span>Description</span>
              <p>{description.trim() || 'No description provided.'}</p>
            </div>
            <div>
              <span>Workspace</span>
              <p>{selectedTeamId ? `Team: ${teams.find(t => t.id === selectedTeamId)?.name}` : 'Personal project'}</p>
            </div>
            <div>
              <span>Visibility</span>
              <p>{isPublic ? 'Public' : 'Private'}</p>
            </div>
            <div>
              <span>Context</span>
              <p>{context.trim() || 'No extra context provided.'}</p>
            </div>
            <div>
              <span>Sources</span>
              <p>{sources.length > 0 ? `${sources.length} source${sources.length === 1 ? '' : 's'} attached.` : 'No sources attached.'}</p>
            </div>
          </div>
        )}

        {message && (
          <div className="inline-status">
            {message.includes('success') ? <CheckCircle2 size={16} color="var(--success)" /> : <FileText size={16} color="var(--warning)" />}
            <span>{message}</span>
          </div>
        )}

        <div className="field-with-help field-with-help-action">
          <div className="wizard-actions" style={{ display: 'flex', gap: 'var(--space-md)', width: '100%' }}>
            <button 
              className="btn btn-glass" 
              type="button" 
              onClick={() => setWizardStep((step) => Math.max(0, step - 1))} 
              disabled={isFirstWizardStep || saving}
              style={{ flex: 1 }}
            >
              <ArrowLeft size={18} />
              Back
            </button>
            {!isLastWizardStep ? (
              <button
                className="btn btn-primary"
                type="button"
                onClick={() => {
                  if (wizardStep === 1 && !name.trim()) {
                    setMessage('Project name is required');
                    return;
                  }
                  setWizardStep((step) => Math.min(projectWizardSteps.length - 1, step + 1));
                }}
                disabled={saving}
                style={{ flex: 1 }}
              >
                Next
                <ArrowRight size={18} />
              </button>
            ) : (
              <button 
                className="btn btn-primary" 
                type="submit" 
                disabled={saving || !name.trim()}
                style={{ flex: 1 }}
              >
                {saving ? <RefreshCw className="spin" size={18} /> : <PlusCircle size={18} />}
                {saving ? 'Creating...' : 'Create Project'}
              </button>
            )}
          </div>
          <FieldHelp title="Next step">
            After creation, open the project and run the orchestrator to generate tasks. Review outputs before approving the final report.
          </FieldHelp>
        </div>
      </form>
    </motion.div>
  );
};

export default NewProject;
