from __future__ import annotations

import os
import tempfile
import zipfile
from pathlib import Path

from pygitweb.api.project import Project
from pygitweb.tasks import create_board_for_project


class ProjectZip(Project):
    def __init__(
        self,
        path: os.PathLike[str] | str,
        zip_content: bytes,
        create_task_board: bool = False,
        do_maintenance: bool = False,
    ) -> None:
        self.path: str = str(Path(path))
        with tempfile.TemporaryDirectory() as tmpdir:
            zip_path = os.path.join(tmpdir, "repo.zip")
            with open(zip_path, "wb") as file_obj:
                file_obj.write(zip_content)
            with zipfile.ZipFile(zip_path, "r") as zip_file:
                zip_file.extractall(tmpdir)
            repo_root: str = self._discover_repo_root(tmpdir)
            super().__init__(
                path=self.path,
                remote_url=repo_root,
                create_task_board=False,
                do_maintenance=do_maintenance,
            )
        if create_task_board:
            create_board_for_project(Path(self.path).name, name="Tasks", description="")

    @staticmethod
    def _discover_repo_root(tmpdir: str) -> str:
        for name in os.listdir(tmpdir):
            if name == "repo.zip":
                continue
            candidate = os.path.join(tmpdir, name)
            if os.path.isdir(candidate) and os.path.isdir(os.path.join(candidate, ".git")):
                return candidate
        if os.path.isdir(os.path.join(tmpdir, ".git")):
            return tmpdir
        subdirs: list[str] = [
            name for name in os.listdir(tmpdir) if name != "repo.zip" and os.path.isdir(os.path.join(tmpdir, name))
        ]
        if len(subdirs) == 1:
            return os.path.join(tmpdir, subdirs[0])
        for name in os.listdir(tmpdir):
            if name != "repo.zip":
                candidate = os.path.join(tmpdir, name)
                if os.path.isdir(candidate):
                    return candidate
        return tmpdir

    @classmethod
    def form_content(cls) -> str:
        return (
            '<label class="form-label" for="repo_zip">Upload .zip (git repo)</label>'
            '<div class="dropzone border rounded p-4 text-center" id="dropzone" style="min-height: 120px;">'
            '<input type="file" class="form-control d-none" id="repo_zip" name="repo_zip" accept=".zip" '
            "data-dropzone-target>"
            '<div class="dropzone-placeholder text-muted" data-dropzone-placeholder>'
            "Drag a .zip file here or click to choose."
            "</div>"
            '<div class="dropzone-filename d-none text-start small mt-2" data-dropzone-filename></div>'
            "</div>"
        )