#!/bin/sh
set -e

echo "=== Creating demo git repository ==="

BARE_REPO="/workspace/demo-repo.git"
TEMP_DIR=$(mktemp -d)

# Initialize bare repo
git init --bare "$BARE_REPO"

cd "$TEMP_DIR"
git init -b main
git remote add origin "$BARE_REPO"

# ─── main branch: initial task manager app ───

cat > README.md << 'READMEEOF'
# Task Manager

A modern task management application built with React and TypeScript.

## Features

- Create, update, and delete tasks
- Filter by status and priority
- Real-time updates
- Responsive design

## Getting Started

```bash
npm install
npm run dev
```
READMEEOF

cat > package.json << 'PKGEOF'
{
  "name": "task-manager",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build"
  },
  "dependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}
PKGEOF

mkdir -p src/components src/hooks src/lib

cat > src/app.tsx << 'APPEOF'
import { useState } from 'react';
import { TaskList } from './components/TaskList';
import { Sidebar } from './components/Sidebar';

export function App() {
  const [filter, setFilter] = useState('all');

  return (
    <div className="app">
      <Sidebar filter={filter} onFilterChange={setFilter} />
      <main>
        <h1>Task Manager</h1>
        <TaskList filter={filter} />
      </main>
    </div>
  );
}
APPEOF

cat > src/components/TaskList.tsx << 'TLEOF'
import { useTasks } from '../hooks/useTasks';

interface TaskListProps {
  filter: string;
}

export function TaskList({ filter }: TaskListProps) {
  const { tasks, loading } = useTasks(filter);

  if (loading) return <div>Loading...</div>;

  return (
    <ul className="task-list">
      {tasks.map(task => (
        <li key={task.id}>
          <span>{task.title}</span>
          <span className="status">{task.status}</span>
        </li>
      ))}
    </ul>
  );
}
TLEOF

cat > src/components/Sidebar.tsx << 'SBEOF'
interface SidebarProps {
  filter: string;
  onFilterChange: (filter: string) => void;
}

export function Sidebar({ filter, onFilterChange }: SidebarProps) {
  const filters = ['all', 'active', 'completed'];

  return (
    <aside className="sidebar">
      <h2>Filters</h2>
      <ul>
        {filters.map(f => (
          <li key={f}>
            <button
              className={f === filter ? 'active' : ''}
              onClick={() => onFilterChange(f)}
            >
              {f}
            </button>
          </li>
        ))}
      </ul>
    </aside>
  );
}
SBEOF

cat > src/hooks/useTasks.ts << 'HTEOF'
import { useState, useEffect } from 'react';
import { fetchTasks } from '../lib/api';

export function useTasks(filter: string) {
  const [tasks, setTasks] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchTasks(filter).then(data => {
      setTasks(data);
      setLoading(false);
    });
  }, [filter]);

  return { tasks, loading };
}
HTEOF

cat > src/lib/api.ts << 'APIEOF'
const API_URL = '/api';

export async function fetchTasks(filter: string) {
  const res = await fetch(`${API_URL}/tasks?filter=${filter}`);
  return res.json();
}

export async function createTask(title: string) {
  const res = await fetch(`${API_URL}/tasks`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title }),
  });
  return res.json();
}
APIEOF

git add -A
git commit -m "feat: initial task manager setup"
git push origin main

# ─── initiative branch (same as main, no extra commits) ───

git checkout -b cw/task-manager-redesign
git push origin cw/task-manager-redesign

# ─── phase branch: UI overhaul with 3 commits ───

git checkout -b cw/task-manager-redesign-phase-ui-overhaul

# Commit 1: responsive header with search and notifications
mkdir -p src/components

cat > src/components/Header.tsx << 'HDREOF'
import { useState } from 'react';

interface HeaderProps {
  onSearch: (query: string) => void;
}

export function Header({ onSearch }: HeaderProps) {
  const [query, setQuery] = useState('');
  const [notifications] = useState([
    { id: 1, text: 'Task "Deploy v2" completed', unread: true },
    { id: 2, text: 'New comment on "API redesign"', unread: true },
    { id: 3, text: 'Sprint review tomorrow', unread: false },
  ]);

  const unreadCount = notifications.filter(n => n.unread).length;

  return (
    <header className="header">
      <div className="header-brand">
        <h1>TaskFlow</h1>
      </div>
      <div className="header-search">
        <input
          type="search"
          placeholder="Search tasks..."
          value={query}
          onChange={e => {
            setQuery(e.target.value);
            onSearch(e.target.value);
          }}
        />
      </div>
      <div className="header-actions">
        <button className="notification-bell" aria-label="Notifications">
          🔔 {unreadCount > 0 && <span className="badge">{unreadCount}</span>}
        </button>
        <div className="avatar">JD</div>
      </div>
    </header>
  );
}
HDREOF

cat > src/components/TaskFilters.tsx << 'TFEOF'
interface TaskFiltersProps {
  activeFilter: string;
  onFilterChange: (filter: string) => void;
  activePriority: string;
  onPriorityChange: (priority: string) => void;
}

export function TaskFilters({
  activeFilter,
  onFilterChange,
  activePriority,
  onPriorityChange,
}: TaskFiltersProps) {
  const statuses = ['all', 'active', 'completed', 'blocked'];
  const priorities = ['all', 'high', 'medium', 'low'];

  return (
    <div className="task-filters">
      <div className="filter-group">
        <label>Status</label>
        <div className="filter-buttons">
          {statuses.map(s => (
            <button
              key={s}
              className={s === activeFilter ? 'active' : ''}
              onClick={() => onFilterChange(s)}
            >
              {s}
            </button>
          ))}
        </div>
      </div>
      <div className="filter-group">
        <label>Priority</label>
        <div className="filter-buttons">
          {priorities.map(p => (
            <button
              key={p}
              className={p === activePriority ? 'active' : ''}
              onClick={() => onPriorityChange(p)}
            >
              {p}
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}
TFEOF

# Update app.tsx to use Header
cat > src/app.tsx << 'APPEOF2'
import { useState } from 'react';
import { Header } from './components/Header';
import { TaskList } from './components/TaskList';
import { TaskFilters } from './components/TaskFilters';
import { Sidebar } from './components/Sidebar';

export function App() {
  const [filter, setFilter] = useState('all');
  const [priority, setPriority] = useState('all');
  const [searchQuery, setSearchQuery] = useState('');

  return (
    <div className="app-layout">
      <Header onSearch={setSearchQuery} />
      <div className="app-body">
        <Sidebar filter={filter} onFilterChange={setFilter} />
        <main className="main-content">
          <TaskFilters
            activeFilter={filter}
            onFilterChange={setFilter}
            activePriority={priority}
            onPriorityChange={setPriority}
          />
          <TaskList filter={filter} />
        </main>
      </div>
    </div>
  );
}
APPEOF2

git add -A
git commit -m "feat: add responsive header with search and notifications"

# Commit 2: enhance task list with status icons and priorities
cat > src/components/TaskList.tsx << 'TL2EOF'
import { useTasks } from '../hooks/useTasks';

interface Task {
  id: string;
  title: string;
  status: 'active' | 'completed' | 'blocked';
  priority: 'high' | 'medium' | 'low';
  assignee?: string;
  dueDate?: string;
}

interface TaskListProps {
  filter: string;
}

const STATUS_ICONS: Record<string, string> = {
  active: '🔵',
  completed: '✅',
  blocked: '🔴',
};

const PRIORITY_COLORS: Record<string, string> = {
  high: 'priority-high',
  medium: 'priority-medium',
  low: 'priority-low',
};

export function TaskList({ filter }: TaskListProps) {
  const { tasks, loading } = useTasks(filter);

  if (loading) {
    return (
      <div className="task-list-skeleton">
        {[1, 2, 3].map(i => (
          <div key={i} className="skeleton-row" />
        ))}
      </div>
    );
  }

  if (tasks.length === 0) {
    return (
      <div className="empty-state">
        <p>No tasks found</p>
        <button className="btn-primary">Create your first task</button>
      </div>
    );
  }

  return (
    <div className="task-list">
      <div className="task-list-header">
        <span>Task</span>
        <span>Priority</span>
        <span>Assignee</span>
        <span>Due Date</span>
        <span>Status</span>
      </div>
      {(tasks as Task[]).map(task => (
        <div key={task.id} className="task-row">
          <div className="task-title">
            <span className="status-icon">{STATUS_ICONS[task.status]}</span>
            <span>{task.title}</span>
          </div>
          <span className={`priority-badge ${PRIORITY_COLORS[task.priority]}`}>
            {task.priority}
          </span>
          <span className="assignee">
            {task.assignee ? (
              <span className="avatar-small">{task.assignee.slice(0, 2).toUpperCase()}</span>
            ) : (
              <span className="unassigned">—</span>
            )}
          </span>
          <span className="due-date">{task.dueDate ?? '—'}</span>
          <span className={`status-badge status-${task.status}`}>
            {task.status}
          </span>
        </div>
      ))}
    </div>
  );
}
TL2EOF

git add -A
git commit -m "refactor: enhance task list with status icons and priorities"

# Commit 3: type-safe API client with error handling
cat > src/lib/api.ts << 'API2EOF'
interface ApiError {
  message: string;
  status: number;
}

interface Task {
  id: string;
  title: string;
  status: 'active' | 'completed' | 'blocked';
  priority: 'high' | 'medium' | 'low';
  assignee?: string;
  dueDate?: string;
}

interface CreateTaskInput {
  title: string;
  priority?: Task['priority'];
  assignee?: string;
  dueDate?: string;
}

class ApiClient {
  private baseUrl: string;

  constructor(baseUrl = '/api') {
    this.baseUrl = baseUrl;
  }

  private async request<T>(path: string, options?: RequestInit): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...options?.headers,
      },
    });

    if (!response.ok) {
      const error: ApiError = {
        message: `Request failed: ${response.statusText}`,
        status: response.status,
      };
      throw error;
    }

    return response.json();
  }

  async getTasks(filter?: string): Promise<Task[]> {
    const params = filter && filter !== 'all' ? `?filter=${filter}` : '';
    return this.request<Task[]>(`/tasks${params}`);
  }

  async getTask(id: string): Promise<Task> {
    return this.request<Task>(`/tasks/${id}`);
  }

  async createTask(input: CreateTaskInput): Promise<Task> {
    return this.request<Task>('/tasks', {
      method: 'POST',
      body: JSON.stringify(input),
    });
  }

  async updateTask(id: string, updates: Partial<Task>): Promise<Task> {
    return this.request<Task>(`/tasks/${id}`, {
      method: 'PATCH',
      body: JSON.stringify(updates),
    });
  }

  async deleteTask(id: string): Promise<void> {
    await this.request(`/tasks/${id}`, { method: 'DELETE' });
  }
}

export const api = new ApiClient();
API2EOF

cat > src/hooks/useTasks.ts << 'HT2EOF'
import { useState, useEffect, useCallback } from 'react';
import { api } from '../lib/api';

interface Task {
  id: string;
  title: string;
  status: 'active' | 'completed' | 'blocked';
  priority: 'high' | 'medium' | 'low';
  assignee?: string;
  dueDate?: string;
}

interface UseTasksResult {
  tasks: Task[];
  loading: boolean;
  error: string | null;
  refresh: () => void;
  createTask: (title: string) => Promise<void>;
  deleteTask: (id: string) => Promise<void>;
}

export function useTasks(filter: string): UseTasksResult {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const loadTasks = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const data = await api.getTasks(filter);
      setTasks(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load tasks');
    } finally {
      setLoading(false);
    }
  }, [filter]);

  useEffect(() => {
    loadTasks();
  }, [loadTasks]);

  const createTask = useCallback(async (title: string) => {
    await api.createTask({ title });
    await loadTasks();
  }, [loadTasks]);

  const deleteTask = useCallback(async (id: string) => {
    await api.deleteTask(id);
    await loadTasks();
  }, [loadTasks]);

  return { tasks, loading, error, refresh: loadTasks, createTask, deleteTask };
}
HT2EOF

git add -A
git commit -m "refactor: type-safe API client with error handling"

# Push all branches
git push origin cw/task-manager-redesign-phase-ui-overhaul

# Clean up
cd /
rm -rf "$TEMP_DIR"

echo "=== Demo git repository created at $BARE_REPO ==="

# ─── Step 2: Run Node.js seed ───

echo "=== Running database seed ==="
PROJECT_ID=$(CW_DB_PATH=/workspace/.cw/cw.db node /app/apps/server/dist/preview-seed.js)
echo "=== Seed complete, project ID: $PROJECT_ID ==="

# ─── Step 3: Set up local branches in the server's clone dir ───

CLONE_DIR="/workspace/repos/demo-app-${PROJECT_ID}"
echo "=== Cloning demo repo to $CLONE_DIR ==="

mkdir -p /workspace/repos
git clone "$BARE_REPO" "$CLONE_DIR"

echo "=== Setting up local branches in $CLONE_DIR ==="

cd "$CLONE_DIR"
git checkout -b cw/task-manager-redesign origin/cw/task-manager-redesign
git checkout -b cw/task-manager-redesign-phase-ui-overhaul origin/cw/task-manager-redesign-phase-ui-overhaul
git checkout main

echo "=== Preview seed complete ==="
