import { LitElement, html, css } from "lit";
import { customElement } from "lit/decorators/custom-element.js";
import { property } from "lit/decorators/property.js";
import { styleMap } from "lit/directives/style-map.js";
import { ref, createRef, Ref } from "lit/directives/ref.js";
import { LitDraggable } from "./lit-draggable.js";
import { LitDragEvent } from "./types.js";
import { LitDragStart, LitDragEnd } from "./lit-events.js";

@customElement("fridge-tile")
export class FridgeTile extends LitElement {
    @property({ type: String })
    word = "";

    dragHandle: LitDraggable;

    transform = {
        rotate: Math.random() * 30 - 15,
        scale: 1.0,
    };

    handle: Ref<HTMLDivElement> = createRef();

    static get styles() {
        return css`
            :host {
                display: block;
                position: absolute;
            }

            :host([data-dragging="idle"]) {
                cursor: grab;
            }

            :host([data-dragging="dragging"]) {
                cursor: grabbing;
            }

            .word {
                font-family: Georgia, Palatino, "Palatino Linotype", Times, "Times New Roman", serif;
                box-shadow: 0 0 0.375rem 0.125rem #aaa;
                text-align: center;
                border-radius: 10%;
                user-select: none;
                cursor: pointer;
                color: #444;
                font-size: 0.9375rem;
                padding: 0.1875rem 0.25rem 0.25rem 0.25rem;
                position: relative;
                background: white;
                z-index: 100;
                transition-property: transform;
                transition-duration: 200ms;
                transition-timing-function: ease-in-out; //other options are ease
            }

            .word.dragging {
                font-size: 1.1875rem;
            }
        `;
    }

    constructor() {
        super();
        this.dragHandle = new LitDraggable(this);
        this.onDragEnd = this.onDragEnd.bind(this);
        this.onDragStart = this.onDragStart.bind(this);
        this.addEventListener(LitDragEnd.eventName, this.onDragEnd);
        this.addEventListener(LitDragStart.eventName, this.onDragStart);
    }

    onDragEnd(ev: LitDragEvent) {
        this.transform = { scale: 1.0, rotate: Math.random() * 30 - 15 };
        this.handle.value!.style.setProperty(
            "transform",
            `scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
        );
        this.style.setProperty("top", `${+ev.offsetY}px`);
        this.style.setProperty("left", `${+ev.offsetX}px`);
    }

    onDragStart(_ev: LitDragEvent) {
        this.transform = { scale: 1.3, rotate: Math.random() * 30 - 15 };
        this.handle.value!.style.setProperty(
            "transform",
            `scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
        );
    }

    render() {
        const styles = {
            width: `${this.word.length * 1.2}ch`,
            transform: `rotate(${this.transform.rotate}deg)`,
        };
        return html`<div part="word ${ref(this.handle)} " style="${styleMap(styles)}" class="word">${this.word}</div>`;
    }
}

//
//     base_style:
//         'font-size': "15px"
//
//     drag_style:
//         'font-size': "19px"
//
//     visible: false
//
//     # Initial tilt.
//     rotation: (Math.random() * 30) - 15
//
//     constructor: (@word, @board, @master) ->
//         super()
//         @el = $('<div class="word">' + @word.w + '</div>')
//         @el.css @base_style
//         @board.append(@el)
//         @rotation = (Math.random() * 30) - 15
//
//         @el.draggable
//             helper: "original"
//             refreshPositions: false
//             revertDuration: 1
//
//             start: (event) =>
//                 mod = (Math.random() * 16) - 8
//                 @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
//                 style = clone(@drag_style)
//                 style.rotate = @rotation
//                 @el.animate(style, 200, () => @new_width = @el.width())
//                 true
//
//             stop: (event) =>
//                 # Drop the thing dead center, at least on the x-axis,
//                 # and animate its return to the new font size.
//                 mod = (Math.random() * 16) - 8
//                 @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
//                 style = clone(@base_style)
//                 style.rotate = @rotation
//                 style['left'] = parseInt(@el.position().left + (0.5 * (@new_width - @width())))
//                 @el.animate style, 200, 'easeOutQuad', () =>
//                     @reset_dims()
//                     explode_hearts(@board, @)
//                     @master.poemed(@)
//                 true
//
//     fadeOut: -> $.Deferred((d) => @el.fadeOut('fast', (() => @unset_dims(); @visible = false; d.resolve()))).promise()
//
//     # Shape for deteriming poemed collision
//     fuzzyshape: -> shape  @left() - WIDTH_FUZZ, @top() - HEIGHT_FUZZ, @width() + (2 * WIDTH_FUZZ), @height() + (2 * HEIGHT_FUZZ)
//
//     get_new_pos: ->
//         bh = => parseInt(Math.random() * (@board.height() - @height()) * 0.985)
//         bw = => parseInt(Math.random() * (@board.width() - @width()) * 0.98)
//         [top, left] = [bh(), bw()]
//         [top, left] = [bh(), bw()] until @master.unoccupied(left, top, @width(), @height())
//         [top, left]
//
//     flyIn: ->
//         fd = (mod) ->
//             m = parseInt(40 * Math.random())
//             if (Math.random() < 0.5) then mod + m else -1 * m
//         @el.css
//             left: fd(@board.width())
//             top:  fd(@board.height())
//         dfd = $.Deferred()
//         x = Math.random()
//         [top, left] = @get_new_pos()
//         @el.fadeIn().animate {top: top, left: left, rotate: @rotation}, 1500, 'easeOutQuint', () =>
//             @visible = true
//             dfd.resolve()
//         dfd.promise()
//
//