import type { DocumentConstructor, IDocument, IFileManager } from '@e-mc/types/lib';
import type { ExternalAsset, IFileThread } from '@e-mc/types/lib/asset';
import type { ExecAction, DocumentDirectory as IDocumentDirectory, DocumentModule as IDocumentModule, DocumentSettings as IDocumentSettings } from '@e-mc/types/lib/settings';

import type { DependencyScopes, DocumentOutput, FinalizedElement } from './squared';

interface DocumentDirectory extends IDocumentDirectory {
    template?: string;
    project?: string;
}

interface AndroidDocumentSettings extends Pick<IDocumentSettings, "users" | "directory">, PlainObject {
    extensions?: {
        task?: {
            exec?: ExecAction;
            command?: string;
        };
    };
    language?: {
        [T in LanguageOfType]?: LanguageType;
    };
}

type DocumentProperties = "targetAPI" | "resolutionScreenWidth" | "resolutionScreenHeight" | "elements" | "extensionData" | "directories";

export interface UserConfig extends Omit<DocumentOutput, DocumentProperties> {
    mainParentDir: string;
    mainSrcDir: string;
    mainActivityFile: string;
    javaVersion: number;
    dataBinding: boolean;
}

export interface DocumentModule extends IDocumentModule {
    settings?: AndroidDocumentSettings;
}

export interface TemplateData {
    localUri?: string;
    source?: string;
    existing?: boolean;
    kotlin?: boolean;
    language?: LanguageType;
}

export interface FindTemplateOptions {
    detect?: boolean;
    languageOf?: LanguageOfType;
    subDir?: string | string[];
    throwsDoesNotExist?: boolean;
}

export interface MavenArtifact {
    groupId: string;
    artifactId: string;
    version: string;
    scope?: DependencyScopes;
    dependencies?: MavenArtifact[];
}

export type LanguageType = "java" | "kotlin" | "java+kotlin";
export type LanguageOfType = "gradle";
export type DocumentAsset = ExternalAsset;

export interface IAndroidDocument<T extends IFileManager<U>, U extends DocumentAsset = DocumentAsset> extends IDocument<T, U, DocumentModule>, Pick<DocumentOutput, DocumentProperties> {
    config: UserConfig;
    elements: FinalizedElement[];
    extensionData: PlainObject;
    using(data: IFileThread): Promise<void>;
    writeTemplate(data: TemplateData, host?: T): void;
    findTemplate(baseDir: string, filename: string, options?: FindTemplateOptions): TemplateData;
    findData<V = AnyObject>(filename: string, format?: string): V | null;
    languageOf(name: LanguageOfType, value?: LanguageType): LanguageType | undefined;
    detectKts(...paths: string[]): boolean | null;
    detect(host?: T): boolean;
    get settings(): AndroidDocumentSettings;
}

export interface AndroidDocumentConstructor<T extends IFileManager<U>, U extends DocumentAsset = DocumentAsset> extends ConstructorDerived<DocumentConstructor<T, U>> {
    readonly prototype: IAndroidDocument<T, U>;
    new(module?: DocumentModule, ...args: unknown[]): IAndroidDocument<T, U>;
}