import mimetypes
import os
import urllib.parse
from datetime import datetime
from pathlib import Path
from urllib.parse import quote, unquote

from aiohttp import web

from snek.system.view import BaseView


class DriveView(BaseView):

    login_required = True

    async def get(self):
        target = await self.services.user.get_home_folder(self.session.get("uid"))
        rel_path = self.request.match_info.get("rel_path", "")
        if rel_path:
            target = target.joinpath(rel_path)

        if not target.exists():
            return web.HTTPNotFound(reason="Path not found")

        if target.is_dir():
            return await self.render_template("drive.html", {"path": rel_path})
        if target.is_file():
            return web.FileResponse(target)


class DriveApiView(BaseView):

    login_required = True

    async def get_target(self):
        target = await self.services.user.get_home_folder(self.session.get("uid"))
        return target

    async def get_download_url(self, rel):
        return f"/drive/{urllib.parse.quote(rel)}"

    async def get(self):
        target = await self.get_target()
        original_target = target 
        rel = self.request.query.get("path", "")
        offset = int(self.request.query.get("offset", 0))
        limit = int(self.request.query.get("limit", 20))

        if rel:
            target = target.joinpath(rel)

        if not target.exists():
            return web.json_response({"error": "Not found"}, status=404)

        if not target.relative_to(original_target):
            return web.json_response({"error": "Not found"}, status=404)

        if target.is_dir():
            entries = []
            for p in sorted(
                target.iterdir(), key=lambda p: (p.is_file(), p.name.lower())
            ):
                item_path = (Path(rel) / p.name).as_posix()
                mime = (
                    mimetypes.guess_type(p.name)[0]
                    if p.is_file()
                    else "inode/directory"
                )
                url = (
                    self.request.url.with_path(
                        f"/drive/{urllib.parse.quote(item_path)}"
                    )
                    if p.is_file()
                    else None
                )
                entries.append(
                    {
                        "name": p.name,
                        "type": "directory" if p.is_dir() else "file",
                        "mimetype": mime,
                        "size": p.stat().st_size if p.is_file() else None,
                        "path": item_path,
                        "url": url,
                    }
                )
            import json

            total = len(entries)
            items = entries[offset : offset + limit]
            return web.json_response(
                {
                    "items": json.loads(json.dumps(items, default=str)),
                    "pagination": {"offset": offset, "limit": limit, "total": total},
                }
            )

        url = self.request.url.with_path(await self.get_download_url(rel))
        return web.json_response(
            {
                "name": target.name,
                "type": "file",
                "mimetype": mimetypes.guess_type(target.name)[0],
                "size": target.stat().st_size,
                "path": rel,
                "url": str(url),
            }
        )
