package de.sebse.fuplanner.services.kvv.types;

import com.google.android.gms.common.internal.Objects;

import java.io.Serializable;
import java.util.ArrayList;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.ui.treeview.LayoutItemType;
import de.sebse.fuplanner.tools.ui.treeview.TreeNode;


public abstract class Resource implements Serializable {

    final String author;
    final long modifiedDate;
    final String title;
    final String url;
    private final boolean visible;
    private final String container;


    Resource(String author, String title, long modifiedDate, String url, boolean visible, String container) {
        this.author = author;
        this.title = title;
        this.modifiedDate = modifiedDate;
        this.url = url;
        this.visible = visible;
        this.container = container;
    }

    public String getAuthor() {
        return author;
    }

    public long getModifiedDate() {
        return modifiedDate;
    }

    public String getTitle() {
        return title;
    }

    public String getUrl() {
        return url;
    }

    public String getContainer() {
        return container;
    }

    public boolean isVisible() {
        return visible;
    }

    public abstract TreeNode getTreeNode();

    @Override
    public int hashCode() {
        return Objects.hashCode(getAuthor(), getContainer(), getModifiedDate(), getTitle(), getUrl());
    }

    public static class Document extends Resource implements LayoutItemType {

        private final ArrayList<DownloadFile> urls;
        private final String body;

        public Document(String author, String title, long modifiedDate, String url, boolean visible, String container, String body) {
            super(author, title, modifiedDate, url, visible, container);
            this.body = body;
            this.urls = new ArrayList<>();
        }

        @NonNull
        @Override
        public String toString() {
            return "Resource{" +
                    "author='" + author + '\'' +
                    ", modifiedDate=" + modifiedDate +
                    ", title='" + title + '\'' +
                    ", url='" + url + '\'' +
                    ", body='" + body + '\'' +
                    ", urls='" + urls + '\'' +
                    '}';
        }

        public String getBody() {
            return body;
        }

        public void addUrl(String url, String name){
            urls.add(new DownloadFile(url, name));
        }

        public DownloadFile getUrl(int id){
            return urls.get(id);
        }

        public int size(){
            return urls.size();
        }

        @Override
        public TreeNode getTreeNode() {
            return new TreeNode<>(this);
        }

        @Override
        public @LayoutRes int getLayoutId() {
            return R.layout.list_announcement_items;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(super.hashCode(), urls, body, this.getClass().getSimpleName());
        }

        public class DownloadFile implements Serializable {
            public final String url;
            public final String name;

            public DownloadFile(String url, String name) {
                this.url = url;
                this.name = name;
            }

            @Override
            public int hashCode() {
                return Objects.hashCode(url, name);
            }
        }
    }

    public static class File extends Resource implements LayoutItemType {
        private final String type;

        public File(String author, String title, long modifiedDate, String url, boolean visible, String container, String type) {
            super(author, title, modifiedDate, url, visible, container);
            this.type = type;
        }

        @NonNull
        @Override
        public String toString() {
            return "Resource{" +
                    "author='" + author + '\'' +
                    ", modifiedDate=" + modifiedDate +
                    ", title='" + title + '\'' +
                    ", url='" + url + '\'' +
                    ", type='" + type + '\'' +
                    '}';
        }

        @Override
        public TreeNode getTreeNode() {
            return new TreeNode<>(this);
        }

        @Override
        public @LayoutRes int getLayoutId() {
            return R.layout.item_file;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(super.hashCode(), this.type, this.getClass().getSimpleName());
        }
    }

    public static class Folder extends Resource implements LayoutItemType {

        private final ArrayList<Resource> children;
        public Folder(String author, String title, long modifiedDate, String url, boolean visible, String container) {
            super(author, title, modifiedDate, url, visible, container);
            children = new ArrayList<>();
        }

        public void add(Resource res){
            children.add(res);
        }

        public Resource get(int id){
            return children.get(id);
        }

        public int size(){
            return children.size();
        }

        @NonNull
        @Override
        public String toString() {
            return "Resource{" +
                    "author='" + author + '\'' +
                    ", modifiedDate=" + modifiedDate +
                    ", title='" + title + '\'' +
                    ", url='" + url + '\'' +
                    ", children='" + children + '\'' +
                    '}';
        }

        @Override
        public TreeNode getTreeNode() {
            TreeNode dir = new TreeNode<>(this);
            for (Resource res: children) {
                dir.addChild(res.getTreeNode());
            }
            return dir;
        }

        @Override
        public @LayoutRes int getLayoutId() {
            return R.layout.item_dir;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(super.hashCode(), children, this.getClass().getSimpleName());
        }
    }
}


