// types/templates.ts
import { BaseExercise, Equipment, ExerciseCategory, SetType } from './exercise';
import { StorageSource, SyncableContent } from './shared';
import { generateId } from '@/utils/ids';

/**
 * Template Classifications
 * Aligned with NIP-33402
 */
export type TemplateType = 'strength' | 'circuit' | 'emom' | 'amrap';

export type TemplateCategory = 
  | 'Full Body' 
  | 'Push/Pull/Legs' 
  | 'Upper/Lower' 
  | 'Custom' 
  | 'Cardio' 
  | 'CrossFit' 
  | 'Strength'
  | 'Conditioning';

/**
 * Exercise configurations within templates
 */
export interface TemplateExerciseDisplay {
  title: string;
  targetSets: number;
  targetReps: number;
  equipment?: string; 
  notes?: string;
}

export interface TemplateExerciseConfig {
  id?: string; // Add this line
  exercise: BaseExercise;
  targetSets?: number;
  targetReps?: number;
  targetWeight?: number;
  weight?: number;
  rpe?: number;
  setType?: SetType;
  restSeconds?: number;
  notes?: string;
  
  // Format configuration from NIP-33401
  format?: {
    weight?: boolean;
    reps?: boolean;
    rpe?: boolean;
    set_type?: boolean;
  };
  format_units?: {
    weight?: 'kg' | 'lbs';
    reps?: 'count';
    rpe?: '0-10';
    set_type?: 'warmup|normal|drop|failure';
  };
  
  // For timed workouts
  duration?: number;
  interval?: number;
  
  // For circuit/EMOM
  position?: number;
  roundRest?: number;
}

export interface TemplateExerciseWithData {
  id: string;
  exercise: BaseExercise;
  displayOrder: number;
  targetSets: number | null;
  targetReps: number | null;
  targetWeight: number | null;
  notes: string | null;
  nostrReference?: string | null;
}

/**
 * Template versioning and derivation tracking
 */
export interface TemplateSource {
  id: string;
  eventId?: string;
  authorName?: string;
  authorPubkey?: string;
  version?: number;
}

/**
 * Base template properties shared between UI and database
 */
export interface TemplateBase {
  id: string;
  title: string;
  type: TemplateType;
  category: TemplateCategory;
  description?: string;
  notes?: string;
  tags: string[];
  
  // Workout structure
  rounds?: number;
  duration?: number;
  interval?: number;
  restBetweenRounds?: number;
  
  // Metadata
  metadata?: {
    lastUsed?: number;
    useCount?: number;
    averageDuration?: number;
    completionRate?: number;
  };
  
  author?: {
    name: string;
    pubkey?: string;
  };
}

/**
 * UI Template - Used for display and interaction
 */
export interface Template extends TemplateBase {
  exercises: TemplateExerciseDisplay[];
  source: 'local' | 'powr' | 'nostr';
  isFavorite: boolean;  // Required for UI state
}

/**
 * Full Template - Used for database storage and Nostr events
 */
export interface WorkoutTemplate extends TemplateBase, SyncableContent {
  exercises: TemplateExerciseConfig[];
  isPublic: boolean;
  version: number;
  lastUpdated?: number;
  parentId?: string;
  
  // Template configuration
  format?: {
    weight?: boolean;
    reps?: boolean;
    rpe?: boolean;
    set_type?: boolean;
  };
  format_units?: {
    weight: 'kg' | 'lbs';
    reps: 'count';
    rpe: '0-10';
    set_type: 'warmup|normal|drop|failure';
  };
  
  // Template derivation
  sourceTemplate?: TemplateSource;
  derivatives?: {
    count: number;
    lastCreated: number;
  };
  
  // Nostr integration
  nostrEventId?: string;
  relayUrls?: string[];
  authorPubkey?: string;
  
  // Template management
  isArchived?: boolean;
}

/**
 * Helper Functions
 */

/**
 * Gets a display string for the template source
 */
export function getSourceDisplay(template: WorkoutTemplate): string {
  if (!template.sourceTemplate) {
    return template.availability.source.includes('nostr') 
      ? 'NOSTR'
      : template.availability.source.includes('powr')
        ? 'POWR'
        : 'Local Template';
  }

  const author = template.sourceTemplate.authorName || 'Unknown Author';
  if (template.sourceTemplate.version) {
    return `Modified from ${author} (v${template.sourceTemplate.version})`;
  }
  return `Original by ${author}`;
}

/**
 * Converts a WorkoutTemplate to Template for UI display
 */
export function toTemplateDisplay(template: WorkoutTemplate): Template {
  return {
    id: template.id,
    title: template.title,
    type: template.type,
    category: template.category,
    description: template.description,
    exercises: template.exercises.map(ex => ({
      title: ex.exercise.title,
      targetSets: ex.targetSets || 0, // Add default value
      targetReps: ex.targetReps || 0, // Add default value
      notes: ex.notes
    })),
    tags: template.tags,
    source: template.availability.source.includes('nostr') 
      ? 'nostr' 
      : template.availability.source.includes('powr')
        ? 'powr'
        : 'local',
    isFavorite: false,
    metadata: template.metadata,
    author: template.author
  };
}

/**
 * Converts a Template to WorkoutTemplate for storage/sync
 */
export function toWorkoutTemplate(template: Template): WorkoutTemplate {
  return {
    ...template,
    exercises: template.exercises.map(ex => ({
      exercise: {
        id: generateId(),
        title: ex.title,
        type: 'strength',
        category: 'Push' as ExerciseCategory,
        equipment: 'barbell' as Equipment,
        tags: [],
        format: {
          weight: true,
          reps: true,
          rpe: true,
          set_type: true
        },
        format_units: {
          weight: 'kg',
          reps: 'count',
          rpe: '0-10',
          set_type: 'warmup|normal|drop|failure'
        },
        availability: {
          source: ['local']
        },
        created_at: Date.now()
      },
      targetSets: ex.targetSets,
      targetReps: ex.targetReps,
      notes: ex.notes
    })),
    isPublic: false,
    version: 1,
    created_at: Date.now(),
    availability: {
      source: ['local']
    }
  };
}

/**
 * Creates a Nostr event from a template (NIP-33402)
 */
export function createNostrTemplateEvent(template: WorkoutTemplate) {
  return {
    kind: 33402,
    content: template.description || '',
    tags: [
      ['d', template.id],
      ['title', template.title],
      ['type', template.type],
      ...(template.rounds ? [['rounds', template.rounds.toString()]] : []),
      ...(template.duration ? [['duration', template.duration.toString()]] : []),
      ...(template.interval ? [['interval', template.interval.toString()]] : []),
      ...template.exercises.map(ex => [
        'exercise',
        `33401:${ex.exercise.id}`,
        (ex.targetSets || 0).toString(),
        (ex.targetReps || 0).toString(),
        ex.setType || 'normal'
      ]),
      ...template.tags.map(tag => ['t', tag])
    ],
    created_at: Math.floor(Date.now() / 1000)
  };
}