// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

import '../logic/qualified_task.dart';

import 'task_box.dart';

/// Header icon for all [Task]s that map to the same [Task.stageName]
/// and [Task.name].
///
/// Intended to be used in the first row of [TaskGrid]. Shows an
/// icon based on [qualifiedTask.stage], defaulting to [Icons.help] if
/// it can't be mapped. On tap, shows the task.
class TaskIcon extends StatelessWidget {
  const TaskIcon({
    super.key,
    required this.qualifiedTask,
  });

  /// [Task] to get information from.
  final QualifiedTask qualifiedTask;

  /// A lookup table for matching [stageName] to [Image].
  ///
  /// [stageName] is based on the backend.
  Widget stageIconForBrightness(Brightness brightness) {
    // Pass this as the `color` for Image's that are black and white icons.
    // This only works in the CanvasKit implementation currently, not in DOM. If
    // this needs to run in the DOM implementation, it will need to include
    // different assets.
    final Color? blendFilter = brightness == Brightness.dark ? Colors.white : null;

    if (qualifiedTask.isGoogleTest) {
      return Image.asset(
        'assets/googleLogo.png',
        color: blendFilter,
      );
    }

    if (qualifiedTask.task == null || !(qualifiedTask.isLuci || qualifiedTask.isDartInternal)) {
      return Icon(
        Icons.help,
        color: blendFilter,
      );
    }

    final String matchedName = qualifiedTask.task!.toLowerCase();
    final bool isWebTest = matchedName.contains('_web') || matchedName.contains('web_');
    final bool isToolTest = matchedName.contains('_tool') || matchedName.contains('tool_');

    if (matchedName.contains('_fuchsia')) {
      return Padding(
        padding: const EdgeInsets.all(2.0),
        child: Image.asset(
          'assets/fuchsia.png',
          color: blendFilter,
        ),
      );
    } else if (isWebTest && !isToolTest) {
      return Padding(
        padding: const EdgeInsets.all(2.0),
        child: Image.asset(
          'assets/chromium.png',
          color: blendFilter,
        ),
      );
    } else if (matchedName.contains('_android')) {
      return Icon(
        Icons.android,
        color: blendFilter,
      );
    } else if (matchedName.startsWith('linux')) {
      return Padding(
        padding: const EdgeInsets.all(2.0),
        child: Image.asset(
          'assets/linux.png',
          color: blendFilter,
        ),
      );
    } else if (matchedName.startsWith('mac')) {
      if (matchedName.contains('_ios')) {
        return Icon(
          Icons.phone_iphone,
          color: blendFilter,
        );
      } else {
        return Padding(
          padding: const EdgeInsets.all(2.0),
          child: Image.asset(
            'assets/apple.png',
            color: blendFilter,
          ),
        );
      }
    } else if (matchedName.startsWith('win')) {
      return Image.asset(
        'assets/windows.png',
        color: blendFilter,
      );
    }

    return Icon(
      Icons.help,
      color: blendFilter,
    );
  }

  @override
  Widget build(BuildContext context) {
    final Brightness brightness = Theme.of(context).brightness;
    final Widget icon = stageIconForBrightness(brightness);

    return IconTheme.merge(
      data: IconThemeData(size: TaskBox.of(context) - 5),
      child: InkWell(
        onTap: () {
          launchUrl(Uri.parse(qualifiedTask.sourceConfigurationUrl));
        },
        child: Tooltip(
          message: '${qualifiedTask.task} (${qualifiedTask.stage})',
          child: Align(
            alignment: Alignment.bottomCenter,
            child: icon,
          ),
        ),
      ),
    );
  }
}
