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

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

import '../local_storage/sqflite_localpodcast.dart';
import '../type/play_histroy.dart';
import '../type/podcastlocal.dart';
import '../util/custom_widget.dart';
import '../util/duraiton_picker.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.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> {
  MarkStatus _markStatus = MarkStatus.none;
  RefreshCoverStatus _coverStatus = RefreshCoverStatus.none;
  int _seconds = 0;

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

  Future<void> _saveSkipSeconds(int seconds) async {
    var dbHelper = DBHelper();
    await dbHelper.saveSkipSeconds(widget.podcastLocal.id, seconds);
  }

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

  void _confirmMarkListened(BuildContext context) => generalDialog(
        context,
        title: Text(context.s.markConfirm),
        content: Text(context.s.markConfirmContent),
        actions: <Widget>[
          FlatButton(
            onPressed: () {
              Navigator.of(context).pop();
            },
            child: Text(
              context.s.cancel,
              style: TextStyle(color: Colors.grey[600]),
            ),
          ),
          FlatButton(
            onPressed: () async {
              Navigator.of(context).pop();
              await _markListened(widget.podcastLocal.id);
            },
            child: Text(
              context.s.confirm,
              style: TextStyle(color: context.accentColor),
            ),
          )
        ],
      );

  Future<void> _refreshArtWork() async {
    setState(() => _coverStatus = RefreshCoverStatus.start);
    var options = BaseOptions(
      connectTimeout: 20000,
      receiveTimeout: 20000,
    );
    String imageUrl;

    try {
      var response = await Dio(options).get(widget.podcastLocal.rssUrl);
      try {
        RssFeed p;
        p = RssFeed.parse(response.data);
        imageUrl == p.itunes.image.href;
      } 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') &&
        (imageUrl != widget.podcastLocal.imageUrl ||
            !File(widget.podcastLocal.imageUrl).existsSync())) {
      try {
        img.Image thumbnail;
        var imageResponse = await Dio().get<List<int>>(imageUrl,
            options: Options(
              responseType: ResponseType.bytes,
              receiveTimeout: 90000,
            ));
        var image = img.decodeImage(imageResponse.data);
        thumbnail = img.copyResize(image, width: 300);
        if (thumbnail != null) {
          var dir = await getApplicationDocumentsDirectory();
          File("${dir.path}/${widget.podcastLocal.id}.png")
            ..writeAsBytesSync(img.encodePng(thumbnail));
          if (mounted) {
            setState(() => _coverStatus = RefreshCoverStatus.complete);
          }
        }
      } catch (e) {
        if (mounted) setState(() => _coverStatus = RefreshCoverStatus.error);
      }
    }
    if (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;
    }
  }

  Future<bool> _getAutoDownload(String id) async {
    var dbHelper = DBHelper();
    return await dbHelper.getAutoDownload(id);
  }

  Future<int> _getSkipSecond(String id) async {
    var dbHelper = DBHelper();
    var seconds = await dbHelper.getSkipSeconds(id);
    return seconds;
  }

  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.complete:
        return Icon(Icons.refresh, color: Colors.red);
        break;
      default:
        return Center();
    }
  }

  @override
  Widget build(BuildContext context) {
    final s = context.s;
    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),
                  leading: SizedBox(
                    height: 18,
                    width: 18,
                    child: CustomPaint(
                      painter: DownloadPainter(
                        color: context.brightness == Brightness.light
                            ? Colors.grey[600]
                            : Colors.white,
                        fraction: 0,
                        progressColor: context.accentColor,
                      ),
                    ),
                  ),
                  title: Text(s.autoDownload),
                  trailing: Transform.scale(
                    scale: 0.9,
                    child: Switch(
                        value: snapshot.data, onChanged: _setAutoDownload),
                  ),
                );
              }),
          Divider(height: 1),
          FutureBuilder<int>(
            future: _getSkipSecond(widget.podcastLocal.id),
            initialData: 0,
            builder: (context, snapshot) => ListTile(
              onTap: () {
                generalDialog(
                  context,
                  title: Text(s.skipSecondsAtStart, maxLines: 2),
                  content: DurationPicker(
                    duration: Duration(seconds: snapshot.data),
                    onChange: (value) => _seconds = value.inSeconds,
                  ),
                  actions: <Widget>[
                    FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                        _seconds = 0;
                      },
                      child: Text(
                        s.cancel,
                        style: TextStyle(color: Colors.grey[600]),
                      ),
                    ),
                    FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                        _saveSkipSeconds(_seconds);
                      },
                      child: Text(
                        s.confirm,
                        style: TextStyle(color: context.accentColor),
                      ),
                    )
                  ],
                ).then((value) => setState(() {}));
              },
              leading: Icon(Icons.fast_forward),
              title: Text(s.skipSecondsAtStart),
              trailing: Padding(
                padding: const EdgeInsets.only(right: 10.0),
                child: Text(snapshot.data.toTime),
              ),
            ),
          ),
          Divider(height: 1),
          ListTile(
              onTap: () {
                if (_markStatus != MarkStatus.start) {
                  _confirmMarkListened(context);
                }
              },
              title: Text(s.menuMarkAllListened),
              leading: SizedBox(
                height: 20,
                width: 20,
                child: CustomPaint(
                  painter: ListenedAllPainter(
                      context.brightness == Brightness.light
                          ? Colors.grey[600]
                          : Colors.white,
                      stroke: 2),
                ),
              ),
              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)),
              )),
          Divider(height: 1),
          ListTile(
              onTap: () {
                if (_coverStatus != RefreshCoverStatus.start) {
                  _refreshArtWork();
                }
              },
              title: Text(s.refreshArtwork),
              leading: Icon(Icons.refresh),
              trailing: SizedBox(
                  height: 20,
                  width: 20,
                  child: Padding(
                      padding: const EdgeInsets.only(right: 10.0),
                      child: _getRefreshStatusIcon(_coverStatus)))),
          Divider(height: 1),
        ]);
  }
}
