import '../../../../core/errors/failures.dart';
import '../../../../core/errors/result.dart';
import '../../../../core/logging/app_logger.dart';
import '../../domain/entities/task_entity.dart';
import '../../domain/repositories/task_repository.dart';
import '../datasources/task_local_datasource.dart';
import '../models/task_model.dart';

class LocalTaskRepositoryImpl implements TaskRepository {
  final TaskLocalDataSource localDataSource;
  final AppLogger logger;

  LocalTaskRepositoryImpl({
    required this.localDataSource,
    required this.logger,
  });

  String _formatDate(DateTime date) {
    return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
  }

  @override
  Future<Result<List<TaskEntity>>> getTasksByDate(DateTime date, {String? status}) async {
    try {
      final tasks = await localDataSource.getTasksByDate(
        _formatDate(date),
        status: status,
      );
      logger.info('Loaded ${tasks.length} tasks for ${_formatDate(date)} (local)');
      return Success(tasks);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<TaskEntity>> getTaskById(String id) async {
    try {
      final task = await localDataSource.getTaskById(id);
      return Success(task);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      if (e.toString().contains('not found')) {
        return Error(NotFoundFailure(message: 'Task not found'));
      }
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<TaskEntity>> createTask(TaskEntity task) async {
    try {
      final model = TaskModel.fromEntity(task);
      final created = await localDataSource.createTask(model);
      logger.info('Created task: ${created.id} (local)');
      return Success(created);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<TaskEntity>> updateTask(TaskEntity task) async {
    try {
      final model = TaskModel.fromEntity(task);
      final updated = await localDataSource.updateTask(model);
      logger.info('Updated task: ${updated.id} (local)');
      return Success(updated);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      if (e.toString().contains('not found')) {
        return Error(NotFoundFailure(message: 'Task not found'));
      }
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<void>> deleteTask(String id) async {
    try {
      await localDataSource.deleteTask(id);
      logger.info('Deleted task: $id (local)');
      return const Success(null);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<TaskEntity>> toggleTaskStatus(String id) async {
    try {
      final task = await localDataSource.toggleTaskStatus(id);
      logger.info('Toggled task status: $id -> ${task.isDone} (local)');
      return Success(task);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      if (e.toString().contains('not found')) {
        return Error(NotFoundFailure(message: 'Task not found'));
      }
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }

  @override
  Future<Result<TaskEntity>> rescheduleTask(String id, DateTime targetDate) async {
    try {
      final task = await localDataSource.rescheduleTask(id, _formatDate(targetDate));
      logger.info('Rescheduled task: $id -> ${_formatDate(targetDate)} (local)');
      return Success(task);
    } catch (e, stackTrace) {
      logger.error('Local storage error', e, stackTrace);
      if (e.toString().contains('not found')) {
        return Error(NotFoundFailure(message: 'Task not found'));
      }
      return Error(UnexpectedFailure(message: e.toString()));
    }
  }
}
