// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. 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:code_builder/code_builder.dart';

import '../formatting.dart';
import '../interop_gen/namer.dart';
import 'base.dart';
import 'builtin.dart';
import 'declarations.dart';
import 'documentation.dart';
import 'types.dart';

Type getJSTypeAlternative(Type type) {
  if (type is BuiltinType) {
    if (type.fromDartJSInterop) return type;

    final primitiveType = switch (type.name) {
      'num' => PrimitiveType.num,
      'int' => PrimitiveType.int,
      'double' => PrimitiveType.double,
      'String' => PrimitiveType.string,
      'bool' => PrimitiveType.boolean,
      _ => null
    };

    if (primitiveType == null) return BuiltinType.anyType;

    return BuiltinType.primitiveType(primitiveType, shouldEmitJsType: true);
  } else if (type is ReferredType) {
    switch (type.declaration) {
      case TypeAliasDeclaration(type: final t):
      case EnumDeclaration(baseType: final t):
        final jsTypeT = getJSTypeAlternative(t);
        return jsTypeT == t ? type : jsTypeT;
      default:
        return type;
    }
  }
  return type;
}

Expression generateJSAnnotation([String? name]) {
  return refer('JS', 'dart:js_interop')
      .call([if (name != null) literalString(name)]);
}

List<Parameter> spreadParam(ParameterDeclaration p, int count) {
  return List.generate(count - 1, (i) {
    final paramNumber = i + 2;
    final paramName = '${p.name}$paramNumber';
    return ParameterDeclaration(name: paramName, type: p.type).emit();
  });
}

final Map<String, Set<String>> _memberHierarchyCache = {};

Set<String> getMemberHierarchy(TypeDeclaration type,
    [bool addDirectMembers = false]) {
  final members = <String>{};

  void addMembersIfReferredType(Type type) {
    if (type case ReferredType<Declaration>(declaration: final d)
        when d is TypeDeclaration) {
      members.addAll(getMemberHierarchy(d, true));
    }
  }

  if (addDirectMembers) {
    if (_memberHierarchyCache.containsKey(type.name)) {
      return _memberHierarchyCache[type.name]!;
    }
    // add direct members
    members.addAll(type.methods.map((m) => m.name));
    members.addAll(type.properties.map((m) => m.name));
    members.addAll(type.operators.map((m) => m.name));
  }

  switch (type) {
    case ClassDeclaration(
        extendedType: final extendee,
        implementedTypes: final implementees
      ):
      if (extendee case final extendedType?) {
        addMembersIfReferredType(extendedType);
      }
      implementees.forEach(addMembersIfReferredType);
      break;
    case InterfaceDeclaration(extendedTypes: final extendees):
      extendees.forEach(addMembersIfReferredType);
      break;
  }

  if (addDirectMembers) {
    _memberHierarchyCache[type.name] ??= members;
  }

  return members;
}

Type getRepresentationType(TypeDeclaration td) {
  if (td case ClassDeclaration(extendedType: final extendee?)) {
    return switch (extendee) {
      ReferredType(declaration: final d) when d is TypeDeclaration =>
        getRepresentationType(d),
      final BuiltinType b => b,
      _ => BuiltinType.primitiveType(PrimitiveType.object, isNullable: false)
    };
  } else if (td case InterfaceDeclaration(extendedTypes: [final extendee])) {
    return switch (extendee) {
      ReferredType(declaration: final d) when d is TypeDeclaration =>
        getRepresentationType(d),
      final BuiltinType b => b,
      _ => BuiltinType.primitiveType(PrimitiveType.object, isNullable: false)
    };
  } else {
    final primitiveType = switch (td.name) {
      'Array' => PrimitiveType.array,
      _ => PrimitiveType.object
    };

    return BuiltinType.primitiveType(primitiveType, isNullable: false);
  }
}

(List<String>, List<Expression>) generateFromDocumentation(
    Documentation? docs) {
  if (docs == null) return ([], []);

  if (docs.docs.trim().isEmpty) {
    return ([], docs.annotations.map((d) => d.emit()).toList());
  }
  return (
    // setting it at 80 may not work depending on how long the sentence is
    formatDocs(docs.docs.trim(), 78),
    docs.annotations.map((d) => d.emit()).toList()
  );
}

(List<Parameter>, List<Parameter>) emitParameters(
    List<ParameterDeclaration> parameters,
    [DeclarationOptions? options]) {
  final requiredParams = <Parameter>[];
  final optionalParams = <Parameter>[];
  for (final p in parameters) {
    if (p.variadic) {
      optionalParams.addAll(spreadParam(p, GlobalOptions.variadicArgsCount));
      requiredParams.add(p.emit(options));
    } else {
      if (p.optional) {
        optionalParams.add(p.emit(options));
      } else {
        requiredParams.add(p.emit(options));
      }
    }
  }

  return (requiredParams, optionalParams);
}

/// Recursively get the generic types specified in a given type [t]
Set<GenericType> getGenericTypes(Type t) {
  final types = <(String, Type?)>{};
  switch (t) {
    case GenericType():
      types.add((t.name, t.constraint));
      break;
    case ReferredType(typeParams: final referredTypeParams):
    case UnionType(types: final referredTypeParams):
      for (final referredTypeParam in referredTypeParams) {
        types.addAll(getGenericTypes(referredTypeParam)
            .map((t) => (t.name, t.constraint)));
      }
      break;
    case ObjectLiteralType(
        properties: final objectProps,
        methods: final objectMethods,
        constructors: final objectConstructors,
        operators: final objectOperators
      ):
      for (final PropertyDeclaration(type: propType) in objectProps) {
        types.addAll(
            getGenericTypes(propType).map((t) => (t.name, t.constraint)));
      }

      for (final MethodDeclaration(
            typeParameters: alreadyEstablishedTypeParams,
            returnType: methodType,
            parameters: methodParams
          ) in objectMethods) {
        final typeParams = [methodType, ...methodParams.map((p) => p.type)];

        for (final type in typeParams) {
          final genericTypes = getGenericTypes(type);
          for (final genericType in genericTypes) {
            if (!alreadyEstablishedTypeParams
                .any((al) => al.name == genericType.name)) {
              types.add((genericType.name, genericType.constraint));
            }
          }
        }
      }

      for (final ConstructorDeclaration(parameters: methodParams)
          in objectConstructors) {
        for (final ParameterDeclaration(type: methodParamType)
            in methodParams) {
          types.addAll(getGenericTypes(methodParamType)
              .map((t) => (t.name, t.constraint)));
        }
      }

      for (final OperatorDeclaration(
            typeParameters: alreadyEstablishedTypeParams,
            returnType: methodType,
            parameters: methodParams
          ) in objectOperators) {
        final typeParams = [methodType, ...methodParams.map((p) => p.type)];

        for (final type in typeParams) {
          final genericTypes = getGenericTypes(type);
          for (final genericType in genericTypes) {
            if (!alreadyEstablishedTypeParams
                .any((al) => al.name == genericType.name)) {
              types.add((genericType.name, genericType.constraint));
            }
          }
        }
      }
      break;
    case ClosureType(
        typeParameters: final alreadyEstablishedTypeParams,
        returnType: final closureType,
        parameters: final closureParams
      ):
      for (final type in [closureType, ...closureParams.map((p) => p.type)]) {
        final genericTypes = getGenericTypes(type);
        for (final genericType in genericTypes) {
          if (!alreadyEstablishedTypeParams
              .any((al) => al.name == genericType.name)) {
            types.add((genericType.name, genericType.constraint));
          }
        }
      }
      break;
    default:
      break;
  }

  // Types are cloned so that modifications to constraints can happen without
  // affecting initial references
  return types.map((t) => GenericType(name: t.$1, constraint: t.$2)).toSet();
}

Type desugarTypeAliases(Type t) {
  if (t case final ReferredType ref
      when ref.declaration is TypeAliasDeclaration) {
    return desugarTypeAliases((ref.declaration as TypeAliasDeclaration).type);
  }
  return t;
}

class TupleDeclaration extends NamedDeclaration
    implements ExportableDeclaration {
  @override
  bool get exported => true;

  @override
  ID get id => ID(type: 'tuple', name: name);

  final int count;

  final bool readonly;

  TupleDeclaration({required this.count, this.readonly = false});

  @override
  String? dartName;

  @override
  String get name => readonly ? 'JSReadonlyTuple$count' : 'JSTuple$count';

  @override
  set name(String name) {
    throw Exception('Forbidden: Cannot set name on tuple declaration');
  }

  /// Creates a tuple from types.
  ///
  /// The type args represent the tuple types for the tuple declaration
  @override
  TupleType asReferredType(
      [List<Type>? typeArgs, bool isNullable = false, String? url]) {
    assert(typeArgs?.length == count,
        'Type arguments must equal the number of tuples supported');
    return TupleType(types: typeArgs ?? [], tupleDeclUrl: url);
  }

  @override
  Spec emit([covariant DeclarationOptions? options]) {
    options ??= DeclarationOptions();

    final repType = BuiltinType.primitiveType(PrimitiveType.array,
        shouldEmitJsType: true, typeParams: [BuiltinType.anyType]);

    return ExtensionType((e) => e
      ..name = name
      ..primaryConstructorName = '_'
      ..representationDeclaration = RepresentationDeclaration((r) => r
        ..name = '_'
        ..declaredRepresentationType = repType.emit())
      ..implements.addAll([if (repType != BuiltinType.anyType) repType.emit()])
      ..types.addAll(List.generate(
          count,
          (index) => TypeReference((t) => t
            ..symbol = String.fromCharCode(65 + index)
            ..bound = BuiltinType.anyType.emit())))
      ..methods.addAll([
        ...List.generate(count, (index) {
          final returnType = String.fromCharCode(65 + index);
          return Method((m) => m
            ..name = '\$${index + 1}'
            ..returns = refer(returnType)
            ..type = MethodType.getter
            ..body = refer('_')
                .index(literalNum(index))
                .asA(refer(returnType))
                .code);
        }),
        if (!readonly)
          ...List.generate(count, (index) {
            final returnType = String.fromCharCode(65 + index);
            return Method((m) => m
              ..name = '\$${index + 1}'
              ..type = MethodType.setter
              ..requiredParameters.add(Parameter((p) => p
                ..name = 'newValue'
                ..type = refer(returnType)))
              ..body = refer('_')
                  .index(literalNum(index))
                  .assign(refer('newValue'))
                  .code);
          })
      ]));
  }
}
