import 'dart:developer' as developer;
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:webfeed/webfeed.dart';

import '../local_storage/sqflite_localpodcast.dart';
import '../state/podcast_group.dart';
import '../type/play_histroy.dart';
import '../type/podcastlocal.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
import '../widgets/duraiton_picker.dart';

enum MarkStatus { start, complete, none }
enum RefreshCoverStatus { start, complete, error, none }

class PodcastSetting extends StatefulWidget {
  const PodcastSetting({this.podcastLocal, Key key}) : super(key: key);
  final PodcastLocal podcastLocal;

  @override
  _PodcastSettingState createState() => _PodcastSettingState();
}

class _PodcastSettingState extends State<PodcastSetting> {
  final _dbHelper = DBHelper();
  MarkStatus _markStatus = MarkStatus.none;
  RefreshCoverStatus _coverStatus = RefreshCoverStatus.none;
  int _secondsStart;
  int _secondsEnd;
  bool _markConfirm;
  bool _removeConfirm;
  bool _showStartTimePicker;
  bool _showEndTimePicker;

  @override
  void initState() {
    super.initState();
    _secondsStart = 0;
    _secondsEnd = 0;
    _markConfirm = false;
    _removeConfirm = false;
    _showStartTimePicker = false;
    _showEndTimePicker = false;
  }

  Future<void> _setAutoDownload(bool boo) async {
    var permission = await _checkPermmison();
    if (permission) {
      await _dbHelper.saveAutoDownload(widget.podcastLocal.id, boo: boo);
    }
    if (mounted) setState(() {});
  }

  Future<void> _setNeverUpdate(bool boo) async {
    await _dbHelper.saveNeverUpdate(widget.podcastLocal.id, boo: boo);
    if (mounted) setState(() {});
  }

  Future<void> _saveSkipSecondsStart(int seconds) async {
    await _dbHelper.saveSkipSecondsStart(widget.podcastLocal.id, seconds);
  }

  Future<void> _saveSkipSecondsEnd(int seconds) async {
    await _dbHelper.saveSkipSecondsEnd(widget.podcastLocal.id, seconds);
  }

  Future<bool> _getAutoDownload(String id) async {
    return await _dbHelper.getAutoDownload(id);
  }

  Future<bool> _getNeverUpdate(String id) async {
    return await _dbHelper.getNeverUpdate(id);
  }

  Future<int> _getSkipSecondStart(String id) async {
    return await _dbHelper.getSkipSecondsStart(id);
  }

  Future<int> _getSkipSecondEnd(String id) async {
    return await _dbHelper.getSkipSecondsEnd(id);
  }

  Future<void> _markListened(String podcastId) async {
    setState(() {
      _markStatus = MarkStatus.start;
    });
    final episodes = await _dbHelper.getRssItem(podcastId, -1,
        reverse: true, hideListened: true);
    for (var episode in episodes) {
      final history = PlayHistory(episode.title, episode.enclosureUrl, 0, 1);
      await _dbHelper.saveHistory(history);
    }
    if (mounted) {
      setState(() {
        _markStatus = MarkStatus.complete;
      });
    }
  }

  Future<void> _refreshArtWork() async {
    setState(() => _coverStatus = RefreshCoverStatus.start);
    var options = BaseOptions(
      connectTimeout: 30000,
      receiveTimeout: 90000,
    );
    var dir = await getApplicationDocumentsDirectory();
    var filePath = "${dir.path}/${widget.podcastLocal.id}.png";
    var dio = Dio(options);
    String imageUrl;

    try {
      var response = await dio.get(widget.podcastLocal.rssUrl);
      try {
        var p = RssFeed.parse(response.data);
        imageUrl = p.itunes.image.href ?? p.image.url;
      } catch (e) {
        developer.log(e.toString());
        if (mounted) setState(() => _coverStatus = RefreshCoverStatus.error);
      }
    } catch (e) {
      developer.log(e.toString());
      if (mounted) setState(() => _coverStatus = RefreshCoverStatus.error);
    }
    if (imageUrl != null && imageUrl.contains('http')) {
      try {
        img.Image thumbnail;
        var imageResponse = await dio.get<List<int>>(imageUrl,
            options: Options(
              responseType: ResponseType.bytes,
            ));
        var image = img.decodeImage(imageResponse.data);
        thumbnail = img.copyResize(image, width: 300);
        if (thumbnail != null) {
          File(filePath)..writeAsBytesSync(img.encodePng(thumbnail));
          _dbHelper.updatePodcastImage(
              id: widget.podcastLocal.id, filePath: filePath);
          print('saved image');
          if (mounted) {
            setState(() => _coverStatus = RefreshCoverStatus.complete);
          }
        }
      } catch (e) {
        developer.log(e.toString());
        if (mounted) setState(() => _coverStatus = RefreshCoverStatus.error);
      }
    } else if (_coverStatus == RefreshCoverStatus.start && mounted) {
      setState(() => _coverStatus = RefreshCoverStatus.complete);
    }
  }

  Future<bool> _checkPermmison() async {
    var permission = await Permission.storage.status;
    if (permission != PermissionStatus.granted) {
      var permissions = await [Permission.storage].request();
      if (permissions[Permission.storage] == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }
  }

  Widget _getRefreshStatusIcon(RefreshCoverStatus status) {
    switch (status) {
      case RefreshCoverStatus.none:
        return Center();
        break;
      case RefreshCoverStatus.start:
        return CircularProgressIndicator(strokeWidth: 2);
        break;
      case RefreshCoverStatus.complete:
        return Icon(Icons.done);
        break;
      case RefreshCoverStatus.error:
        return Icon(Icons.refresh, color: Colors.red);
        break;
      default:
        return Center();
    }
  }

  @override
  Widget build(BuildContext context) {
    final s = context.s;
    final groupList = context.watch<GroupList>();
    final textStyle = context.textTheme.bodyText2;
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        FutureBuilder<bool>(
            future: _getAutoDownload(widget.podcastLocal.id),
            initialData: false,
            builder: (context, snapshot) {
              return ListTile(
                onTap: () => _setAutoDownload(!snapshot.data),
                dense: true,
                title: Row(
                  children: [
                    SizedBox(
                      height: 18,
                      width: 18,
                      child: CustomPaint(
                        painter: DownloadPainter(
                          color: context.textColor,
                          fraction: 0,
                          progressColor: context.accentColor,
                        ),
                      ),
                    ),
                    SizedBox(width: 20),
                    Text(s.autoDownload, style: textStyle),
                  ],
                ),
                trailing: Transform.scale(
                  scale: 0.8,
                  child:
                      Switch(value: snapshot.data, onChanged: _setAutoDownload),
                ),
              );
            }),
        FutureBuilder<bool>(
            future: _getNeverUpdate(widget.podcastLocal.id),
            initialData: false,
            builder: (context, snapshot) {
              return ListTile(
                dense: true,
                onTap: () => _setNeverUpdate(!snapshot.data),
                title: Row(
                  children: [
                    Icon(Icons.lock_outlined, size: 18),
                    SizedBox(width: 20),
                    Text(s.neverAutoUpdate, style: textStyle),
                  ],
                ),
                trailing: Transform.scale(
                  scale: 0.8,
                  child:
                      Switch(value: snapshot.data, onChanged: _setNeverUpdate),
                ),
              );
            }),
        FutureBuilder<int>(
          future: _getSkipSecondStart(widget.podcastLocal.id),
          initialData: 0,
          builder: (context, snapshot) => ListTile(
            onTap: () {
              _secondsStart = 0;
              setState(() {
                _removeConfirm = false;
                _markConfirm = false;
                _showEndTimePicker = false;
                _showStartTimePicker = !_showStartTimePicker;
              });
            },
            dense: true,
            title: Row(
              children: [
                Icon(Icons.fast_forward_outlined, size: 18),
                SizedBox(width: 20),
                Text(s.skipSecondsAtStart, style: textStyle),
              ],
            ),
            trailing: Padding(
              padding: const EdgeInsets.only(right: 10.0),
              child: Text(snapshot.data.toTime),
            ),
          ),
        ),
        if (_showStartTimePicker)
          _TimePicker(
              onCancel: () {
                _secondsStart = 0;
                setState(() => _showStartTimePicker = false);
              },
              onConfirm: () async {
                await _saveSkipSecondsStart(_secondsStart);
                if (mounted) setState(() => _showStartTimePicker = false);
              },
              onChange: (value) => _secondsStart = value.inSeconds),
        ListTile(
            onTap: () {
              if (_coverStatus != RefreshCoverStatus.start) {
                _refreshArtWork();
              }
            },
            dense: true,
            title: Row(
              children: [
                Icon(Icons.refresh, size: 18),
                SizedBox(width: 20),
                Text(s.refreshArtwork, style: textStyle),
              ],
            ),
            trailing: Padding(
                padding: const EdgeInsets.only(right: 15.0),
                child: SizedBox(
                    height: 20,
                    width: 20,
                    child: _getRefreshStatusIcon(_coverStatus)))),
        Divider(height: 1),
        ListTile(
            onTap: () {
              setState(() {
                _removeConfirm = false;
                _showStartTimePicker = false;
                _showEndTimePicker = false;
                _markConfirm = !_markConfirm;
              });
            },
            dense: true,
            title: Row(
              children: [
                SizedBox(
                  height: 18,
                  width: 18,
                  child: CustomPaint(
                    painter: ListenedAllPainter(context.accentColor, stroke: 2),
                  ),
                ),
                SizedBox(width: 20),
                Text(s.menuMarkAllListened,
                    style: textStyle.copyWith(
                        color: context.accentColor,
                        fontWeight: FontWeight.bold)),
              ],
            ),
            trailing: Padding(
              padding: const EdgeInsets.only(right: 10.0),
              child: SizedBox(
                  height: 20,
                  width: 20,
                  child: _markStatus == MarkStatus.none
                      ? Center()
                      : _markStatus == MarkStatus.start
                          ? CircularProgressIndicator(strokeWidth: 2)
                          : Icon(Icons.done)),
            )),
        if (_markConfirm)
          Container(
            width: double.infinity,
            color: context.primaryColorDark,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                FlatButton(
                    onPressed: () => setState(() {
                          _markConfirm = false;
                        }),
                    child: Text(
                      s.cancel,
                      style: TextStyle(color: Colors.grey[600]),
                    )),
                FlatButton(
                    onPressed: () {
                      if (_markStatus != MarkStatus.start) {
                        _markListened(widget.podcastLocal.id);
                      }
                      setState(() {
                        _markConfirm = false;
                      });
                    },
                    child: Text(s.confirm,
                        style: TextStyle(color: context.accentColor))),
              ],
            ),
          ),
        ListTile(
          onTap: () {
            setState(() {
              _markConfirm = false;
              _showStartTimePicker = false;
              _showEndTimePicker = false;
              _removeConfirm = !_removeConfirm;
            });
          },
          dense: true,
          title: Row(
            children: [
              Icon(Icons.delete_outlined, color: Colors.red, size: 18),
              SizedBox(width: 20),
              Text(s.remove,
                  style: textStyle.copyWith(
                      color: Colors.red, fontWeight: FontWeight.bold)),
            ],
          ),
        ),
        if (_removeConfirm)
          Container(
            width: double.infinity,
            color: context.primaryColorDark,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                FlatButton(
                  onPressed: () => setState(() {
                    _removeConfirm = false;
                  }),
                  child:
                      Text(s.cancel, style: TextStyle(color: Colors.grey[600])),
                ),
                FlatButton(
                    splashColor: Colors.red.withAlpha(70),
                    onPressed: () async {
                      await groupList.removePodcast(widget.podcastLocal);
                      Navigator.of(context).pop();
                    },
                    child:
                        Text(s.confirm, style: TextStyle(color: Colors.red))),
              ],
            ),
          ),
      ],
    );
  }
}

class _TimePicker extends StatelessWidget {
  const _TimePicker({this.onConfirm, this.onCancel, this.onChange, Key key})
      : super(key: key);
  final VoidCallback onConfirm;
  final VoidCallback onCancel;
  final ValueChanged<Duration> onChange;

  @override
  Widget build(BuildContext context) {
    final s = context.s;
    return Container(
      color: context.primaryColorDark,
      child: Column(
        children: [
          SizedBox(height: 10),
          DurationPicker(
            onChange: onChange,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              FlatButton(
                onPressed: onCancel,
                child: Text(
                  s.cancel,
                  style: TextStyle(color: Colors.grey[600]),
                ),
              ),
              FlatButton(
                splashColor: context.accentColor.withAlpha(70),
                onPressed: onConfirm,
                child: Text(
                  s.confirm,
                  style: TextStyle(color: context.accentColor),
                ),
              )
            ],
          )
        ],
      ),
    );
  }
}
