#!/usr/bin/env raku

use Samaki;
use Samaki::Exporter::HTML;
use Samaki::Importer::Jupyter;
use Samaki::Page;
use Samaki::Plugins;
use Log::Async;
use Terminal::ANSI::OO;
use JSON::Fast;

logger.untapped-ok = True;
logger.send-to("samaki.log") if %*ENV<SAMAKI_DEBUG>;

my $editor = $*ENV<EDITOR> //  "vim";

sub edit(IO::Path $path) {
  put t.text-reset;
  shell <<$editor $path>>;
  exit note "no page" unless $path.IO.e;
}

#| Browse pages
multi MAIN(:$dir = $*CWD) {
  my $wkdir = $dir;
  my $q = Samaki.new(:wkdir($wkdir.IO), :$editor);
  $q.start-ui: 'browse';
}

#| Import from another format to a samaki file (default: jupyter)
multi MAIN('import', $target, :$format = 'jupyter') {
  given $format.lc {
    when 'jupyter' {
      my $importer = Samaki::Importer::Jupyter.new;
      my $samaki-name = $importer.import-file($target);
      note "✓ Imported from Jupyter: $samaki-name";
      MAIN($samaki-name);
    }
    default {
      exit note "Unknown import format: $format (supported: jupyter)";
    }
  }
}

#| Make a new page and edit
multi MAIN('new', :$wkdir = $*CWD) {
  my $q = Samaki.new(:$wkdir, :$editor);
  my $name = prompt "Please enter a name for the new Samaki page: ";
  my $page = "$name.samaki".IO;
  edit $page;
  $q.start-ui: :page($name);
}

#| Edit an existing page
multi MAIN(Str $target, :$wkdir = $*CWD) {
  if $target.contains('/') && !$target.ends-with('/') {
    my $page = $target.IO.basename;
    my $wkdir = $target.IO.dirname.IO;
    my $q = Samaki.new(:$wkdir, :$editor);
    $q.start-ui: :$page;
    exit;
  }

  if $target.IO.d && !("{$target}.samaki".IO.e) {
    MAIN(dir => $target);
    return;
  }

  my $q = Samaki.new(:$wkdir, :$editor);
  my $page = $target;
  $page .= subst('.samaki','') if $page.ends-with('samaki');
  $q.start-ui: :$page;
}

#| Reset the configuration to the default
multi MAIN('reset-conf') {
  my $wkdir = $*TMPDIR;
  my $q = Samaki.new(:$wkdir, :$editor);
  my $file = $q.config-file;
  if $file.IO.e {
    $file.IO.unlink;
    note "Deleted config file " ~ $file;
  } else {
    note "No config file to delete at " ~ $file;
  }
}

#| Edit the configuration file
multi MAIN('conf') {
  my $wkdir = $*TMPDIR;
  my $q = Samaki.new(:$wkdir, :$editor);
  my $path = $q.config-file;
  $path.IO.e or exit note "No config file at $path";
  shell <<$editor $path>>;
  note "Done editing config file at $path";
}

#| Export a samaki file to another format (default: HTML)
multi MAIN('export', $target, :$wkdir = $*CWD, :$output, :$format = 'html') {
  my $page-path = $target.IO;
  unless $page-path.e {
    exit note "File not found: $target";
  }

  # Determine page name and working directory
  my $page-name;
  my $actual-wkdir;
  if $target.contains('/') {
    $page-name = $page-path.basename.subst(/'.samaki'$/, '');
    $actual-wkdir = $page-path.dirname.IO;
  } else {
    $page-name = $target.subst(/'.samaki'$/, '');
    $actual-wkdir = $wkdir.IO;
  }

  # Initialize Samaki to get plugins configured
  my $q = Samaki.new(:wkdir($actual-wkdir), :$editor);

  # Load the page
  my $page = Samaki::Page.new(name => $page-name, wkdir => $actual-wkdir);
  my $loaded = $page.load(plugins => $q.plugins);

  unless $loaded {
    exit note "Failed to load page: " ~ ($page.errors // "unknown error");
  }

  # Export based on format
  given $format.lc {
    when 'html' {
      my $exporter = Samaki::Exporter::HTML.new(:$page, plugins => $q.plugins);
      my $html = $exporter.generate-html();

      # Determine output path
      my $output-path = $output ?? $output.IO !! $actual-wkdir.child("$page-name.html");

      # Write HTML to file
      spurt $output-path, $html;

      note "✓ Exported to HTML: $output-path";

      # Open in browser
      my $open-cmd = $*DISTRO.is-win ?? 'start' !! ($*KERNEL.name eq 'darwin' ?? 'open' !! 'xdg-open');
      shell "$open-cmd $output-path";
    }
    default {
      exit note "Unknown export format: $format (supported: html)";
    }
  }
}
