import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:immich_mobile/domain/models/exif.model.dart';
import 'package:immich_mobile/extensions/platform_extensions.dart';
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';

@RoutePage()
class AssetTroubleshootPage extends ConsumerWidget {
  final BaseAsset asset;

  const AssetTroubleshootPage({super.key, required this.asset});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: Text('asset_troubleshoot'.tr())),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: _AssetDetailsView(asset: asset),
        ),
      ),
    );
  }
}

class _AssetDetailsView extends ConsumerWidget {
  final BaseAsset asset;

  const _AssetDetailsView({required this.asset});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _AssetPropertiesSection(asset: asset),
        const SizedBox(height: 16),
        Text(
          'matching_assets'.tr(),
          style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
        ),
        if (asset.checksum != null) ...[
          _LocalAssetsSection(asset: asset),
          const SizedBox(height: 16),
          _RemoteAssetSection(asset: asset),
        ] else ...[
          _PropertySectionCard(
            title: 'Local Assets',
            properties: [_PropertyItem(label: 'Status', value: 'no_checksum_local'.tr())],
          ),
          const SizedBox(height: 16),
          _PropertySectionCard(
            title: 'Remote Assets',
            properties: [_PropertyItem(label: 'Status', value: 'no_checksum_remote'.tr())],
          ),
        ],
      ],
    );
  }
}

class _AssetPropertiesSection extends ConsumerStatefulWidget {
  final BaseAsset asset;

  const _AssetPropertiesSection({required this.asset});

  @override
  ConsumerState createState() => _AssetPropertiesSectionState();
}

class _AssetPropertiesSectionState extends ConsumerState<_AssetPropertiesSection> {
  List<_PropertyItem> properties = [];

  @override
  void initState() {
    super.initState();
    _buildAssetProperties(widget.asset).whenComplete(() {
      if (mounted) {
        setState(() {});
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final title = _getAssetTypeTitle(widget.asset);

    return _PropertySectionCard(title: title, properties: properties);
  }

  Future<void> _buildAssetProperties(BaseAsset asset) async {
    _addCommonProperties();

    if (asset is LocalAsset) {
      await _addLocalAssetProperties(asset);
    } else if (asset is RemoteAsset) {
      await _addRemoteAssetProperties(asset);
    }
  }

  void _addCommonProperties() {
    final asset = widget.asset;
    properties.addAll([
      _PropertyItem(label: 'Name', value: asset.name),
      _PropertyItem(label: 'Checksum', value: asset.checksum),
      _PropertyItem(label: 'Type', value: asset.type.toString()),
      _PropertyItem(label: 'Created At', value: asset.createdAt.toString()),
      _PropertyItem(label: 'Updated At', value: asset.updatedAt.toString()),
      _PropertyItem(label: 'Width', value: asset.width?.toString()),
      _PropertyItem(label: 'Height', value: asset.height?.toString()),
      _PropertyItem(
        label: 'Duration',
        value: asset.durationInSeconds != null ? '${asset.durationInSeconds} seconds' : null,
      ),
      _PropertyItem(label: 'Is Favorite', value: asset.isFavorite.toString()),
      _PropertyItem(label: 'Live Photo Video ID', value: asset.livePhotoVideoId),
    ]);
  }

  Future<void> _addLocalAssetProperties(LocalAsset asset) async {
    properties.insertAll(0, [
      _PropertyItem(label: 'Local ID', value: asset.id),
      _PropertyItem(label: 'Remote ID', value: asset.remoteId),
    ]);

    properties.insert(4, _PropertyItem(label: 'Orientation', value: asset.orientation.toString()));
    final albums = await ref.read(assetServiceProvider).getSourceAlbums(asset.id);
    properties.add(_PropertyItem(label: 'Album', value: albums.map((a) => a.name).join(', ')));
    if (CurrentPlatform.isIOS) {
      properties.add(_PropertyItem(label: 'Adjustment Time', value: asset.adjustmentTime?.toString()));
    }
    properties.add(
      _PropertyItem(
        label: 'GPS Coordinates',
        value: asset.hasCoordinates ? '${asset.latitude}, ${asset.longitude}' : null,
      ),
    );
  }

  Future<void> _addRemoteAssetProperties(RemoteAsset asset) async {
    properties.insertAll(0, [
      _PropertyItem(label: 'Remote ID', value: asset.id),
      _PropertyItem(label: 'Local ID', value: asset.localId),
      _PropertyItem(label: 'Owner ID', value: asset.ownerId),
    ]);

    final additionalProps = <_PropertyItem>[
      _PropertyItem(label: 'Thumb Hash', value: asset.thumbHash),
      _PropertyItem(label: 'Visibility', value: asset.visibility.toString()),
      _PropertyItem(label: 'Stack ID', value: asset.stackId),
    ];

    properties.insertAll(4, additionalProps);

    final exif = await ref.read(assetServiceProvider).getExif(asset);
    if (exif != null) {
      _addExifProperties(exif);
    } else {
      properties.add(const _PropertyItem(label: 'EXIF', value: null));
    }
  }

  void _addExifProperties(ExifInfo exif) {
    properties.addAll([
      _PropertyItem(
        label: 'File Size',
        value: exif.fileSize != null ? '${(exif.fileSize! / 1024 / 1024).toStringAsFixed(2)} MB' : null,
      ),
      _PropertyItem(label: 'Description', value: exif.description),
      _PropertyItem(label: 'Date Taken', value: exif.dateTimeOriginal?.toString()),
      _PropertyItem(label: 'Time Zone', value: exif.timeZone),
      _PropertyItem(label: 'Camera Make', value: exif.make),
      _PropertyItem(label: 'Camera Model', value: exif.model),
      _PropertyItem(label: 'Lens', value: exif.lens),
      _PropertyItem(label: 'F-Number', value: exif.f != null ? 'f/${exif.fNumber}' : null),
      _PropertyItem(label: 'Focal Length', value: exif.mm != null ? '${exif.focalLength}mm' : null),
      _PropertyItem(label: 'ISO', value: exif.iso?.toString()),
      _PropertyItem(label: 'Exposure Time', value: exif.exposureTime.isNotEmpty ? exif.exposureTime : null),
      _PropertyItem(
        label: 'GPS Coordinates',
        value: exif.hasCoordinates ? '${exif.latitude}, ${exif.longitude}' : null,
      ),
      _PropertyItem(
        label: 'Location',
        value: [exif.city, exif.state, exif.country].where((e) => e != null && e.isNotEmpty).join(', '),
      ),
    ]);
  }

  String _getAssetTypeTitle(BaseAsset asset) {
    if (asset is LocalAsset) return 'Local Asset';
    if (asset is RemoteAsset) return 'Remote Asset';
    return 'Base Asset';
  }
}

class _LocalAssetsSection extends ConsumerWidget {
  final BaseAsset asset;

  const _LocalAssetsSection({required this.asset});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final assetService = ref.watch(assetServiceProvider);

    return FutureBuilder<List<LocalAsset?>>(
      future: assetService.getLocalAssetsByChecksum(asset.checksum!),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const _PropertySectionCard(
            title: 'Local Assets',
            properties: [_PropertyItem(label: 'Status', value: 'Loading...')],
          );
        }

        if (snapshot.hasError) {
          return _PropertySectionCard(
            title: 'Local Assets',
            properties: [_PropertyItem(label: 'Error', value: snapshot.error.toString())],
          );
        }

        final localAssets = snapshot.data?.cast<LocalAsset>() ?? [];
        if (asset is LocalAsset) {
          localAssets.removeWhere((a) => a.id == (asset as LocalAsset).id);

          if (localAssets.isEmpty) {
            return const SizedBox.shrink();
          }
        }

        if (localAssets.isEmpty) {
          return _PropertySectionCard(
            title: 'Local Assets',
            properties: [_PropertyItem(label: 'Status', value: 'no_local_assets_found'.tr())],
          );
        }

        return Column(
          children: [
            if (localAssets.length > 1)
              _PropertySectionCard(
                title: 'Local Assets Summary',
                properties: [_PropertyItem(label: 'Total Count', value: localAssets.length.toString())],
              ),
            ...localAssets.map((localAsset) {
              return Padding(
                padding: const EdgeInsets.only(top: 16),
                child: _AssetPropertiesSection(asset: localAsset),
              );
            }),
          ],
        );
      },
    );
  }
}

class _RemoteAssetSection extends ConsumerWidget {
  final BaseAsset asset;

  const _RemoteAssetSection({required this.asset});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final assetService = ref.watch(assetServiceProvider);

    if (asset is RemoteAsset) {
      return const SizedBox.shrink();
    }

    return FutureBuilder<RemoteAsset?>(
      future: assetService.getRemoteAssetByChecksum(asset.checksum!),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const _PropertySectionCard(
            title: 'Remote Assets',
            properties: [_PropertyItem(label: 'Status', value: 'Loading...')],
          );
        }

        if (snapshot.hasError) {
          return _PropertySectionCard(
            title: 'Remote Assets',
            properties: [_PropertyItem(label: 'Error', value: snapshot.error.toString())],
          );
        }

        final remoteAsset = snapshot.data;

        if (remoteAsset == null) {
          return _PropertySectionCard(
            title: 'Remote Assets',
            properties: [_PropertyItem(label: 'Status', value: 'no_remote_assets_found'.tr())],
          );
        }

        return _AssetPropertiesSection(asset: remoteAsset);
      },
    );
  }
}

class _PropertySectionCard extends StatelessWidget {
  final String title;
  final List<_PropertyItem> properties;

  const _PropertySectionCard({required this.title, required this.properties});

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 8),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(title, style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold)),
            const SizedBox(height: 8),
            ...properties,
          ],
        ),
      ),
    );
  }
}

class _PropertyItem extends StatelessWidget {
  final String label;
  final String? value;

  const _PropertyItem({required this.label, this.value});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 120,
            child: Text('$label:', style: const TextStyle(fontWeight: FontWeight.w500)),
          ),
          Expanded(
            child: Text(
              value ?? 'not_available'.tr(),
              style: TextStyle(color: Theme.of(context).colorScheme.secondary),
            ),
          ),
        ],
      ),
    );
  }
}
