import 'dart:convert';

import 'package:scheduler_core/scheduler_core.dart' as core;
import 'package:scheduler_export/export.dart';
import 'package:scheduler_persistence_memory/persistence_memory.dart';
import 'package:test/test.dart';

void main() {
  test('JSON writer exports owner-scoped tasks through controller', () async {
    final ownerId = core.OwnerId('owner-a');
    final repository = InMemoryTaskRepository();
    await repository.insert(ownerId: ownerId, task: _task('task-b'));
    await repository.insert(ownerId: ownerId, task: _task('task-a'));
    await repository.insert(
      ownerId: core.OwnerId('owner-b'),
      task: _task('task-hidden'),
    );
    final output = StringBuffer();

    await ExportController(taskRepository: repository).exportTasksToSink(
      context: ExportContext(
        ownerId: ownerId,
        timezone: 'America/Los_Angeles',
        version: 1,
      ),
      format: 'json',
      sink: output,
      pageSize: 1,
    );

    final decoded = jsonDecode(output.toString()) as Map<String, Object?>;
    final context = decoded['context'] as Map<String, Object?>;
    final tasks = decoded['tasks'] as List<Object?>;

    expect(context['ownerId'], 'owner-a');
    expect(context['timezone'], 'America/Los_Angeles');
    expect(tasks.map((task) => (task as Map<String, Object?>)['_id']),
        ['task-a', 'task-b']);
  });

  test('CSV writer exports task rows', () async {
    final ownerId = core.OwnerId('owner-a');
    final repository = InMemoryTaskRepository();
    await repository.insert(ownerId: ownerId, task: _task('task-a'));
    final output = StringBuffer();

    await ExportController(taskRepository: repository).exportTasksToSink(
      context: ExportContext(
        ownerId: ownerId,
        timezone: 'UTC',
        version: 1,
      ),
      format: 'csv',
      sink: output,
    );

    final lines = output.toString().trim().split('\n');
    expect(lines.first, startsWith('id,title,projectId,type,status'));
    expect(lines.singleWhere((line) => line.startsWith('task-a,')),
        contains('Task task-a'));
  });

  test('writer registry supports custom writer factories', () async {
    final registry = ExportWriterRegistry();
    registry.register('custom', _CountingWriter.new);
    final writer = registry.create(' CUSTOM ', StringBuffer());

    expect(writer, isA<_CountingWriter>());
  });
}

core.Task _task(String id) {
  return core.Task(
    id: id,
    title: 'Task $id',
    projectId: 'project-a',
    type: core.TaskType.flexible,
    status: core.TaskStatus.backlog,
    durationMinutes: 30,
    createdAt: DateTime.utc(2026, 1),
    updatedAt: DateTime.utc(2026, 1),
  );
}

final class _CountingWriter implements ExportWriter {
  _CountingWriter(StringSink sink);

  var count = 0;

  @override
  Future<void> begin(ExportContext context) async {}

  @override
  Future<void> writeTask(core.Task task) async {
    count += 1;
  }

  @override
  Future<void> end() async {}
}
