// ignore_for_file: deprecated_member_use_from_same_package

import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:audioplayers/audioplayers.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hoshan/core/gen/assets.gen.dart';
import 'package:hoshan/core/services/api/dio_service.dart';
import 'package:hoshan/core/utils/date_time.dart';
import 'package:hoshan/ui/theme/colors.dart';
import 'package:hoshan/ui/theme/text.dart';
import 'package:hoshan/ui/widgets/components/button/circle_icon_btn.dart';
import 'package:string_validator/string_validator.dart';

class Player extends StatefulWidget {
  final String fileUrl;
  final Function()? onDelete;
  final bool inMessages;
  const Player(
      {super.key,
      required this.fileUrl,
      this.onDelete,
      this.inMessages = false});

  @override
  State<Player> createState() => _PlayerState();
}

enum DownloadAudioState { onDownloading, downloaded, initial }

class _PlayerState extends State<Player> {
  final AudioPlayer audioPlayer = AudioPlayer();
  bool isPlaying = false;
  bool isPaused = false;
  Duration duration = Duration.zero;
  DownloadAudioState downloadState = DownloadAudioState.initial;
  StreamSubscription? durationSubscription;
  StreamSubscription? positionSubscription;
  StreamSubscription? playerStateChangeSubscription;
  String? _audioFilePath;

  @override
  void initState() {
    super.initState();
    try {
      setAudio();
    } catch (e) {
      if (kDebugMode) {
        print("Audio Error is: $e");
      }
    }

    playerStateChangeSubscription = audioPlayer.onPlayerStateChanged.listen(
      (state) {
        if (kDebugMode) {
          print("Player state changed: $state");
        }
        setState(() {
          isPlaying = state == PlayerState.playing;
          isPaused = state == PlayerState.paused;
        });
      },
    );

    durationSubscription = audioPlayer.onDurationChanged.listen(
      (newDuration) {
        if (kDebugMode) {
          print("Duration changed: $newDuration");
        }
        setState(() {
          duration = newDuration;
        });
      },
    );

    audioPlayer.onPlayerComplete.listen((event) {
      if (kDebugMode) {
        print("Player completed");
      }
    });

    audioPlayer.onLog.listen((msg) {
      if (kDebugMode) {
        print("AudioPlayer log: $msg");
      }
    });
  }

  Future setAudio() async {
    try {
      audioPlayer.setReleaseMode(ReleaseMode.stop);

      if (widget.fileUrl.isNotEmpty) {
        XFile? file;
        if (widget.fileUrl.isURL()) {
          setState(() {
            downloadState = DownloadAudioState.onDownloading;
          });
          file = await DioService.downloadFile(
            widget.fileUrl,
          );
        } else {
          file = XFile(widget.fileUrl);
        }
        if (file != null) {
          final fileExists = await File(file.path).exists();
          if (!fileExists) {
            if (kDebugMode) {
              print("Audio file does not exist: ${file.path}");
            }
            setState(() {
              downloadState = DownloadAudioState.initial;
            });
            return;
          }

          await Future.delayed(const Duration(milliseconds: 100));

          _audioFilePath = file.path;
          if (kDebugMode) {
            print("Setting audio source: ${file.path}");
            final fileSize = await File(file.path).length();
            print("File size: $fileSize bytes");
          }
          try {
            await audioPlayer.setSource(DeviceFileSource(file.path));
            setState(() {
              downloadState = DownloadAudioState.downloaded;
            });
            if (kDebugMode) {
              print("Audio source set successfully");
            }
          } catch (error) {
            if (kDebugMode) {
              print("Error setting audio source: $error");
            }
            setState(() {
              downloadState = DownloadAudioState.initial;
            });
          }
        } else {
          setState(() {
            downloadState = DownloadAudioState.initial;
          });
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print("Error in setAudio: $e");
      }
    }
  }

  @override
  void dispose() {
    playerStateChangeSubscription?.cancel();
    durationSubscription?.cancel();
    positionSubscription?.cancel();
    audioPlayer.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      child: Row(
        children: [
          if (widget.onDelete != null)
            Padding(
              padding: const EdgeInsets.only(right: 8),
              child: SizedBox(
                width: 24,
                height: 24,
                child: GestureDetector(
                  onTap: widget.onDelete,
                  child: Assets.icon.outline.trash.svg(),
                ),
              ),
            ),
          widget.inMessages
              ? downloadState == DownloadAudioState.initial
                  ? CircleIconBtn(
                      icon: Assets.icon.outline.download,
                      size: 32,
                      iconPadding: const EdgeInsets.all(6),
                      iconColor: AppColors.secondryColor.defaultShade,
                      onTap: () async {
                        await setAudio();
                      },
                    )
                  : downloadState == DownloadAudioState.onDownloading
                      ? Stack(
                          children: [
                            Transform.rotate(
                              angle: pi / 4,
                              child: CircleIconBtn(
                                icon: Assets.icon.outline.add,
                                size: 32,
                                iconPadding: const EdgeInsets.all(6),
                                iconColor: AppColors.secondryColor.defaultShade,
                                onTap: () async {},
                              ),
                            ),
                            Positioned.fill(child: Builder(builder: (context) {
                              return const CircularProgressIndicator();
                            }))
                          ],
                        )
                      : CircleIconBtn(
                          icon: isPlaying
                              ? Assets.icon.outline.pause
                              : Assets.icon.outline.play,
                          size: 32,
                          iconPadding: const EdgeInsets.all(6),
                          iconColor: AppColors.secondryColor.defaultShade,
                          onTap: () async {
                            try {
                              if (isPlaying) {
                                await audioPlayer.pause();
                              } else if (isPaused) {
                                await audioPlayer.resume();
                              } else {
                                if (_audioFilePath != null) {
                                  await audioPlayer
                                      .play(DeviceFileSource(_audioFilePath!));
                                }
                              }
                            } catch (e) {
                              if (kDebugMode) {
                                print("Error playing audio: $e");
                              }
                            }
                          },
                        )
              : SizedBox(
                  width: 28,
                  height: 28,
                  child: GestureDetector(
                    onTap: () async {
                      try {
                        if (isPlaying) {
                          await audioPlayer.pause();
                        } else if (isPaused) {
                          await audioPlayer.resume();
                        } else {
                          if (_audioFilePath != null) {
                            await audioPlayer
                                .play(DeviceFileSource(_audioFilePath!));
                          }
                        }
                      } catch (e) {
                        if (kDebugMode) {
                          print("Error playing audio: $e");
                        }
                      }
                    },
                    child: (isPlaying
                            ? Assets.icon.bold.pause
                            : Assets.icon.bold.play)
                        .svg(color: AppColors.primaryColor.defaultShade),
                  ),
                ),
          Expanded(
              child: StreamBuilder<Duration>(
                  stream: audioPlayer.onPositionChanged,
                  builder: (context, snapshot) {
                    Duration position = Duration.zero;
                    if (snapshot.hasData && snapshot.data != null) {
                      position = snapshot.data!;
                    }
                    return Row(
                      children: [
                        Expanded(
                          child: Directionality(
                            textDirection: TextDirection.ltr,
                            child: Slider(
                              activeColor: widget.inMessages
                                  ? AppColors.secondryColor[200]
                                  : null,
                              inactiveColor: AppColors.secondryColor[50],
                              thumbColor: widget.inMessages
                                  ? AppColors.secondryColor.defaultShade
                                  : null,
                              min: 0,
                              max: position < duration
                                  ? duration.inMilliseconds.toDouble()
                                  : 100,
                              value: position < duration
                                  ? position.inMilliseconds.toDouble()
                                  : 10,
                              onChanged: (value) async {
                                if (downloadState !=
                                    DownloadAudioState.downloaded) {
                                  return;
                                }
                                final position =
                                    Duration(milliseconds: value.toInt());
                                await audioPlayer.seek(position);
                                // await audioPlayer.resume();
                              },
                            ),
                          ),
                        ),
                        Text(
                          DateTimeUtils.getTimeFromDuration(
                            (isPlaying || isPaused ? position : duration)
                                .inSeconds,
                          ),
                          style: AppTextStyles.body4.copyWith(
                              color: widget.inMessages
                                  ? Colors.white
                                  : Theme.of(context).colorScheme.onSurface),
                        ),
                      ],
                    );
                  })),
        ],
      ),
    );
  }
}
