import { Button, ComboBox, ScrollView, Switch } from "std-widgets.slint";

import { Const } from "Const.slint";
import { WindowBase } from "WindowBase.slint";

global LocalConst {
    out property<length> song-spacing: 5px;
    out property<length> cover-img-wh: 100px;
    out property<length> main-spacing: 10px;
    out property<color> active-background: #e0e0e0;
}

export enum SearchWindowMode { // TODO: Add progress indicator.
    Item,
    Message,
}

export struct SearchWindowItem {
    name: string,
    uploader-name: string,
    cover-img: image,
    duration: string,
    bpm: string,
    score: string,
    preview-url: string,
    download-url: string,
    difficulty-ints: [int],
    difficulty-strs: [string],
    active: bool,
    preview-active: bool,
}

component Song {
    in property<SearchWindowItem> item;

    callback select();

    touch := TouchArea {
        Rectangle {
            background: root.item.active || touch.has-hover ? LocalConst.active-background : Const.content-background;

            HorizontalLayout {
                spacing: LocalConst.song-spacing;

                Rectangle {
                    width: LocalConst.cover-img-wh;
                    height: LocalConst.cover-img-wh;

                    Image {
                        source: root.item.cover-img;
                        image-fit: contain;
                        width: LocalConst.cover-img-wh;
                        height: LocalConst.cover-img-wh;
                    }

                    if (root.item.active || touch.has-hover) : Image {
                        source: !root.item.preview-active ? @image-url("image/play.svg") : @image-url("image/stop.svg");
                        image-fit: contain;
                        x: 0;
                        y: 0;
                        width: LocalConst.cover-img-wh;
                        height: LocalConst.cover-img-wh;
                    }
                }

                Text {
                    text: root.item.name;
                    wrap: word-wrap;
                }
            }
        }

        clicked => {
            root.select();
        }
    }
}

export component SearchWindow inherits WindowBase {
    default-font-family: Const.default-font-family;
    default-font-size: Const.default-font-size;
    background: Const.border-color;

    in-out property<string> query;
    out property<string> order <=> order.current-value;
    property<int> orig-order-index;
    out property<bool> ascending <=> ascending.checked;
    in property<bool> test-visible: false;
    in property<SearchWindowMode> mode;
    in property<bool> show-detail: false;
    in property<[SearchWindowItem]> items;
    in property<SearchWindowItem> detail-item;
    in-out property<int> difficulty-index;
    in property<string> detail-message;
    in property<string> message;

    callback change-query();
    callback change-other();
    callback refresh();
    callback test();
    callback select(int);
    callback play();

    init => {
        root.orig-order-index = order.current-index;
    }

    VerticalLayout { 
        Text {
            text: "Search";
            horizontal-alignment: center;
            vertical-alignment: center;
            color: Const.title-color;
            height: Const.title-height;
        }

        rect := Rectangle {
            background: Const.content-background;
            border-color: Const.border-color;
            border-width: Const.border-width;
            border-radius: 2 * Const.border-width;

            VerticalLayout {
                width: rect.width - 2 * rect.border-width;
                height: rect.height - 2 * rect.border-width;
                padding: LocalConst.main-spacing;
                spacing: LocalConst.main-spacing;

                HorizontalLayout {
                    vertical-stretch: 0;
                    spacing: LocalConst.main-spacing;

                    Button {
                        text: root.query == "" ? "Query" : root.query;
                        width: 20%; // TODO: how to constraint width (e.g. query is too long)?
                                
                        clicked => {
                            root.change-query();
                        }
                    }

                    order := ComboBox {
                        model: ["Latest", "Relevance", "Rating", "Curated", "Duration"];
                        current-index: 1;
                        width: 20%;

                        selected => {
                            if (root.orig-order-index != self.current-index) { // Trigger callback only in case of change.
                                root.orig-order-index = self.current-index;
                                root.change-other();
                            }
                        }
                    }

                    ascending := Switch {
                        text: self.checked ? "Ascending" : "Descending";
                        checked: false;
                        width: 20%;

                        toggled => {
                            root.change-other();
                        }
                    }

                    Button {
                        text: "Refresh";
                        width: 15%;

                        clicked => {
                            root.refresh();
                        }
                    }

                    if (root.test-visible) : Button {
                        text: "Test Mode";
                        width: 15%;

                        clicked => {
                            root.test();
                        }
                    }
                }

                if (root.mode == SearchWindowMode.Item) : HorizontalLayout {
                    vertical-stretch: 1;
                    spacing: LocalConst.main-spacing;

                    ScrollView {
                        width: (1200px - 2 * rect.border-width - 2 * LocalConst.main-spacing - LocalConst.main-spacing) / 2; // TODO: avoid hardcode of window width.
                        
                        VerticalLayout {
                            spacing: LocalConst.song-spacing;

                            for item[index] in root.items : Song {
                                item: item;

                                select => {
                                    root.select(index);
                                }
                            }
                        }
                    }

                    if (root.show-detail) : VerticalLayout {
                        width: (1200px - 2 * rect.border-width - 2 * LocalConst.main-spacing - LocalConst.main-spacing) / 2; // TODO: avoid hardcode of window width.
                        alignment: start;
                        spacing: LocalConst.main-spacing;

                        VerticalLayout {
                            Text {
                                text: "Uploader: " + root.detail-item.uploader-name;
                                wrap: word-wrap;
                            }

                            Text {
                                text: "Duration: " + root.detail-item.duration;
                                wrap: word-wrap;
                            }

                            Text {
                                text: "BPM: " + root.detail-item.bpm;
                                wrap: word-wrap;
                            }

                            Text {
                                text: "Score: " + root.detail-item.score + "%";
                                wrap: word-wrap;
                            }
                        }

                        HorizontalLayout {
                            spacing: LocalConst.main-spacing;

                            for difficulty-str[index] in root.detail-item.difficulty-strs : Button {
                                text: difficulty-str;
                                primary: root.difficulty-index == index;

                                clicked => {
                                    root.difficulty-index = index;
                                }
                            }
                        }

                        if (root.detail-item.difficulty-strs.length > 0) : Button {
                            text: "Play";

                            clicked => {
                                root.play();
                            }
                        }

                        if (root.detail-item.difficulty-strs.length == 0) : Text {
                            text: "The song doesn't support Standard characteristic";
                            wrap: word-wrap;
                        }

                        Text {
                            text: root.detail-message;
                            wrap: word-wrap;
                        }
                    }
                }

                if (root.mode == SearchWindowMode.Message) : Rectangle {
                    vertical-stretch: 1;

                    Text {
                        text: root.message;
                        wrap: word-wrap;
                    }
                }
            }
        }
    }
}