import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:html/parser.dart' as parser;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(useMaterial3: true).copyWith(
        colorScheme: ColorScheme.fromSeed(
            seedColor: Colors.blueAccent, brightness: Brightness.dark),
        scaffoldBackgroundColor: const Color(0xFF121212),
        cardColor: const Color(0xFF1E1E1E),
      ),
      home: const AnimeListScreen(),
    );
  }
}

class AnimeListScreen extends StatefulWidget {
  const AnimeListScreen({super.key});

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

class AnimeListScreenState extends State<AnimeListScreen> {
  final List<Map<String, String>> _animeList = [];
  bool _isLoading = true;
  bool _hasMore = true;
  int _currentPage = 1;
  final ScrollController _scrollController = ScrollController();
  static const userAgent =
      'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36';

  @override
  void initState() {
    super.initState();
    _fetchAnimeList();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        _loadMore();
      }
    });
  }

  Future<void> _fetchAnimeList([int page = 1]) async {
    const baseUrl = 'https://www.okanime.xyz/espisode-list';
    final url = '$baseUrl?page=$page';
    try {
      final response = await http.get(Uri.parse(url), headers: {
        'User-Agent': userAgent,
      });
      if (response.statusCode == 200) {
        final document = parser.parse(response.body);
        final animeElements =
            document.querySelectorAll('div.section-content.mt-3 > div > div');
        if (animeElements.isEmpty) {
          _hasMore = false;
        } else {
          final newAnimeList = animeElements.map((element) {
            final titleElement = element.querySelector('div.anime-title > h4');
            final episodeElement =
                element.querySelector('div.anime-title > h5');
            final imgElement = element.querySelector('div.episode-image > img');
            final urlElement = element.querySelector('div.episode-image > a');
            return {
              'title': titleElement?.text.trim() ?? 'No title found',
              'episode': episodeElement?.text.trim() ?? 'No episode number found',
              'imgUrl': imgElement?.attributes['src'] ?? '',
              'pageUrl': urlElement?.attributes['href'] ?? '',
            };
          }).toList();
          setState(() {
            _animeList.addAll(newAnimeList);
            _isLoading = false;
          });
        }
      } else {
        _handleError('Failed to load page $page');
      }
    } catch (e) {
      _handleError('Error fetching anime list: $e');
    }
  }

  void _handleError(String message) {
    if (kDebugMode) {
      print(message);
    }
    setState(() {
      _isLoading = false;
    });
    ScaffoldMessenger.of(context)
        .showSnackBar(SnackBar(content: Text(message)));
  }

  void _loadMore() {
    if (!_isLoading && _hasMore) {
      setState(() {
        _isLoading = true;
        _currentPage++;
      });
      _fetchAnimeList(_currentPage);
    }
  }

  Future<String> _fetchStreamUrl(String pageUrl) async {
    try {
      final response = await http.get(Uri.parse(pageUrl), headers: {
        'User-Agent': userAgent,
      });
      if (response.statusCode == 200) {
        var document = parser.parse(response.body);
        var streamLinks =
            document.querySelectorAll('#streamlinks > a');
        for (var link in streamLinks) {
          if (link.text.contains('sendvid')) {
            var embedUrl = link.attributes['data-src'] ?? 'No stream URL found';
            if (embedUrl != 'No stream URL found') {
              final embedResponse = await http.get(Uri.parse(embedUrl), headers: {
                'User-Agent': userAgent,
              });
              if (embedResponse.statusCode == 200) {
                var embedDocument = parser.parse(embedResponse.body);
                var videoElement = embedDocument.querySelector('video source');
                return videoElement?.attributes['src'] ?? 'No .mp4 URL found';
              }
            }
          }
        }
      }
      return 'No .mp4 URL found';
    } catch (e) {
      if (kDebugMode) {
        print('Error fetching stream URL: $e');
      }
      return 'No .mp4 URL found';
    }
  }

  void _launchVideoUrl(String mp4Url) async {
    if (mp4Url != 'No .mp4 URL found') {
      if (await canLaunchUrl(Uri.parse(mp4Url))) {
        await launchUrl(
          Uri.parse(mp4Url),
          mode: LaunchMode.externalApplication,
        );
      } else {
        _handleError('Could not launch video URL');
      }
    } else {
      _handleError('Could not fetch video URL');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: _isLoading && _animeList.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : ListView.builder(
              controller: _scrollController,
              itemCount: _hasMore ? _animeList.length + 1 : _animeList.length,
              itemBuilder: (context, index) {
                if (index < _animeList.length) {
                  final anime = _animeList[index];
                  return Card(
                    clipBehavior: Clip.antiAlias,
                    margin:
                        const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    child: Stack(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Row(
                            children: [
                              CachedNetworkImage(
                                imageUrl: anime['imgUrl']!,
                                width: 120,
                                height: 160,
                                fit: BoxFit.cover,
                                placeholder: (context, url) => const SizedBox(
                                  width: 120,
                                  height: 160,
                                  child: Center(
                                      child: CircularProgressIndicator()),
                                ),
                                errorWidget: (context, url, error) =>
                                    const Icon(Icons.error),
                              ),
                              const SizedBox(width: 16),
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      anime['title']!,
                                      maxLines: 2,
                                      overflow: TextOverflow.ellipsis,
                                      style: const TextStyle(
                                          fontSize: 16,
                                          fontWeight: FontWeight.bold),
                                    ),
                                    Text('${anime['episode']}'),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                        Positioned(
                          bottom: 8,
                          right: 8,
                          child: ElevatedButton(
                            onPressed: () async {
                              final mp4Url =
                                  await _fetchStreamUrl(anime['pageUrl']!);
                              _launchVideoUrl(mp4Url);
                            },
                            child: const Text('Watch Now'),
                          ),
                        ),
                      ],
                    ),
                  );
                } else {
                  return Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Center(
                      child: _isLoading
                          ? const CircularProgressIndicator()
                          : const SizedBox(),
                    ),
                  );
                }
              },
            ),
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }
}
improve design ui