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>"
		)