import ForgejoKit
import Foundation

// Fake model instances for SwiftUI previews
#if DEBUG
    extension Repository {
        static let preview = Repository(
            id: 1,
            name: "test-repo",
            fullName: "testuser/test-repo",
            description: "A test repository",
            empty: false,
            private: false,
            fork: false,
            parent: nil,
            mirror: false,
            size: 1024,
            language: "Swift",
            languagesUrl: nil,
            htmlUrl: "",
            sshUrl: "",
            cloneUrl: "",
            website: nil,
            starsCount: 42,
            forksCount: 7,
            watchersCount: 10,
            openIssuesCount: 3,
            openPrCounter: 1,
            releaseCounter: 2,
            defaultBranch: "main",
            archived: false,
            createdAt: Date(),
            updatedAt: Date(),
            permissions: nil,
            hasIssues: true,
            internalTracker: nil,
            hasWiki: true,
            hasPullRequests: true,
            hasProjects: true,
            hasReleases: true,
            hasPackages: false,
            hasActions: true,
            template: false,
            avatarUrl: nil,
        )
    }

    extension User {
        static let preview = User(
            id: 1,
            login: "testuser",
            fullName: "Test User",
            email: "test@example.com",
            avatarUrl: nil,
            isAdmin: false,
            created: Date(),
        )

        static let previewBot = User(
            id: 2,
            login: "botuser",
            fullName: "Bot User",
            email: "bot@example.com",
            avatarUrl: nil,
            isAdmin: false,
            created: Date(),
        )
    }

    extension Commit {
        static let preview = Commit(
            sha: "abc123def456789",
            htmlUrl: "https://forgejo.example.com/testuser/test-repo/commit/abc123def456789",
            commit: CommitDetail(
                message: "Add new feature",
                author: CommitSignature(name: "Test User", email: "test@example.com", date: Date()),
                committer: CommitSignature(name: "Test User", email: "test@example.com", date: Date()),
            ),
            author: .preview,
        )
    }

    extension ForgejoInstance {
        static let preview = ForgejoInstance(
            serverURL: "https://forgejo.example.com",
            username: "testuser",
        )
    }

    extension IssueLabel {
        static let preview = IssueLabel(
            id: 1,
            name: "bug",
            color: "ee0701",
            description: "Something isn't working",
        )

        static let previewList: [IssueLabel] = [
            .preview,
            IssueLabel(
                id: 2,
                name: "enhancement",
                color: "0075ca",
                description: "New feature or request",
            ),
        ]
    }

    extension IssueMilestone {
        static let preview = IssueMilestone(
            id: 1,
            title: "v1.0",
            description: "First stable release",
            state: "open",
        )
    }

    extension Attachment {
        static let previewImage = Attachment(
            id: 1,
            uuid: "ee01801f-ffdb-4154-856b-77eab52aaad2",
            name: "screenshot.png",
            size: 222_208,
            browserDownloadUrl: "https://codeberg.org/attachments/ee01801f-ffdb-4154-856b-77eab52aaad2",
            type: "image/png",
            created: Date(),
        )

        static let previewFile = Attachment(
            id: 2,
            uuid: "abc12345-0000-0000-0000-000000000000",
            name: "report.pdf",
            size: 51200,
            browserDownloadUrl: "https://codeberg.org/attachments/abc12345-0000-0000-0000-000000000000",
            type: "application/pdf",
            created: Date(),
        )
    }

    extension IssueComment {
        static let preview = IssueComment(
            id: 1,
            body: "This looks good! I think we should also consider **edge cases** for empty input.",
            user: .preview,
            createdAt: Date(),
            updatedAt: Date(),
        )
    }

    extension Issue {
        static let preview = Issue(
            id: 1,
            number: 1,
            title: "Fix login crash on empty password",
            body: """
            The app crashes when the user submits the login form with an empty password.

            ## Steps to reproduce
            1. Open the app
            2. Enter a username
            3. Leave password empty
            4. Tap **Login**
            """,
            state: "open",
            user: .preview,
            labels: IssueLabel.previewList,
            milestone: .preview,
            assignees: [.preview],
            createdAt: Date().addingTimeInterval(-86400),
            updatedAt: Date(),
            comments: 2,
        )

        static let previewWithRepo = Issue(
            id: 1,
            number: 1,
            title: "Fix login crash on empty password",
            body: "The app crashes when the user submits the login form with an empty password.",
            state: "open",
            user: .preview,
            labels: IssueLabel.previewList,
            milestone: .preview,
            assignees: [.preview],
            createdAt: Date().addingTimeInterval(-86400),
            updatedAt: Date(),
            comments: 2,
            repository: .preview,
        )

        static let previewPullRequest = Issue(
            id: 10,
            number: 4,
            title: "Add dark mode support",
            body: "This PR adds dark mode support.",
            state: "open",
            user: .preview,
            labels: IssueLabel.previewList,
            createdAt: Date().addingTimeInterval(-86400),
            updatedAt: Date(),
            pullRequest: IssuePullRequest(merged: false),
            comments: 1,
            repository: .preview,
        )
    }

    extension PRBranchRef {
        static let previewHead = PRBranchRef(
            label: "testuser:feature-branch",
            ref: "feature-branch",
            sha: "abc123def456789",
            repo: PRRepo(id: 1, name: "test-repo", fullName: "testuser/test-repo"),
        )

        static let previewBase = PRBranchRef(
            label: "testuser:main",
            ref: "main",
            sha: "def456789abc123",
            repo: PRRepo(id: 1, name: "test-repo", fullName: "testuser/test-repo"),
        )
    }

    extension PullRequest {
        static let preview = PullRequest(
            id: 1,
            number: 4,
            title: "Add dark mode support",
            body: "This PR adds dark mode support to the app.\n\n- Updated color scheme\n- Added toggle in settings",
            state: "open",
            user: .preview,
            labels: IssueLabel.previewList,
            assignees: [.preview, .previewBot],
            head: .previewHead,
            base: .previewBase,
            mergeable: true,
            merged: false,
            requestedReviewers: [.previewBot],
            draft: false,
            comments: 1,
            createdAt: Date().addingTimeInterval(-86400),
            updatedAt: Date(),
        )
    }

    extension NotificationSubject {
        static let preview = NotificationSubject(
            type: "Issue",
            title: "Fix login crash on empty password",
            state: "open",
        )
    }

    extension NotificationThread {
        static let preview = NotificationThread(
            id: 1,
            unread: true,
            pinned: false,
            updatedAt: Date(),
            subject: .preview,
            repository: .preview,
        )

        static let previewList: [NotificationThread] = [
            .preview,
            NotificationThread(
                id: 2,
                unread: false,
                pinned: false,
                updatedAt: Date().addingTimeInterval(-3600),
                subject: NotificationSubject(
                    type: "Pull",
                    title: "Add dark mode support",
                    state: "open",
                ),
                repository: .preview,
            ),
        ]
    }

    extension PullRequestReview {
        static let preview = PullRequestReview(
            id: 1,
            body: "Looks good overall, just a few minor suggestions.",
            user: .previewBot,
            state: "APPROVED",
            commentsCount: 1,
            submittedAt: Date(),
        )
    }

    extension ReviewComment {
        static let preview = ReviewComment(
            id: 1,
            body: "Consider using a guard statement here instead.",
            user: .previewBot,
            path: "README.md",
            diffHunk: "@@ -1,3 +1,4 @@\n # Test Repo\n+Some new line",
            createdAt: Date(),
            updatedAt: Date(),
        )
    }

    extension ParsedDiff {
        static let preview = ParsedDiff(
            files: [
                DiffFile(
                    oldName: "README.md",
                    newName: "README.md",
                    hunks: [
                        DiffHunk(
                            header: "@@ -1,5 +1,6 @@",
                            lines: [
                                DiffLine(
                                    type: .context, content: " # Test Repo",
                                    oldLineNumber: 1, newLineNumber: 1, diffPosition: 1,
                                ),
                                DiffLine(
                                    type: .context, content: " ",
                                    oldLineNumber: 2, newLineNumber: 2, diffPosition: 2,
                                ),
                                DiffLine(
                                    type: .deletion, content: "-Old description",
                                    oldLineNumber: 3, newLineNumber: nil, diffPosition: 3,
                                ),
                                DiffLine(
                                    type: .addition, content: "+New and improved description",
                                    oldLineNumber: nil, newLineNumber: 3, diffPosition: 4,
                                ),
                                DiffLine(
                                    type: .context, content: " ",
                                    oldLineNumber: 4, newLineNumber: 4, diffPosition: 5,
                                ),
                                DiffLine(
                                    type: .addition, content: "+Added a new line",
                                    oldLineNumber: nil, newLineNumber: 5, diffPosition: 6,
                                ),
                            ],
                        ),
                    ],
                ),
            ],
        )
    }

    extension Branch {
        static let preview = Branch(
            name: "main",
            commit: BranchCommit(id: "abc123", message: "Initial commit", url: ""),
            protected: true,
        )

        static let previewList: [Branch] = [
            .preview,
            Branch(
                name: "feature-branch",
                commit: BranchCommit(id: "def456", message: "Add feature", url: ""),
                protected: false,
            ),
            Branch(
                name: "develop",
                commit: BranchCommit(id: "789abc", message: "Merge develop", url: ""),
                protected: false,
            ),
        ]
    }

    extension AuthenticationService {
        static let previewDefault: AuthenticationService = .preview(
            user: .preview,
            instance: .preview,
        )
    }
#endif
