import React, { createContext, useContext, useState, ReactNode } from 'react';
import { Task, UserStory, Sprint } from '../types';

interface AppContextType {
  tasks: Task[];
  userStories: UserStory[];
  sprints: Sprint[];
  activeSprint: Sprint | null;
  addTask: (task: Omit<Task, 'id' | 'createdAt' | 'updatedAt' | 'comments'>) => void;
  updateTask: (id: string, updates: Partial<Task>) => void;
  deleteTask: (id: string) => void;
  addComment: (taskId: string, comment: string, author: string) => void;
  addUserStory: (story: Omit<UserStory, 'id'>) => void;
  updateUserStory: (id: string, updates: Partial<UserStory>) => void;
  reorderUserStories: (stories: UserStory[]) => void;
  addSprint: (sprint: Omit<Sprint, 'id'>) => void;
  updateSprint: (id: string, updates: Partial<Sprint>) => void;
  closeSprint: (id: string) => void;
  setActiveSprint: (sprint: Sprint) => void;
}

const AppContext = createContext<AppContextType | undefined>(undefined);

export const useApp = () => {
  const context = useContext(AppContext);
  if (!context) {
    throw new Error('useApp must be used within AppProvider');
  }
  return context;
};

const mockUserStories: UserStory[] = [
  {
    id: 'us-1',
    title: 'User Authentication',
    description: 'As a user, I want to log in securely',
    storyPoints: 5,
    businessValue: 8,
    acceptanceCriteria: 'User can login with email and password',
    status: 'in-sprint',
    priority: 1,
    sprintId: 'sprint-1'
  },
  {
    id: 'us-2',
    title: 'Dashboard View',
    description: 'As a user, I want to see my dashboard',
    storyPoints: 8,
    businessValue: 9,
    acceptanceCriteria: 'Dashboard shows key metrics and recent activity',
    status: 'in-sprint',
    priority: 2,
    sprintId: 'sprint-1'
  },
  {
    id: 'us-3',
    title: 'Data Export',
    description: 'As a user, I want to export my data',
    storyPoints: 3,
    businessValue: 5,
    acceptanceCriteria: 'User can export data in CSV format',
    status: 'sprint-ready',
    priority: 3
  }
];

const mockSprint: Sprint = {
  id: 'sprint-1',
  name: 'Sprint 1',
  goal: 'Deliver core authentication and dashboard features',
  startDate: new Date('2025-10-13'),
  endDate: new Date('2025-10-27'),
  capacity: 40,
  status: 'active',
  userStories: ['us-1', 'us-2']
};

const mockTasks: Task[] = [
  {
    id: 'task-1',
    title: 'Design login form',
    description: 'Create mockups for the login interface',
    timeComplexity: '4 hours',
    status: 'done',
    userStoryId: 'us-1',
    comments: [
      {
        id: 'c-1',
        text: 'Mockups look great!',
        author: 'Jane Smith',
        timestamp: new Date('2025-10-14')
      }
    ],
    createdAt: new Date('2025-10-13'),
    updatedAt: new Date('2025-10-14')
  },
  {
    id: 'task-2',
    title: 'Implement authentication API',
    description: 'Set up backend authentication endpoints',
    timeComplexity: '8 hours',
    status: 'in-progress',
    userStoryId: 'us-1',
    comments: [],
    createdAt: new Date('2025-10-13'),
    updatedAt: new Date('2025-10-15')
  },
  {
    id: 'task-3',
    title: 'Create dashboard layout',
    description: 'Build responsive dashboard layout',
    timeComplexity: '6 hours',
    status: 'todo',
    userStoryId: 'us-2',
    comments: [],
    createdAt: new Date('2025-10-13'),
    updatedAt: new Date('2025-10-13')
  }
];

export const AppProvider = ({ children }: { children: ReactNode }) => {
  const [tasks, setTasks] = useState<Task[]>(mockTasks);
  const [userStories, setUserStories] = useState<UserStory[]>(mockUserStories);
  const [sprints, setSprints] = useState<Sprint[]>([mockSprint]);
  const [activeSprint, setActiveSprintState] = useState<Sprint | null>(mockSprint);

  const addTask = (taskData: Omit<Task, 'id' | 'createdAt' | 'updatedAt' | 'comments'>) => {
    const newTask: Task = {
      ...taskData,
      id: `task-${Date.now()}`,
      comments: [],
      createdAt: new Date(),
      updatedAt: new Date()
    };
    setTasks([...tasks, newTask]);
  };

  const updateTask = (id: string, updates: Partial<Task>) => {
    setTasks(tasks.map(task => 
      task.id === id ? { ...task, ...updates, updatedAt: new Date() } : task
    ));
  };

  const deleteTask = (id: string) => {
    setTasks(tasks.filter(task => task.id !== id));
  };

  const addComment = (taskId: string, text: string, author: string) => {
    setTasks(tasks.map(task => {
      if (task.id === taskId) {
        return {
          ...task,
          comments: [
            ...task.comments,
            {
              id: `c-${Date.now()}`,
              text,
              author,
              timestamp: new Date()
            }
          ],
          updatedAt: new Date()
        };
      }
      return task;
    }));
  };

  const addUserStory = (storyData: Omit<UserStory, 'id'>) => {
    const newStory: UserStory = {
      ...storyData,
      id: `us-${Date.now()}`
    };
    setUserStories([...userStories, newStory]);
  };

  const updateUserStory = (id: string, updates: Partial<UserStory>) => {
    setUserStories(userStories.map(story => 
      story.id === id ? { ...story, ...updates } : story
    ));
  };

  const reorderUserStories = (stories: UserStory[]) => {
    setUserStories(stories);
  };

  const addSprint = (sprintData: Omit<Sprint, 'id'>) => {
    const newSprint: Sprint = {
      ...sprintData,
      id: `sprint-${Date.now()}`
    };
    setSprints([...sprints, newSprint]);
  };

  const updateSprint = (id: string, updates: Partial<Sprint>) => {
    setSprints(sprints.map(sprint => 
      sprint.id === id ? { ...sprint, ...updates } : sprint
    ));
    if (activeSprint?.id === id) {
      setActiveSprintState(prev => prev ? { ...prev, ...updates } : null);
    }
  };

  const closeSprint = (id: string) => {
    // Move unfinished items back to backlog
    const sprint = sprints.find(s => s.id === id);
    if (sprint) {
      setUserStories(userStories.map(story => {
        if (story.sprintId === id) {
          return { ...story, status: 'backlog', sprintId: undefined };
        }
        return story;
      }));
      
      setSprints(sprints.map(s => 
        s.id === id ? { ...s, status: 'closed' as const } : s
      ));
      
      if (activeSprint?.id === id) {
        setActiveSprintState(null);
      }
    }
  };

  const setActiveSprint = (sprint: Sprint) => {
    setActiveSprintState(sprint);
  };

  return (
    <AppContext.Provider value={{
      tasks,
      userStories,
      sprints,
      activeSprint,
      addTask,
      updateTask,
      deleteTask,
      addComment,
      addUserStory,
      updateUserStory,
      reorderUserStories,
      addSprint,
      updateSprint,
      closeSprint,
      setActiveSprint
    }}>
      {children}
    </AppContext.Provider>
  );
};
