import { LitElement, css, html } from 'lit';
import { property, customElement, query } from 'lit/decorators.js';

import '@shoelace-style/shoelace/dist/components/card/card.js';

import '@shoelace-style/shoelace/dist/components/button/button.js';

import { styles } from '../../styles/shared-styles';

import {EditorState} from 'prosemirror-state'
import { Transaction } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import { Schema } from 'prosemirror-model';


import { keymap } from 'prosemirror-keymap';
import { toggleMark } from 'prosemirror-commands';
import {undo, redo, history} from 'prosemirror-history'
import { baseKeymap } from 'prosemirror-commands';

import {createMenuPlugin} from '../../components/menu-plugin'


export const customSchema = new Schema({
	nodes: {
	  text: {
		group: 'inline',
	  },
	  star: {
		inline: true,
		group: 'inline',
		toDOM() {
		  return ['star', '⭐'];
		},
		parseDOM: [{ tag: 'star' }],
	  },
	  paragraph: {
		group: 'block',
		content: 'inline*',
		toDOM() {
		  return ['p', 0];
		},
		parseDOM: [{ tag: 'p' }],
	  },
	  boring_paragraph: {
		group: 'block',
		content: 'text*',
		marks: '',
		toDOM() {
		  return ['p', { class: 'boring' }, 0];
		},
		parseDOM: [{ tag: 'p.boring', priority: 60 }],
	  },
	  doc: {
		content: 'block+',
	  },
	},
	marks: {
	  shouting: {
		toDOM() {
		  return ['shouting', 0];
		},
		parseDOM: [{ tag: 'shouting' }],
	  },
	  link: {
		attrs: { href: {} },
		toDOM(node) {
		  return ['a', { href: node.attrs.href }, 0];
		},
		parseDOM: [
		  {
			tag: 'a',
			getAttrs(dom) {
			  return { href: dom };
			},
		  },
		],
		inclusive: false,
	  },
	},
  });

// Create the menu plugin
const menuPlugin = createMenuPlugin(customSchema);

  // Commands
function insertStar(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
	const type = customSchema.nodes.star;
	const { $from } = state.selection;

	// If the parent cannot replace with the 'star' node, return false
	if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) {
	  return false;
	}

	// If dispatch is provided, apply the transaction
	if (dispatch) {
	  dispatch(state.tr.replaceSelectionWith(type.create()));
	}

	// Always return true if insertion conditions are met
	return true;
  }

function toggleLink(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
	let {doc, selection} = state
	if (selection.empty) return false
	let attrs = null
	if (!doc.rangeHasMark(selection.from, selection.to, customSchema.marks.link)) {
	  attrs = {href: prompt("Link to where?", "")}
	  if (!attrs.href) return false
	}
	return toggleMark(customSchema.marks.link, attrs)(state, dispatch)
  }


  // Keymap
const customKeymap = keymap({
	'Ctrl-Space': insertStar,
	"Ctrl-b": (state, dispatch) => {
    console.log("Ctrl-b pressed, toggling shouting mark...");
    return toggleMark(customSchema.marks.shouting)(state, dispatch);
  },
  	'Ctrl-q': (state, dispatch) => {
		console.log("you should have just gotten an alert");
		return toggleLink(state, dispatch);
	},

  });




@customElement('app-write')
export class AppWrite extends LitElement {
	@property({ type: String }) placeholder: string = 'Compose your note...';
	@property({ type: String }) public value?: string;

	// Reference to the ProseMirror container
	@query('#editor') editorContainer!: HTMLElement;

	private editorView!: EditorView




    static styles = [
        styles, css`
		:host {
		display: block;
		}

		shouting {
  all: unset; /* Remove inherited or conflicting styles */
  font-weight: bold;
  text-transform: uppercase;
  color: red; /* Add a visible color for debugging */
}

		`

    ];

    protected async firstUpdated() {
		console.log("Welcome to the compose page");
		await this.updateComplete;
		this.initializeEditor()

}
private initializeEditor() {
		if (!this.editorContainer) {
			console.error('Editor container not here');
			return
		}
 	const doc = customSchema.nodes.doc.createAndFill();
	  if (!doc) {
		console.error("failed to create initial document")
		return;
	}

	const state = EditorState.create({
    	doc,
    	plugins: [
			menuPlugin,
			history(),
      		keymap({
        	'Mod-z': undo,
        	'Mod-y': redo,
      		}),
      		keymap(baseKeymap),
     	 // Add the plus-button plugin here
			customKeymap
    		],
	 	});



		let view = new EditorView(this.editorContainer, {
			state,
			dispatchTransaction(transaction) {
				console.log('Document size went from', transaction.before.content.size, "to",
					transaction.doc.content.size
				)
				let newState = view.state.apply(transaction)
				view.updateState(newState)
			}
		});
		this.editorView = view;
		console.log(state.plugins);

		console.log('editor initialized')

	}

	/* connectedCallback(): void {
		super.connectedCallback();
		if(!this.editorView) {
			this.editorView;
		}
	} */

    disconnectedCallback(): void {
        super.disconnectedCallback();
		if (this.editorView) {
			this.editorView.destroy();
			this.editorView = null!
		}
    }



    protected render() {
        return html`
        <app-header ?enableBack="${true}"></app-header>

		<main>
		<div id="welcomeBar">

        <sl-card id="welcomeCard">
            <div slot="header">
              <h2>Editor Demo</h2>
            </div>



			<h3>Basic Intructions</h3>
			<p>click inside the white text area to highlight with your cursor.
			You can type and press enter to insert a new block below.
			<br>
			Highlight a piece of text, then CTRL+X to cut and CTRL+V to paste.<br>
			Press Ctrl+Space to add a yellow star to the document. Press
			Ctrl+B over a highlighted selection to add the "shouting" mark, making
			it all caps and red.</p>

</sl-card>
<sl-card>
<div id="editor" class="ProseMirror"></div>
</sl-card>
            </main>
        `}
	}