import 'dart:io';

import 'package:dartboard_resume/dartboard_parser.dart';
import 'package:dartboard_resume/dartboard_widgets.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:toml/toml.dart';

int? lastDartboardHash;

Future<void> renderPdf(String tomlFilePath, {bool force = false}) async {
  try {
    final start = DateTime.now().microsecondsSinceEpoch;
    final dartboardData = DartboardData.fromToml(tomlFilePath);
    if (lastDartboardHash == dartboardData.hashCode && !force) {
      return;
    }
    lastDartboardHash = dartboardData.hashCode;
    stdout.writeln("Detected change:\nRendering with new dartboard data: $lastDartboardHash");
    final pdfFuture = Document()..addPage(_generatePdfPage(dartboardData: dartboardData, renderNs: 0));
    await pdfFuture.save();

    final renderNs = DateTime.now().microsecondsSinceEpoch - start;

    final pdf = Document();
    pdf.addPage(_generatePdfPage(dartboardData: dartboardData, renderNs: renderNs));
    final file = File("example.pdf");
    final bytes = await pdf.save();

    stdout.writeln('New pdf file saved.');
    file.writeAsBytesSync(bytes);
    stdout.writeln('Reloading llpp...');
    Process.runSync('pkill', ['-HUP', 'llpp']);
    UrlFootnotes().reset();
  } catch (e, st) {
    stderr.writeln('Encountered error: $e');
    stderr.writeln(st);
    try {
      stderr.writeln('Current toml map:\n${TomlDocument.loadSync(tomlFilePath).toMap()}');
    } catch (_) {
      stderr.writeln('Cannot display current toml map');
    }
  }
}

Page _generatePdfPage({required DartboardData dartboardData, required int renderNs}) {
  UrlFootnotes().style = dartboardData.defaultTextStyle;
  final List<Widget> groupedExperienceList = dartboardData.groupedExperiences.entries.map<Widget>(
    (entry) {
      final String subsection = entry.key;
      final List<DartboardExperience> experiences = entry.value;
      return Column(
        children: [
          Row(
            children: [
              Text(
                subsection,
                style: dartboardData.subheaderTextStyle
                    .merge(const TextStyle(fontSize: 18))
                    .apply(color: const PdfColorGrey(0.2)),
              ),
            ],
          ),
          Row(
            children: [
              Container(height: 2, width: 200, color: const PdfColorGrey(0.7)),
            ],
          ),
          SizedBox(height: 3),
          ...experiences.map(
            (DartboardExperience exp) => DartboardExperienceEntry(dartboardData: dartboardData, exp: exp),
          ),
        ],
      );
    },
  ).toList();
  final List<Widget> groupedMiscList = dartboardData.groupedMisc.entries.map<Widget>((entry) {
    final String subsection = entry.key;
    final List<DartboardMisc> miscs = entry.value;
    return Column(
      children: [
        Row(
          children: [
            Text(
              subsection,
              style: dartboardData.subheaderTextStyle
                  .merge(const TextStyle(fontSize: 18))
                  .apply(color: const PdfColorGrey(0.2)),
            ),
          ],
        ),
        Row(
          children: [
            Container(height: 2, width: 200, color: const PdfColorGrey(0.7)),
          ],
        ),
        SizedBox(height: 3),
        ...miscs.map(
          (DartboardMisc misc) => DartboardMiscEntry(dartboardData: dartboardData, misc: misc),
        ),
      ],
    );
  }).toList();
  return FullPage(
    pageTheme: PageTheme(
        buildBackground: (_) => Container(color: dartboardData.backgroundColor), pageFormat: PdfPageFormat.standard),
    build: (Context context) {
      return
          // FullPage(
          // ignoreMargins: true,
          // child:
          Column(
        children: [
          if (dartboardData.imagePath == null)
            Center(
              child: Column(
                children: [
                  Text(dartboardData.fullName, style: dartboardData.headerTextStyle),
                  if (dartboardData.phoneNumber != null)
                    Text(dartboardData.phoneNumber!, style: dartboardData.headerTextStyle),
                  if (dartboardData.email != null) Text(dartboardData.email!, style: dartboardData.headerTextStyle),
                ],
              ),
            )
          else
            SizedBox(
              height: 100,
              width: double.infinity,
              child: Stack(
                children: [
                  if (dartboardData.imagePath != null)
                    Positioned(
                      left: 0,
                      child: Container(
                        height: 100,
                        width: 100,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          image: DecorationImage(
                            fit: BoxFit.contain,
                            image: MemoryImage(
                              File(dartboardData.imagePath!).readAsBytesSync(),
                            ),
                          ),
                        ),
                      ),
                    ),
                  Center(
                    child: Column(
                      children: [
                        Text(dartboardData.fullName, style: dartboardData.headerTextStyle),
                        if (dartboardData.phoneNumber != null)
                          Text(dartboardData.phoneNumber!, style: dartboardData.headerTextStyle),
                        if (dartboardData.email != null)
                          Text(dartboardData.email!, style: dartboardData.headerTextStyle),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ...groupedExperienceList,
          ...groupedMiscList,
          // this is quirky and gets evaluated before the actual footnotes get added up, so the original adding is done in the prerender
          ...UrlFootnotes().footnotes,
          DartboardFooter(dartboardData: dartboardData, renderNs: renderNs),
        ],
        // ),
      );
    },
  );
}