<?php
/**
 * app/plugins/bookmarks/controllers/bookmarks.php
 *
 * This is the bookmarks controller.
 *
 * @package TP Bookmarks
 * @version 3.0
 * @author  Joey Kimsey <Joey@thetempusproject.com>
 * @link    https://TheTempusProject.com
 * @license https://opensource.org/licenses/MIT [MIT LICENSE]
 */
namespace TheTempusProject\Controllers;

use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Models\Bookmarks as Bookmark;
use TheTempusProject\Models\Folders;
use TheTempusProject\Models\BookmarkDashboards as Dashboards;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\Preferences;
use TheTempusProject\Canary\Bin\Canary as Debug;

class Bookmarks extends Controller {
    protected static $bookmarks;
    protected static $folders;
    protected static $dashboards;

    public function __construct() {
        parent::__construct();
        if ( ! App::$isLoggedIn ) {
            Session::flash( 'notice', 'You must be logged in to create or manage bookmarks.' );
            return Redirect::home();
        }
        self::$bookmarks = new Bookmark;
        self::$folders = new Folders;
        self::$dashboards = new Dashboards;
        self::$title = 'Bookmarks - {SITENAME}';
        self::$pageDescription = 'Add and save url bookmarks here.';

        $folderTabs = Views::simpleView( 'bookmarks.nav.folderTabs' );
        if ( stripos( Input::get('url'), 'bookmarks/bookmarks' ) !== false ) {
            $tabsView = Navigation::activePageSelect( $folderTabs, '/bookmarks/folders/', false, true );
            $userFolderTabs = Views::simpleView('bookmarks.nav.userFolderTabs', self::$folders->simpleObjectByUser(true) );
            $userFolderTabsView = Navigation::activePageSelect( $userFolderTabs, Input::get( 'url' ), false, true );
        } else {
            $tabsView = Navigation::activePageSelect( $folderTabs, Input::get( 'url' ), false, true );
            $userFolderTabsView = '';
        }
        Components::set( 'userFolderTabs', $userFolderTabsView );
        Components::set( 'SITE_URL', Routes::getAddress() );
        Views::raw( $tabsView );
        Components::append( 'TEMPLATE_JS_INCLUDES', Template::parse('<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/plugins/bookmarks/js/bookmarks.js"></script>' ) );
        $viewOptions = Views::simpleView( 'bookmarks.nav.viewOptions' );
        Components::set( 'VIEW_OPTIONS', $viewOptions );
        $dashOptions = Views::simpleView( 'bookmarks.dashboards.dashOptions' );
        Components::set( 'DASH_OPTIONS', $dashOptions );
        $this->setPrefToggles();
    }

    public function index() {
        self::$title = 'Manage Bookmarks - {SITENAME}';
        if ( Input::exists('submit') ) {
            $prefs = new Preferences;
            $user = new User;
            $fields = $prefs->convertFormToArray( true );
            $out = $user->updatePrefs( $fields, App::$activeUser->ID );
            $this->setPrefToggles();
        }

        $folders = self::$folders->byUser();
        $panelArray = [];
        if ( !empty( $folders ) ) {
            foreach ( $folders as $folder ) {
                $panel = new \stdClass();
                $folderObject = new \stdClass();
                $folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
                $folderObject->ID = $folder->ID;
                $folderObject->title = $folder->title;
                $folderObject->color = $folder->color;
                $folderObject->uuid = $folder->uuid;
                $folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
                $panelArray[] = $folderObject;
            }
        }
        if ( ! empty( $folders ) ) {
            Components::set( 'folderPanels', Views::simpleView( 'bookmarks.components.bookmarkListPanel', $panelArray ) );
            return Views::view( 'bookmarks.dash' );
        }
        return Views::view( 'bookmarks.indexExplainer' );
    }

    /**
     * Bookmarks
     */
    public function bookmark( $id = 0 ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmark/' . $id );
        return Views::view( 'bookmarks.bookmarks.view', $bookmark );
    }

    public function unsorted() {
        self::$title = 'Unsorted Bookmarks - {SITENAME}';
        $bookmarks = self::$bookmarks->noFolder();
        Views::view( 'bookmarks.bookmarks.unsorted', $bookmarks );
    }

    public function bookmarks( $id = null ) {
        $folder = self::$folders->findById( $id );
        if ( $folder == false ) {
            Session::flash( 'error', 'Folder not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $folder->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to view this folder.' );
            return Redirect::to( 'bookmarks/index' );
        }
        Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmarks/' . $id );
        
        $panelArray = [];
        $panel = new \stdClass();
        $folderObject = new \stdClass();
        $folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
        $folderObject->ID = $folder->ID;
        $folderObject->title = $folder->title;
        $folderObject->color = $folder->color;
        $folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
        $panel->panel = Views::simpleView( 'bookmarks.components.bookmarkListPanel', [$folderObject] );
        $panelArray[] = $panel;
        
        return Views::view( 'bookmarks.bookmarks.listPage', $panelArray );
    }

    public function createBookmark( $id = null ) {
        self::$title = 'Add Bookmark - {SITENAME}';
        $folderID = Input::get('folder_id') ? Input::get('folder_id') : $id;
        $folderID = Input::post('folder_id') ? Input::post('folder_id') : $id;
        $this->setFolderSelect( $folderID );

        if ( ! Input::exists() ) {
            return Views::view( 'bookmarks.bookmarks.create' );
        }
        if ( ! Forms::check( 'createBookmark' ) ) {
            Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.bookmarks.create' );
        }

        $result = self::$bookmarks->create(
            Input::post('title'),
            Input::post('url'),
            $folderID,
            Input::post('description'),
            Input::post('color'),
            Input::post('privacy'),
        );

        if ( ! $result ) {
            Issues::add( 'error', [ 'There was an error creating your bookmark.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.bookmarks.create' );
        }
        // self::$bookmarks->refreshInfo( $result );
        Session::flash( 'success', 'Your Bookmark has been created.' );
        if ( ! empty( $folderID ) ) {
            Redirect::to( 'bookmarks/bookmarks/'. $folderID );
        } else {
            Redirect::to( 'bookmarks/index' );
        }
    }

    public function editBookmark( $id = null ) {
        self::$title = 'Edit Bookmark - {SITENAME}';
        $folderID = Input::exists('folder_id') ? Input::post('folder_id') : '';

        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Issues::add( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( empty( $folderID ) ) {
            $folderID = $bookmark->folderID;
        }

        $this->setFolderSelect( $folderID );
        Components::set( 'color', $bookmark->color );

        if ( ! Input::exists( 'submit' ) ) {
            return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
        }
        if ( ! Forms::check( 'editBookmark' ) ) {
            Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
        }

        $result = self::$bookmarks->update(
            $id,
            Input::post('title'),
            Input::post('url'),
            $folderID,
            Input::post('description'),
            Input::post('color'),
            Input::post('privacy'),
        );
        if ( ! $result ) {
            Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
        }
        Session::flash( 'success', 'Your Bookmark has been updated.' );
        Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
    }

    public function deleteBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Issues::add( 'error', 'Bookmark not found.' );
            return $this->index();
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
            return $this->index();
        }
        $result = self::$bookmarks->delete( $id );
        if ( !$result ) {
            Session::flash( 'error', 'There was an error deleting the bookmark(s)' );
        } else {
            Session::flash( 'success', 'Bookmark deleted' );
        }
        Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
    }

    /**
     * Folders
     */
    public function folders( $id = null) {
        $folder = self::$folders->findById( $id );
        if ( $folder == false ) {
            $folders = self::$folders->byUser();
            Components::set( 'foldersList', Views::simpleView( 'bookmarks.folders.list', $folders ) );
            return Views::view( 'bookmarks.folders.listPage' );
        }
        if ( $folder->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to view this folder.' );
            return Redirect::to( 'bookmarks/index' );
        }
        Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/folders/' . $id );
        return Views::view( 'bookmarks.folders.view', $folder );
    }

    public function createFolder( $id = 0 ) {
        self::$title = 'Create Folder - {SITENAME}';
        $folderID = Input::exists('folder_id') ? Input::post('folder_id') : $id;
        $folders = self::$folders->simpleByUser();
        if ( ! empty( $folders ) ) {
            $this->setFolderSelect( $folderID );
        } else {
            $folderSelect = '';
            Components::set( 'folderSelect', $folderSelect );
        }
        if ( ! Input::exists() ) {
            return Views::view( 'bookmarks.folders.create' );
        }
        if ( ! Forms::check( 'createFolder' ) ) {
            Issues::add( 'error', [ 'There was an error creating your folder.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.folders.create' );
        }
        $folder = self::$folders->create( Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
        if ( ! $folder ) {
            return Views::view( 'bookmarks.folders.create' );
        }
        Session::flash( 'success', 'Your Folder has been created.' );
        Redirect::to( 'bookmarks/folders' );
    }

    public function editFolder( $id = null ) {
        self::$title = 'Edit Folder - {SITENAME}';
        $folder = self::$folders->findById( $id );

        if ( $folder == false ) {
            Issues::add( 'error', 'Folder not found.' );
            return $this->index();
        }

        if ( $folder->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to modify this folder.' );
            return $this->index();
        }
        $folderID = ( false === Input::exists('folder_id') ) ? $folder->ID : Input::post('folder_id');

        $this->setFolderSelect( $folderID );
        Components::set( 'color', $folder->color );

        if ( ! Input::exists( 'submit' ) ) {
            return Views::view( 'bookmarks.folders.edit', $folder );
        }

        if ( !Forms::check( 'editFolder' ) ) {
            Issues::add( 'error', [ 'There was an error editing your folder.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.folders.edit', $folder );
        }

        $result = self::$folders->update( $id, Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
        if ( !$result ) {
            Issues::add( 'error', [ 'There was an error updating your folder.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.folders.edit', $folder );
        }
        Session::flash( 'success', 'Your Folder has been updated.' );
        Redirect::to( 'bookmarks/folders/'. $folder->ID );
    }

    public function deleteFolder( $id = null ) {
        $folder = self::$folders->findById( $id );
        if ( $folder == false ) {
            Issues::add( 'error', 'Folder not found.' );
            return $this->index();
        }
        if ( $folder->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to modify this folder.' );
            return $this->index();
        }
        $results = self::$bookmarks->deleteByFolder( $id );
        $result = self::$folders->delete( $id );
        if ( !$result ) {
            Session::flash( 'error', 'There was an error deleting the folder(s)' );
        } else {
            Session::flash( 'success', 'Folder deleted' );
        }
        Redirect::to( 'bookmarks/folders' );
    }

    /**
     * Dashboards
     */
    public function addDash() {
        self::$title = 'Add Dashboard - {SITENAME}';
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You must have an active membership to add dashboards.' );
            return $this->index();
        }
        $folders = self::$folders->byUser() ?? [];

        if ( !empty( $folders ) ) {
            foreach ( $folders as &$folder ) {
                $folder->selected = '';
            }
        }

        $linkSelect = Views::simpleView( 'bookmarks.components.linkSelect', $folders );
        Components::set( 'LINK_SELECT', $linkSelect );

        if ( ! Input::exists( 'submit' ) ) {
            return Views::view( 'bookmarks.dashboards.create' );
        }

        if ( !Forms::check( 'createDashboard' ) ) {
            Issues::add( 'error', [ 'There was an error creating your dashboard.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.dashboards.create' );
        }
        
        if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
            $filters = implode( ',', Input::post('link_filter') );
        } else {
            $filters = '';
        }
        if ( is_array( Input::post('link_order') ) && ! empty( Input::post('link_order') ) ) {
            $folders = implode( ',', Input::post('link_order') );
        } else {
            $folders = '';
        }
        $result = self::$dashboards->create( Input::post('title'), $filters, $folders, Input::post('description') );

        if ( !$result ) {
            Issues::add( 'error', [ 'There was an error creating your dashboard.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.dashboards.create' );
        }

        Issues::add( 'success', 'Your dashboard has been created.' );
        return $this->dashboards();
    }

    public function editDash( $id = null ) {
        self::$title = 'Edit Dashboard - {SITENAME}';
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You must have an active membership to edit dashboards.' );
            return $this->index();
        }
        $dash = self::$dashboards->findById( $id );

        if ( $dash == false ) {
            Issues::add( 'error', 'Unknown Dashboard' );
            return $this->dashboards();
        }

        if ( $dash->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to view this dashboard.' );
            return $this->dashboards();
        }

        $this->setDashToggles( explode( ',', $dash->saved_prefs ) );

        $folders = self::$folders->byUser() ?? [];
        $selectedFolders = explode( ',', $dash->link_order );
        if ( !empty( $folders ) ) {
            foreach ( $folders as &$folder ) {
                if ( in_array( $folder->ID, $selectedFolders ) ) {
                    $folder->selected = ' checked';
                } else {
                    $folder->selected = '';
                }
            }
        }

        $linkSelect = Views::simpleView( 'bookmarks.components.linkSelect', $folders );
        Components::set( 'LINK_SELECT', $linkSelect );

        if ( ! Input::exists( 'submit' ) ) {
            return Views::view( 'bookmarks.dashboards.edit', $dash );
        }

        if ( ! Forms::check( 'editDashboard' ) ) {
            Issues::add( 'error', [ 'There was an error editing your dashboard.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.dashboards.edit', $dash );
        }

        if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
            $filters = implode( ',', Input::post('link_filter') );
        } else {
            $filters = '';
        }

        if ( is_array( Input::post('link_order') ) && ! empty( Input::post('link_order') ) ) {
            $folders = implode( ',', Input::post('link_order') );
        } else {
            $folders = '';
        }

        $result = self::$dashboards->update( $id, Input::post('title'), $filters, $folders, Input::post('description') );
        
        if ( !$result ) {
            Issues::add( 'error', [ 'There was an error updating your dashboard.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.dashboards.edit', $dash );
        }

        Issues::add( 'success', 'Your dashboard has been updated.' );
        return $this->dashboards();
    }

    public function deleteDash( $id = null ) {
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You must have an active membership to delete dashboards.' );
            return $this->index();
        }
        $dash = self::$dashboards->findById( $id );
        if ( $dash == false ) {
            Issues::add( 'error', 'Unknown Dashboard' );
            return $this->dashboards();
        }
        if ( $dash->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to delete this dash.' );
            return $this->dashboards();
        }
        $result = self::$dashboards->delete( $id );
        if ( !$result ) {
            Issues::add( 'error', 'There was an error deleting the dashboard(s)' );
        } else {
            Issues::add( 'success', 'Dashboard deleted' );
        }
        return $this->dashboards();
    }

    public function dashboard( $uuid = null ) {
        self::$title = 'Bookmark Dashboard - {SITENAME}';
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You must have an active membership to view dashboards.' );
            return $this->index();
        }
        $dash = self::$dashboards->findByUuid( $uuid );
        if ( $dash == false ) {
            return $this->dashboards();
        }
        if ( $dash->createdBy != App::$activeUser->ID ) {
            Issues::add( 'error', 'You do not have permission to view this dash.' );
            return $this->dashboards();
        }
        if ( Input::exists( 'submit' ) ) {
            if ( Forms::check( 'updateDashboard' ) ) {
                $filters = '';
                $folders = '';
                
                if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
                    $filters = implode( ',', Input::post('link_filter') );
                }

                if ( ! empty( Input::post('link_order') ) ) {
                    $folders =  Input::post('link_order');
                }

                $result = self::$dashboards->updateDash( $dash->ID, $filters, $folders );

                if ( !$result ) {
                    Issues::add( 'error', [ 'There was an error saving your dashboard.' => Check::userErrors() ] );
                } else {
                    Issues::add( 'success', 'Your dashboard has been saved.' );
                }
            } else {
                Issues::add( 'error', [ 'There was an error saving your dashboard.' => Check::userErrors() ] );
            }
            unset( $_POST );
        }
        $dash = self::$dashboards->findByUuid( $uuid );

        $foldersArray = [];
        if ( ! empty( $dash->link_order ) ) {
            $folders = explode( ',', $dash->link_order );
            foreach ( $folders as $key => $id ) {
                $folder = self::$folders->findById( $id );
                if ( empty( $folder ) ) {
                    continue;
                }
                
                $bookmarks = self::$bookmarks->byFolder( $folder->ID );
                if ( empty( $bookmarks ) ) {
                    continue;
                }

                $folderObject = new \stdClass();
                $folderObject->ID = $folder->ID;
                $folderObject->title = $folder->title;
                $folderObject->color = $folder->color;
                $folderObject->uuid = $folder->uuid;
                $folderObject->bookmarkRows = Views::simpleView( 'bookmarks.dashboards.bookmarkRows', $bookmarks );
                $foldersArray[] = $folderObject;
            }
        }
        Components::set( 'folderPanels', Views::simpleView( 'bookmarks.dashboards.folderPanels', $foldersArray ) );

        if ( ! empty( $dash->saved_prefs ) ) {
            $this->setDashToggles( explode( ',', $dash->saved_prefs ) );
        } else {
            $this->setDashToggles( [] );
        }

        return Views::view( 'bookmarks.dashboards.view', $dash );
    }

    public function dashboards() {
        self::$title = 'Bookmark Dashboards - {SITENAME}';
        
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You will need an active subscription to start creating dashboards. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
            return Views::view( 'bookmarks.dashboardExplainer' );
        }
        $dashboards = self::$dashboards->byUser();
        return Views::view( 'bookmarks.dashboards.list', $dashboards );
    }

    /**
     * Functionality
     */
    public function publish( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->publish( $id );
        Session::flash( 'success', 'Bookmark mad Public.' );
        return Redirect::to( 'bookmarks/share' );
    }

    public function retract( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->retract( $id );
        Session::flash( 'success', 'Bookmark made Private.' );
        return Redirect::to( 'bookmarks/share' );
    }

    public function hideBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->hide( $id );
        Session::flash( 'success', 'Bookmark hidden.' );
        return Redirect::to( 'bookmarks/index' );
    }

    public function archiveBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->archive( $id );
        Session::flash( 'success', 'Bookmark archived.' );
        return Redirect::to( 'bookmarks/index' );
    }

    public function showBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->show( $id );
        Session::flash( 'success', 'Bookmark shown.' );
        return Redirect::to( 'bookmarks/index' );
    }

    public function unarchiveBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        self::$bookmarks->unarchive( $id );
        Session::flash( 'success', 'Bookmark un-archived.' );
        return Redirect::to( 'bookmarks/index' );
    }

    public function refreshBookmark( $id = null ) {
        $bookmark = self::$bookmarks->findById( $id );
        if ( $bookmark == false ) {
            Session::flash( 'error', 'Bookmark not found.' );
            return Redirect::to( 'bookmarks/index' );
        }
        if ( $bookmark->createdBy != App::$activeUser->ID ) {
            Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
            return Redirect::to( 'bookmarks/index' );
        }
        $info = self::$bookmarks->refreshInfo( $id );
        if ( false == $info ) {
            Session::flash( 'error', 'Issue refreshing your bookmark.' );
            return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
        }
        Session::flash( 'success', 'Bookmark data refreshed.' );
        return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
    }

    public function import() {
        self::$title = 'Bookmark Import - {SITENAME}';
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You will need an active subscription to start importing bookmarks. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
            return Views::view( 'bookmarks.importExplainer' );
        }

        if ( ! Input::exists('submit') ) {
            return Views::view( 'bookmarks.import' );
        }

        if ( ! Forms::check( 'importBookmarks' ) ) {
            Issues::add( 'error', [ 'There was an error importing your bookmarks.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.import' );
        }

        if ( isset( $_FILES['bookmark_file'] ) ) {
            $file = $_FILES['bookmark_file'];

            if ($file['size'] > 1024 * 1024) { // 1024 KB = 1 MB
                Issues::add( 'error', 'There is a 1 meg limit on bookmark imports at this time.' );
                return Views::view( 'bookmarks.import' );
            }

            $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
            if ($fileExtension !== 'html') {
                Issues::add( 'error', 'Invalid file type. Only .html files are allowed.' );
                return Views::view( 'bookmarks.import' );
            }

            $fileContent = file_get_contents($file['tmp_name']);
        } else {
            Issues::add( 'error', 'No Import detected' );
            return Views::view( 'bookmarks.import' );
        }

        $out = $this->parseBookmarks($fileContent);
        $date = date('F j, Y');
        $description = 'Imported on ' . $date . ' from file: ' . $file['name'];
        
        $importFolder = self::$folders->create( 'New Import', 0, $description );
        foreach ($out as $folder => $bookmarks) {
            $currentFolder = self::$folders->create( $folder, $importFolder, $description );
            foreach ($bookmarks as $index => $bookmark) {
                self::$bookmarks->create( $bookmark['name'], $bookmark['url'], $currentFolder);
            }
        }
        
        Session::flash( 'success', 'Your Bookmark has been created.' );
        Redirect::to( 'bookmarks/bookmarks/'. $importFolder );
    }

    public function export() {
        self::$title = 'Bookmark Export - {SITENAME}';
        if ( !App::$isMember ) {
            Issues::add( 'notice', 'You will need an active subscription to start exporting bookmarks. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
            return Views::view( 'bookmarks.exportExplainer' );
        }

        $folders = self::$folders->byUser();

        if ( ! Input::exists('submit') ) {
            return Views::view( 'bookmarks.export', $folders );
        }

        if ( ! Forms::check( 'exportBookmarks' ) ) {
            Issues::add( 'error', [ 'There was an error exporting your bookmarks.' => Check::userErrors() ] );
            return Views::view( 'bookmarks.export', $folders );
        }

        $htmlDoc = '';
        $htmlDoc .= '<!DOCTYPE NETSCAPE-Bookmark-file-1>' . PHP_EOL;
        $htmlDoc .= '<!-- This is an automatically generated file.' . PHP_EOL;
        $htmlDoc .= '     It will be read and overwritten.' . PHP_EOL;
        $htmlDoc .= '     DO NOT EDIT! -->' . PHP_EOL;
        $htmlDoc .= '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">' . PHP_EOL;
        $htmlDoc .= '<TITLE>Bookmarks</TITLE>' . PHP_EOL;
        $htmlDoc .= '<H1>Bookmarks</H1>' . PHP_EOL;
        $htmlDoc .= '<DL><p>' . PHP_EOL;
        foreach ( Input::post('BF_') as $key => $id ) {
            if ( $id == 'unsorted' ) {
                continue;
            }

            $folder = self::$folders->findById( $id );
            if ( $folder == false ) {
                Session::flash( 'error', 'Folder not found.' );
                return Redirect::to( 'bookmarks/index' );
            }

            $hiddenExcluded = ! ( Input::post('hiddenIncluded') ?? false );
            $archivedExcluded = ! ( Input::post('archivedIncluded') ?? false );
            
            $links = self::$bookmarks->byFolder( $folder->ID, $hiddenExcluded, $archivedExcluded );
            $htmlDoc .= $this->exportFolder( $folder->title, $folder->createdAt, $folder->createdAt, $links );
        }
        $htmlDoc .= '</DL><p>' . PHP_EOL;

        $folder = UPLOAD_DIRECTORY . App::$activeUser->username;
        if ( !file_exists( $folder ) ) {
            mkdir( $folder, 0777, true );
        }
        $file = $folder . DIRECTORY_SEPARATOR . 'export.html';
        
        $result = file_put_contents( $file, $htmlDoc );

        if ($result !== false) {
            $filename = basename($file);
            $downloadUrl = '/uploads/' . App::$activeUser->username . '/export.html';
            
            Session::flash( 'success', 'Your Export is available for download <a target="_blank" href="' . $downloadUrl . '">here</a>.' );
            Redirect::to( 'bookmarks/export' );
        } else {
            Session::flash( 'error', 'There was an issue exporting your bookmarks, please try again.' );
            return Redirect::to( 'bookmarks/export' );
        }
    }

    public function share() {
        $panelArray = [];
        $folders = self::$folders->byUser();
        if ( empty( $folders ) ) {
            return Views::view( 'bookmarks.shareExplainer' );
        }
        foreach ( $folders as $key => $folder ) {
            $panel = new \stdClass();
            $folderObject = new \stdClass();
            if ( $folder->privacy == 'private' ) {
                $links = self::$bookmarks->publicByFolder( $folder->ID );
            } else {
                $links = self::$bookmarks->byFolder( $folder->ID );
            }
            $folderObject->bookmarks = $links;

            $folderObject->ID = $folder->ID;
            $folderObject->uuid = $folder->uuid;
            $folderObject->title = $folder->title;
            $folderObject->color = $folder->color;
            $folderObject->privacyBadge = $folder->privacyBadge;

            $folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.shareListRows', $folderObject->bookmarks );
            $panel->panel = Views::simpleView( 'bookmarks.components.shareListPanel', [$folderObject] );
            $panelArray[] = $panel;
        }
        return Views::view( 'bookmarks.share', $panelArray );
    }


    /**
     * Private
     */
    private function exportFolder( $title, $editedAt, $createdAt, $links ) {
        $htmlDoc = '<DT><H3 ADD_DATE="'.$createdAt.'" LAST_MODIFIED="'.$editedAt.'">'.$title.'</H3>' . PHP_EOL;
        $htmlDoc .= '<DL><p>' . PHP_EOL;
        if ( ! empty( $links ) ) {
            foreach ( $links as $key => $link ) {
                $htmlDoc .= $this->exportLink( $link->url, $link->icon, $link->createdAt, $link->title );
            }
        }
        $htmlDoc .= '</DL><p>' . PHP_EOL;
        return $htmlDoc;
    }

    private function exportLink( $url, $icon, $createdAt, $title ) {
        $htmlDoc = '<DT><A HREF="'.$url.'" ADD_DATE="'.$createdAt.'" ICON="'.$icon.'">'.$title.'</A>' . PHP_EOL;
        return $htmlDoc;
    }

    private function parseBookmarks($htmlContent) {
        $started = false;
        $out = [];
        $currentFolder = [];
        $folderName = ['unknown'];
        $lines = explode("\n", $htmlContent);
        foreach ($lines as $line) {
            if ( $started == false ) {
                if (preg_match("/<h1>(.*?)<\/h1>/i", $line, $matches)) {
                    $started = true;
                }
                continue;
            }

            if (preg_match('/<DL><p>/i', $line, $matches)) {
                continue;
            }

            if (preg_match('/<H3(.*)>(.*?)<\/h3>/i', $line, $matches)) {
                $newFolder = $matches[2];
                $out[$newFolder] = [];
                array_unshift($folderName, $newFolder );
                continue;
            }

            if (preg_match('/<\/DL><p>/i', $line, $matches)) {
                array_shift($folderName);
                continue;
            }

            if (preg_match('/<A HREF="(.*?)"(.*)>(.*?)<\/A>/i', $line, $matches)) {
                $href = $matches[1];
                $guts = $matches[2];
                $text = $matches[3];
                $added = '';
                $icon = '';

                if (preg_match('/ADD_DATE="(.*?)"/i', $guts, $addMatches)) {
                    $added = $addMatches[1];
                }
                if (preg_match('/ICON="(.*?)"/i', $guts, $iconMatches)) {
                    $icon = $iconMatches[1];
                }

                $currentFolder = $folderName[0];
                $out[$currentFolder][] = [
                    'name' => $text,
                    'url' => $href,
                    'addDate' => $added,
                    'icon' => $icon,
                    'folderName' => $folderName[0],
                ];
                continue;
            }
        }
        return $out;
    }

    private function setFolderSelect( $folderID ) {
        $options = self::$folders->simpleByUser();
        $out = '';
        $out .= '<div class="mb-3 row">';
        $out .= '<label for="folder_id" class="col-lg-5 col-form-label text-end">Folder</label>';
        $out .= '<div class="col-lg-3">';
        $out .= '<select name="folder_id" id="folder_id" class="form-control">';
        if ( isset( $options[0] ) ) {
            $assocOptions = [];
            foreach ( $options as $key => $value ) {
                $assocOptions[$value] = $value;
            }
            $options = $assocOptions;
        }
        if ( ! empty( $options ) ) {
            foreach ( $options as $fieldname => $value ) {
                if ( $folderID == $value ) {
                    $selected = ' selected';
                } else {
                    $selected = '';
                }
                $out .= '<option value="' . $value . '"' . $selected . '>' . $fieldname . '</option>';
            }
        } else {
            $out .= '<option value="0" selected>No Folder</option>';
        }
        $out .= '</select>';
        $out .= '</div>';
        $out .= '</div>';
        $folderSelect = Template::parse( $out );
        Components::set( 'folderSelect', $folderSelect );
    }

    private function setPrefToggles() {
        $prefsArray = [
            'editModeSwitch',
            'showArchivedSwitch',
            'showHiddenSwitch',
            'archiveButtonSwitch',
            'visibilityButtonSwitch',
            'privacyButtonSwitch',
            'shareButtonSwitch',
            'addButtonSwitch'
        ];
        foreach ($prefsArray as $key => $name) {
            if ( empty( App::$activeUser->prefs[$name] ) ) {
                Components::set( $name . '_IS_CHECKED', '' );
            } else {
                Components::set( $name . '_IS_CHECKED', ' checked' );
            }
        }
    }

    private function setDashToggles( $current = [] ) {
        $prefsArray = [
            'editModeSwitch',
            'showArchivedSwitch',
            'showHiddenSwitch',
            'archiveButtonSwitch',
            'visibilityButtonSwitch',
            'privacyButtonSwitch',
            'shareButtonSwitch',
            'addButtonSwitch'
        ];
        foreach ( $prefsArray as $key => $name ) {
            Debug::error( $name );
            Debug::error( $current );
            if ( ! in_array( $name, $current ) ) {
                Components::set( $name . '_IS_CHECKED', '' );
            } else {
                Debug::error( '_IS_CHECKED' );
                Components::set( $name . '_IS_CHECKED', ' checked' );
            }
        }
    }
}
