import {
    MutableTacticService,
    ServiceError,
    TacticContext,
} from "./MutableTacticService.ts"
import { StepContent, StepInfoNode } from "../model/tactic/Tactic.ts"
import { Fetcher } from "../app/Fetcher.ts"

export class APITacticService implements MutableTacticService {
    private readonly tacticId: number
    private readonly fetcher: Fetcher

    constructor(fetcher: Fetcher, tacticId: number) {
        this.tacticId = tacticId
        this.fetcher = fetcher
    }

    async canBeEdited(): Promise<boolean> {
        const response = await this.fetcher.fetchAPIGet(
            `tactics/${this.tacticId}/can-edit`,
        )
        const { canEdit } = await response.json()
        return canEdit
    }

    async getContext(): Promise<TacticContext | ServiceError> {
        const infoResponsePromise = this.fetcher.fetchAPIGet(
            `tactics/${this.tacticId}`,
        )
        const infoResponse = await infoResponsePromise

        const treeResponsePromise = this.fetcher.fetchAPIGet(
            `tactics/${this.tacticId}/tree`,
        )
        const treeResponse = await treeResponsePromise

        if (infoResponse.status == 401 || treeResponse.status == 401) {
            return ServiceError.UNAUTHORIZED
        }
        const { name, courtType } = await infoResponse.json()
        const { root } = await treeResponse.json()

        return { courtType, name, stepsTree: root }
    }

    async addStep(
        parent: StepInfoNode,
        content: StepContent,
    ): Promise<StepInfoNode | ServiceError> {
        const response = await this.fetcher.fetchAPI(
            `tactics/${this.tacticId}/steps`,
            {
                parentId: parent.id,
                content,
            },
        )
        if (response.status == 404) return ServiceError.NOT_FOUND
        if (response.status == 401) return ServiceError.UNAUTHORIZED

        const { stepId } = await response.json()
        return { id: stepId, children: [] }
    }

    async removeStep(id: number): Promise<void | ServiceError> {
        const response = await this.fetcher.fetchAPI(
            `tactics/${this.tacticId}/steps/${id}`,
            {},
            "DELETE",
        )
        if (response.status == 404) return ServiceError.NOT_FOUND
        if (response.status == 401) return ServiceError.UNAUTHORIZED
    }

    async setName(name: string): Promise<void | ServiceError> {
        const response = await this.fetcher.fetchAPI(
            `tactics/${this.tacticId}/name`,
            { name },
            "PUT",
        )
        if (response.status == 404) return ServiceError.NOT_FOUND
        if (response.status == 401) return ServiceError.UNAUTHORIZED
    }

    async saveContent(
        step: number,
        content: StepContent,
    ): Promise<void | ServiceError> {
        const response = await this.fetcher.fetchAPI(
            `tactics/${this.tacticId}/steps/${step}`,
            { content },
            "PUT",
        )
        if (response.status == 404) return ServiceError.NOT_FOUND
        if (response.status == 401) return ServiceError.UNAUTHORIZED
    }

    async getContent(step: number): Promise<StepContent | ServiceError> {
        const response = await this.fetcher.fetchAPIGet(
            `tactics/${this.tacticId}/steps/${step}`,
        )
        if (response.status == 404) return ServiceError.NOT_FOUND
        if (response.status == 401) return ServiceError.UNAUTHORIZED
        return await response.json()
    }
}
