package info.knacki.pass.ui.passwordList;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.LinearLayout;

import java.io.File;
import java.util.SortedSet;
import java.util.TreeSet;

import info.knacki.pass.io.FileUtils;
import info.knacki.pass.io.PathUtils;

public class PasswordListView extends LinearLayout {
    public String fRootPath;
    public String fCurrentDir;
    protected PasswordClickListener fClickListener;
    protected final Context fContext;

    class FileIdentity implements Comparable<FileIdentity> {
        final boolean fIsDir;
        final String fName;
        private boolean fParent = false;

        FileIdentity(boolean isDir, String name) {
            fIsDir = isDir;
            fName = name;
        }

        public FileIdentity setParent() {
            fParent = true;
            return this;
        }

        public boolean isParent() {
            return fParent;
        }

        @Override
        public int compareTo(@NonNull FileIdentity fileIdentity) {
            if (fIsDir && !fileIdentity.fIsDir)
                return -1;
            if (!fIsDir && fileIdentity.fIsDir)
                return 1;
            return fName.compareTo(fileIdentity.fName);
        }
    }

    protected PasswordListView ClearView() {
        removeAllViews();
        return this;
    }

    public boolean ShowParent() {
        File current = new File(fCurrentDir);
        if (new File(fRootPath).getAbsolutePath().equals(current.getAbsolutePath()))
            return false;
        DisplayDir(current.getParentFile());
        return true;
    }

    protected PasswordView CreateView(final FileIdentity file) {
        PasswordView pv = new PasswordView(getContext(), file.fIsDir ? ((file.isParent() ? PasswordView.TYPE_PARENT : 0) | PasswordView.TYPE_DIR) : PasswordView.TYPE_PASSWORD, file.fName);
        pv.setOnClickListener(view -> {
            File f = new File(fCurrentDir +"/" +file.fName);
            if (file.isParent()) {
                f = new File(fCurrentDir).getParentFile();
                DisplayDir(f);
            }
            if (f.isDirectory())
                DisplayDir(f);
            else
                fClickListener.OnPasswordClicked(f);
        });
        return pv;
    }

    public PasswordListView(final Context ctx) {
        super(ctx);
        fContext = ctx;
    }

    public PasswordListView(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);
        fContext = ctx;
    }

    public PasswordListView(Context ctx, AttributeSet attrs, int style) {
        super(ctx, attrs, style);
        fContext = ctx;
    }

    public void Init(PasswordClickListener clickListener, String rootPath) {
        fClickListener = clickListener;
        File rootDir = new File(rootPath);
        if (!rootDir.exists())
            FileUtils.MkDir(rootDir, true);
        fRootPath = rootPath;
        setOrientation(VERTICAL);
        DisplayDir(rootDir);
    }

    protected boolean IsHidden(File f) {
        return PathUtils.IsHidden(f.getAbsolutePath());
    }

    protected Boolean IsAccessGranted(File f) {
        if ((f.getName().charAt(0) == '.') && !f.getName().equals("..")) {
            return false;
        } else if (fRootPath.equals(f.getAbsolutePath())) {
            return false;
        } else if (IsHidden(f)) {
            return false;
        }
        return f.getAbsolutePath().startsWith(fRootPath);
    }

    public void refresh() {
        DisplayDir(new File(fCurrentDir));
    }

    public void reset() {
        DisplayDir(new File(fRootPath));
    }

    protected void DisplayDir(final File f) {
        ClearView();
        SortedSet<FileIdentity> files = new TreeSet<>();

        File[] fileArr = f.listFiles();
        if (fileArr != null)
            for (File i: fileArr)
                if (IsAccessGranted(i))
                    files.add(new FileIdentity(i.isDirectory(), i.getName()));
        if (!f.getAbsolutePath().equals(fRootPath)) {
            addView(CreateView(new FileIdentity(true, "Parent").setParent()));
        }
        for (FileIdentity i: files)
            addView(CreateView(i));
        fCurrentDir = f.getAbsolutePath();
    }
}
