# ----------------------------------------------------------------
# Scenario 3: One-Click Project Initialization
# Flow: Input description -> Create repo -> Generate files (README/LICENSE/
#        CONTRIBUTING/CI) -> Push to repo -> Milestones -> Issues ->
#        Branch protection -> Initial Release
#
# Commands chained:
#   1. repo +create        -- create repository
#   2. git clone           -- clone the empty repo locally
#   3. file generation     -- README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml
#   4. git add/commit/push -- push scaffold files to repo
#   5. milestone +create   -- create project milestones
#   6. issue +create       -- create initial issues
#   7. branch +protect     -- protect default branch
#   8. release +create     -- create initial release
# ----------------------------------------------------------------
#Requires -Version 5.1

param(
    [string]$Owner = "",
    [string]$Name = "",
    [string]$Description = "",
    [string]$Lang = "go",
    [switch]$Private,
    [switch]$DryRun,
    [switch]$Help
)

$ErrorActionPreference = "Stop"
Import-Module "$PSScriptRoot/lib/common.psm1" -Force -WarningAction SilentlyContinue

if ($Help) {
    Write-Host "Usage: powershell 03-project-init.ps1 -Owner OWNER -Name REPO_NAME -Description DESC [-Lang go|python|node|java] [-Private] [-DryRun]"
    exit 0
}

if (-not $Name)        { Log-Err "Name is required (use -Help for usage)"; exit 1 }
if (-not $Description) { Log-Err "Description is required (use -Help for usage)"; exit 1 }

Check-Auth
if (-not $Owner) {
    $detected = Detect-OwnerRepo
    $Owner = $detected.Owner
}

# ----------------------------------------------------------------
Log-Title "Project Initialization: $Owner/$Name"
# ----------------------------------------------------------------
Write-Host "  Owner:       $Owner"
Write-Host "  Name:        $Name"
Write-Host "  Description: $Description"
Write-Host "  Language:    $Lang"
Write-Host "  Private:     $($Private.IsPresent)"
Divider

# -- Step 1: Create Repository --
Log-Step "Step 1/8: Creating repository..."
if ($DryRun) {
    Log-Warn "[DRY RUN] Would create repository: $Owner/$Name"
} else {
    $privateStr = if ($Private) { "true" } else { "false" }
    $repoResult = Invoke-GLCheck "repo", "+create", "--owner", $Owner, "--name", $Name, "--description", $Description, "--private", $privateStr
    if ($repoResult) {
        Log-Ok "Repository created: $Owner/$Name"
    } else {
        Log-Err "Repository creation failed"
        exit 1
    }
}

# -- Step 2: Clone empty repo --
Log-Step "Step 2/8: Cloning repository..."
$repoUrl = "https://gitlink.org.cn/$Owner/$Name.git"
if ($env:GITLINK_TOKEN) {
    $cloneUrl = "https://oauth2:$($env:GITLINK_TOKEN)@gitlink.org.cn/$Owner/$Name.git"
} else {
    $cloneUrl = $repoUrl
}
$workDir = Join-Path $env:TEMP "gitlink-init-$([System.Guid]::NewGuid().ToString('N').Substring(0, 8))"

if ($DryRun) {
    Log-Warn "[DRY RUN] Would clone: $repoUrl -> $workDir"
} else {
    git clone $cloneUrl $workDir 2>&1 | Select-Object -Last 1
    Log-Ok "Cloned to $workDir"
}

# -- Step 3: Generate project files --
Log-Step "Step 3/8: Generating project scaffold files..."

function Get-ReadmeContent {
    $langSection = switch ($Lang) {
        "go" {
@"
### 环境要求

- Go 1.21+
- Git

### 安装

```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
go mod download
go build ./...
```

### 使用

```bash
go run main.go
```

### 测试

```bash
go test ./...
```
"@
        }
        "python" {
@"
### 环境要求

- Python 3.9+
- pip

### 安装

```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
pip install -r requirements.txt
```

### 使用

```bash
python main.py
```

### 测试

```bash
pytest
```
"@
        }
        "node" {
@"
### 环境要求

- Node.js 18+
- npm or yarn

### 安装

```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
npm install
```

### 使用

```bash
npm start
```

### 测试

```bash
npm test
```
"@
        }
        "java" {
@"
### 环境要求

- JDK 17+
- Maven 3.8+

### 安装

```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
mvn clean install
```

### 使用

```bash
mvn exec:java
```

### 测试

```bash
mvn test
```
"@
        }
        default { "" }
    }

    return @"
# $Name

$Description

## 快速开始

$langSection

## 贡献指南

详见 [CONTRIBUTING](./CONTRIBUTING.md)。

## 许可证

本项目基于 MIT 许可证开源 — 详见 [LICENSE](./LICENSE)。
"@
}

function Get-LicenseContent {
    $year = (Get-Date).Year
    return @"
MIT License

Copyright (c) $year $Owner

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"@
}

function Get-ContributingContent {
    return @"
# Contributing to $Name

Thank you for your interest in contributing!

## How to Contribute

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-feature`
3. Make your changes
4. Run tests to ensure everything passes
5. Commit your changes: `git commit -m 'feat: add my feature'`
6. Push to your fork: `git push origin feature/my-feature`
7. Create a Pull Request

## Code Style

- Follow the existing code style
- Write meaningful commit messages following [Conventional Commits](https://www.conventionalcommits.org/)
- Add tests for new features
- Update documentation as needed

## Reporting Issues

- Use the [issue tracker](https://gitlink.org.cn/$Owner/$Name/issues)
- Include steps to reproduce
- Include environment details (OS, language version, etc.)

## Code of Conduct

Please be respectful and constructive in all interactions.
"@
}

function Get-CIConfigContent {
    switch ($Lang) {
        "go" {
            return @"
image: golang:1.21

stages:
  - test
  - build

test:
  stage: test
  script:
    - go mod download
    - go test ./... -v -cover

build:
  stage: build
  script:
    - go build ./...
"@
        }
        "python" {
            return @"
image: python:3.9

stages:
  - test
  - lint

test:
  stage: test
  script:
    - pip install -r requirements.txt
    - pytest -v --cov

lint:
  stage: lint
  script:
    - pip install flake8
    - flake8 .
"@
        }
        "node" {
            return @"
image: node:18

stages:
  - test
  - build

test:
  stage: test
  script:
    - npm ci
    - npm test -- --coverage

build:
  stage: build
  script:
    - npm ci
    - npm run build
"@
        }
        "java" {
            return @"
image: maven:3.8-openjdk-17

stages:
  - test
  - build

test:
  stage: test
  script:
    - mvn test

build:
  stage: build
  script:
    - mvn package -DskipTests
"@
        }
        default {
            return "# TODO: configure CI/CD pipeline for $Lang"
        }
    }
}

if ($DryRun) {
    Log-Warn "[DRY RUN] Would generate: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
} else {
    $utf8 = [System.Text.UTF8Encoding]::new($false)
    [System.IO.File]::WriteAllText("$workDir\README.md", (Get-ReadmeContent), $utf8)
    [System.IO.File]::WriteAllText("$workDir\LICENSE", (Get-LicenseContent), $utf8)
    [System.IO.File]::WriteAllText("$workDir\CONTRIBUTING.md", (Get-ContributingContent), $utf8)
    [System.IO.File]::WriteAllText("$workDir\.gitlink-ci.yml", (Get-CIConfigContent), $utf8)
    Log-Ok "Generated: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
}

# -- Step 4: Push files to repo --
Log-Step "Step 4/8: Pushing scaffold files to repository..."
if ($DryRun) {
    Log-Warn "[DRY RUN] Would git add/commit/push to $repoUrl"
} else {
    Push-Location $workDir
    try {
        $commitMsg = "chore: initialize project scaffold`n`n- Add README.md with getting-started guide`n- Add MIT LICENSE`n- Add CONTRIBUTING.md with guidelines`n- Add .gitlink-ci.yml CI pipeline configuration"
        git add README.md LICENSE CONTRIBUTING.md .gitlink-ci.yml 2>&1 | Out-Null
        git -c user.name="$Owner" -c user.email="$Owner@gitlink.org.cn" commit -m $commitMsg 2>&1 | Select-Object -Last 1
        git push -u origin master 2>&1 | Select-Object -Last 1
        Log-Ok "Scaffold files pushed to master"
    } finally {
        Pop-Location
    }
}

# -- Step 5: Create Milestones --
Log-Step "Step 5/8: Creating initial milestone..."

$milestones = @(
    @{ Name = "v1.0.0 - First Release"; Description = "First official release milestone" }
)

if ($DryRun) {
    Log-Warn "[DRY RUN] Would create $($milestones.Count) milestones"
} else {
    foreach ($ms in $milestones) {
        $msResult = Invoke-GL "milestone", "+create", "--owner", $Owner, "--repo", $Name, "--name", $ms.Name, "--description", $ms.Description
        if ($msResult) {
            try {
                $msJson = $msResult | ConvertFrom-Json
                if ($msJson.ok) {
                    Log-Ok "Milestone created: $($ms.Name)"
                } else {
                    Log-Warn "Milestone creation failed: $($ms.Name)"
                }
            } catch {
                Log-Warn "Milestone creation may have failed: $($ms.Name)"
            }
        }
    }
}

# -- Step 6: Create Initial Issues --
Log-Step "Step 6/8: Creating welcome issue..."

$issuesToCreate = @(
    @{ Title = "Welcome to $Name"; Body = "欢迎来到 **${Name}** 的仓库，这是本仓库的第一条issue！！"; Label = "welcome" }
)

if ($DryRun) {
    Log-Warn "[DRY RUN] Would create $($issuesToCreate.Count) initial issues"
} else {
    foreach ($entry in $issuesToCreate) {
        $issueResult = Invoke-GL "issue", "+create", "--owner", $Owner, "--repo", $Name, "--title", $entry.Title, "--body", $entry.Body
        if ($issueResult) {
            try {
                $issueJson = $issueResult | ConvertFrom-Json
                $issueNum = if ($issueJson.ok -and $issueJson.data.id) { $issueJson.data.id } elseif ($issueJson.ok -and $issueJson.data.number) { $issueJson.data.number } else { $null }
                if ($issueNum) {
                    Invoke-GL "issue", "+label-add", "--owner", $Owner, "--repo", $Name, "--number", $issueNum, "--labels", $entry.Label | Out-Null
                    Log-Ok "Issue created: #$issueNum - $($entry.Title)"
                }
            } catch {
                Log-Warn "Issue creation may have failed: $($entry.Title)"
            }
        }
    }
}

# -- Step 7: Protect Default Branch --
Log-Step "Step 7/8: Protecting master branch..."
if ($DryRun) {
    Log-Warn "[DRY RUN] Would protect branch 'master'"
} else {
    $protectResult = Invoke-GL "branch", "+protect", "--owner", $Owner, "--repo", $Name, "--name", "master"
    if ($protectResult) {
        try {
            $protectJson = $protectResult | ConvertFrom-Json
            if ($protectJson.ok) {
                Log-Ok "Branch 'master' protected"
            } else {
                Log-Warn "Branch protection may have failed (may require admin permissions)"
            }
        } catch {
            Log-Warn "Branch protection may have failed (may require admin permissions)"
        }
    }
}

# -- Step 8: Create Initial Release --
Log-Step "Step 8/8: Creating initial release v0.1.0..."

$releaseBody = @"
# v0.1.0 - Initial Release

## What's New
- Project initialized with $Lang template
- README, LICENSE, CONTRIBUTING guide in repository
- CI/CD pipeline configuration (`.gitlink-ci.yml`)
- $($milestones.Count) project milestone created
- $($issuesToCreate.Count) initial issues filed
- Branch protection enabled

## Next Steps
- [ ] Setup CI/CD pipeline
- [ ] Write comprehensive tests
- [ ] Complete documentation
- [ ] First feature implementation

---
*Auto-initialized by gitlink-cli project-init workflow*
"@

if ($DryRun) {
    Log-Warn "[DRY RUN] Would create release v0.1.0"
} else {
    $releaseResult = Invoke-GL "release", "+create", "--owner", $Owner, "--repo", $Name, "--tag", "v0.1.0", "--name", "Initial Release", "--body", $releaseBody
    if ($releaseResult) {
        try {
            $releaseJson = $releaseResult | ConvertFrom-Json
            if ($releaseJson.ok) {
                Log-Ok "Release v0.1.0 created"
            } else {
                Log-Warn "Release creation may have failed"
            }
        } catch {
            Log-Warn "Release creation may have failed"
        }
    }
}

# ----------------------------------------------------------------
Log-Title "Project Initialization Complete"
# ----------------------------------------------------------------

Write-Host "  Repository:     $Owner/$Name" -ForegroundColor Green
Write-Host "  Files:          README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml" -ForegroundColor Green
Write-Host "  Milestones:     $($milestones.Count) milestone" -ForegroundColor Green
Write-Host "  Issues:         $($issuesToCreate.Count) initial issues" -ForegroundColor Green
Write-Host "  Branch:         master (protected)" -ForegroundColor Green
Write-Host "  Release:        v0.1.0" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:" -ForegroundColor Cyan
Write-Host "  1. Clone: git clone $repoUrl"
Write-Host "  2. Start coding and close the first issue"
Write-Host "  3. CI/CD will trigger on your first push"

# Cleanup temp directory
if (-not $DryRun -and (Test-Path $workDir)) {
    Remove-Item -Recurse -Force $workDir -ErrorAction SilentlyContinue
}
