"""asa init — Initialize a new ASA project."""

import sys
from pathlib import Path

import typer

from ..core import logging as log
from ..core.config import AsaConfig, save_config
from ..core.fs import ensure_directory, safe_write_file


def run_init(name: str | None = None) -> None:
    """Initialize a new ASA project with runnable Next.js App Router starter.

    After `asa init && npm install && npm run dev` the project must run.
    """
    project_dir = Path.cwd()
    config_path = project_dir / "asa.config.json"

    if config_path.exists():
        log.error(f"ASA project already initialized at {project_dir}")
        raise typer.Exit(1)

    project_name = name or project_dir.name

    # 1. asa.config.json
    config = AsaConfig(name=project_name)
    save_config(config, project_dir)
    log.detail(f"Created: asa.config.json")

    # 2. directories
    ensure_directory(project_dir / "domains")
    log.detail("Created: domains/")
    ensure_directory(project_dir / "shared")
    log.detail("Created: shared/")
    ensure_directory(project_dir / "app")
    log.detail("Created: app/")

    # 3. package.json
    safe_write_file(project_dir / "package.json", _package_json(project_name))
    log.detail("Created: package.json")

    # 4. next.config.ts
    safe_write_file(project_dir / "next.config.ts", _next_config())
    log.detail("Created: next.config.ts")

    # 5. tsconfig.json
    safe_write_file(project_dir / "tsconfig.json", _tsconfig())
    log.detail("Created: tsconfig.json")

    # 6. tailwind.config.ts
    safe_write_file(project_dir / "tailwind.config.ts", _tailwind_config())
    log.detail("Created: tailwind.config.ts")

    # 7. postcss.config.mjs
    safe_write_file(project_dir / "postcss.config.mjs", _postcss_config())
    log.detail("Created: postcss.config.mjs")

    # 8. app/layout.tsx (developer-owned, CLI never overwrites)
    safe_write_file(project_dir / "app" / "layout.tsx", _layout(project_name))
    log.detail("Created: app/layout.tsx")

    # 9. app/page.tsx (developer-owned)
    safe_write_file(project_dir / "app" / "page.tsx", _page(project_name))
    log.detail("Created: app/page.tsx")

    # 10. app/globals.css
    safe_write_file(project_dir / "app" / "globals.css", _globals_css())
    log.detail("Created: app/globals.css")

    # 11. .env.example
    safe_write_file(project_dir / ".env.example", "# ASA project environment variables\n")
    log.detail("Created: .env.example")

    # 12. .cursorrules
    safe_write_file(project_dir / ".cursorrules", _cursorrules())
    log.detail("Created: .cursorrules")

    # 13. .gitignore
    safe_write_file(project_dir / ".gitignore", _gitignore())
    log.detail("Created: .gitignore")

    # 14. .asa/spec.yaml (desired architecture state)
    safe_write_file(project_dir / ".asa" / "spec.yaml", _spec_yaml(project_name))
    log.detail("Created: .asa/spec.yaml")

    log.success(f"ASA project initialized: {project_name}")


def _package_json(name: str) -> str:
    import json
    pkg = {
        "name": name,
        "version": "0.1.0",
        "private": True,
        "scripts": {
            "dev": "next dev",
            "build": "next build",
            "start": "next start",
            "lint": "next lint",
        },
        "dependencies": {
            "next": "^15.0.0",
            "react": "^19.0.0",
            "react-dom": "^19.0.0",
            "zod": "^3.23.0",
        },
        "devDependencies": {
            "typescript": "^5.6.0",
            "@types/node": "^22.0.0",
            "@types/react": "^19.0.0",
            "@types/react-dom": "^19.0.0",
            "tailwindcss": "^4.0.0",
            "@tailwindcss/postcss": "^4.0.0",
            "postcss": "^8.4.0",
        },
    }
    return json.dumps(pkg, indent=2, ensure_ascii=False) + "\n"


def _next_config() -> str:
    return """import type { NextConfig } from 'next';

const nextConfig: NextConfig = {};

export default nextConfig;
"""


def _tsconfig() -> str:
    return """{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [{ "name": "next" }],
    "paths": {
      "@/*": ["./*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}
"""


def _tailwind_config() -> str:
    return """import type { Config } from 'tailwindcss';

const config: Config = {
  content: [
    './app/**/*.{ts,tsx}',
    './domains/**/*.{ts,tsx}',
    './shared/**/*.{ts,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

export default config;
"""


def _postcss_config() -> str:
    return """export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};
"""


def _layout(name: str) -> str:
    return f"""import type {{ Metadata }} from 'next';
import './globals.css';

export const metadata: Metadata = {{
  title: '{name}',
  description: 'Built with ASA architecture',
}};

export default function RootLayout({{
  children,
}}: {{
  children: React.ReactNode;
}}) {{
  return (
    <html lang="en">
      <body>{{children}}</body>
    </html>
  );
}}
"""


def _page(name: str) -> str:
    return f"""export default function HomePage() {{
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      <h1 className="text-4xl font-bold">{name}</h1>
      <p className="mt-4 text-gray-600">Built with ASA architecture</p>
    </main>
  );
}}
"""


def _globals_css() -> str:
    return """@import 'tailwindcss';
"""


def _cursorrules() -> str:
    return """# ASA Architecture Rules for AI Tools

## Boundary Rules
- NEVER import from other domains (domains/X cannot import from domains/Y)
- ALWAYS use shared/ for cross-domain code
- Each slice is a vertical unit: handler + repository + schemas + UI
- Business logic belongs in domains/, not in app/

## File Ownership
- app/api/**/route.ts — ASA runtime adapters (DO NOT EDIT)
- app/**/page.tsx — ASA runtime adapters (DO NOT EDIT)
- app/layout.tsx — Developer-owned (safe to edit)
- domains/**/* — Slice files with ASA markers (edit only USER CODE sections)
- shared/**/* — Cross-domain utilities

## ASA Markers
- Code between `// --- ASA GENERATED START ---` and `// --- ASA GENERATED END ---` is auto-generated. DO NOT EDIT.
- Code between `// --- USER CODE START ---` and `// --- USER CODE END ---` is your code. SAFE TO EDIT.

## Naming
- Slice directories: kebab-case (e.g., reset-password/)
- Components: PascalCase (e.g., AuthLoginForm.tsx)
- Hooks: camelCase with use prefix (e.g., useAuthLogin)
- DB tables: snake_case
- Env vars: SCREAMING_SNAKE_CASE
"""


def _spec_yaml(name: str) -> str:
    return f"""# ASA Architecture Spec v0.1
# This file declares the desired architecture state for your project.
# Edit this file to match your project's actual configuration.

asa:
  spec_version: "0.1"

app:
  name: "{name}"
  mode: "greenfield"
  framework: "nextjs"
  runtime: "vercel"

providers:
  auth: "supabase"
  database: "supabase-postgres"
  billing: "stripe"

tenancy:
  principal: "user"
  tenant_key: "user_id"

domains:
  foundation:
    - "auth"
    - "billing"
    - "entitlements"
  business: []
  # Add your business domains here, e.g.:
  # - "invoices"
  # - "projects"

rules:
  no_auth_in_ui: true
  no_stripe_outside_billing: true
  no_direct_db_from_ui: true
  no_supabase_admin_outside_server: true

auth:
  session_source: "supabase"
  user_entity: "profiles"
  guard_api:
    - "requireUser"
    - "requireRole"

billing:
  provider: "stripe"
  webhook_source_of_truth: true
  plans:
    - key: "free"
    - key: "pro"

entitlements:
  source_of_truth: "database"
  features: []
  limits: []
  # Add your features and limits here, e.g.:
  # features:
  #   - key: "csv_export"
  #     type: "boolean"
  #     default: false
  # limits:
  #   - key: "max_invoices_per_month"
  #     type: "number"
  #     default: 5
  guard_api:
    - "requireEntitlement"
    - "requireLimit"

data_access:
  rls_required: true
  ownership_model: "user-scoped"
  forbidden_imports:
    - "@supabase/supabase-js in ui"
    - "stripe in ui"
"""


def _gitignore() -> str:
    return """node_modules/
.next/
.env
.env.local
*.tsbuildinfo
next-env.d.ts
"""
