import type { Meta, StoryObj } from '@storybook/react-vite'
import { useState } from 'react'

import { Badge } from '~/components/ui/badge'
import type { ComposerProps } from '~/features/chat/composer/views/composer-view'
import { ComposerView } from '~/features/chat/composer/views/composer-view'

import { newWorkWorkspaceFixtures } from './fixtures/new-work'
import { NewWorkBaseBranchControlView } from './new-work-base-branch-control-view'
import type { NewWorkFailureKind } from './new-work-error-view'
import { NewWorkPageView } from './new-work-page-view'
import { NewWorkWorkspaceSelectorView } from './new-work-workspace-selector-view'

type NewWorkStoryState
  = | 'ready'
    | 'adding-workspace'
    | 'workspace-menu-open'
    | 'base-branch-picker-open'
    | 'other-branch-selected'
    | 'loading-workspaces'
    | 'no-local-workspace'
    | 'dirty-source'
    | 'remote-base-unavailable'
    | 'create-failed'

function failureForState(
  state: NewWorkStoryState,
): NewWorkFailureKind | null {
  if (state === 'dirty-source') {
    return 'dirty-source'
  }
  if (state === 'remote-base-unavailable') {
    return 'remote-base-unavailable'
  }
  if (state === 'create-failed') {
    return 'generic'
  }
  return null
}

function NewWorkPageStoryScene({ state }: { state: NewWorkStoryState }) {
  const withoutWorkspaces = state === 'loading-workspaces'
    || state === 'no-local-workspace'
  const workspaces = withoutWorkspaces ? [] : newWorkWorkspaceFixtures
  const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<string | null>(
    workspaces[0]?.id ?? null,
  )
  const selectedWorkspace = workspaces.find(workspace => workspace.id === selectedWorkspaceId)
  const [selectedBaseBranch, setSelectedBaseBranch] = useState<string | null>(
    state === 'other-branch-selected' ? 'origin/develop' : null,
  )
  const [failureDismissed, setFailureDismissed] = useState(false)
  const [activity, setActivity] = useState('Ready to create Work')
  const failureKind = failureDismissed ? null : failureForState(state)
  const workspaceSelector = (
    <div className="flex min-w-0 items-center gap-1.5">
      <NewWorkWorkspaceSelectorView
        workspaces={workspaces}
        selectedWorkspaceId={selectedWorkspaceId}
        adding={state === 'adding-workspace'}
        defaultOpen={state === 'workspace-menu-open'}
        onSelectWorkspace={setSelectedWorkspaceId}
        onAddWorkspace={() => setActivity('Add project selected')}
      />
      {workspaces.length > 0
        ? (
            <NewWorkBaseBranchControlView
              currentBranch={selectedWorkspace?.gitIdentity?.branch ?? null}
              selectedBranch={selectedBaseBranch}
              defaultOpen={state === 'base-branch-picker-open'}
              branches={[
                { name: 'main', scope: 'local' },
                { name: 'develop', scope: 'local' },
                { name: 'origin/main', scope: 'remote' },
                { name: 'origin/develop', scope: 'remote' },
                { name: 'origin/release/next', scope: 'remote' },
              ]}
              onSelectBranch={(branch) => {
                setSelectedBaseBranch(branch)
                setActivity(branch ? `Base branch selected: ${branch}` : 'Current branch selected')
              }}
            />
          )
        : null}
    </div>
  )
  const composerProps: ComposerProps = {
    send: {
      submit: (text) => {
        setActivity(text.trim() ? 'Work creation requested' : 'Objective required')
        return true
      },
      label: 'Start Work',
      isSending: false,
      sendDisabled: workspaces.length === 0,
    },
    attachments: {
      supportsAttachments: true,
      acceptsNativeFiles: false,
    },
    slots: {
      toolbar: (
        <div className="flex items-center gap-2 px-1 text-xs text-muted-foreground">
          <Badge variant="secondary">Codex</Badge>
          <span>GPT-5.4</span>
        </div>
      ),
      contextBar: workspaceSelector,
      footer: <span className="text-[11px] text-muted-foreground">Managed Worktree</span>,
    },
    externalSignals: {
      replaceText: state === 'no-local-workspace' || state === 'loading-workspaces'
        ? ''
        : 'Refactor the remaining user-visible surfaces into fixture-driven Views.',
      replaceTextKey: 1,
    },
    view: {
      placeholder: 'Describe a concrete outcome for the agent...',
      textareaRows: 4,
    },
    testIds: {
      textarea: 'new-work-textarea',
      sendButton: 'new-work-send',
    },
    accessibility: {
      textareaAriaLabel: 'Work objective',
      sendButtonAriaLabel: 'Start Work',
    },
  }

  return (
    <main className="h-screen min-h-160 bg-muted/20 text-foreground">
      <NewWorkPageView
        composer={<ComposerView {...composerProps} />}
        workspaceCount={workspaces.length}
        loadingWorkspaces={state === 'loading-workspaces'}
        failureKind={failureKind}
        failureMessage={
          failureKind === 'generic'
            ? 'The server rejected the Work request. Review the selected runtime and try again.'
            : null
        }
        canOpenChanges={failureKind === 'dirty-source'}
        onOpenChanges={() => setActivity('Open Changes selected')}
        onDismissFailure={() => setFailureDismissed(true)}
      />
      <span className="sr-only" role="status">{activity}</span>
    </main>
  )
}

const meta = {
  title: 'App/New Work/Page',
  component: NewWorkPageStoryScene,
  parameters: {
    layout: 'fullscreen',
    controls: { disable: true },
  },
  args: {
    state: 'ready',
  },
} satisfies Meta<typeof NewWorkPageStoryScene>

export default meta

type Story = StoryObj<typeof meta>

export const Ready: Story = {}

export const AddingWorkspace: Story = {
  args: { state: 'adding-workspace' },
}

export const WorkspaceMenuOpen: Story = {
  args: { state: 'workspace-menu-open' },
}

export const BaseBranchPickerOpen: Story = {
  args: { state: 'base-branch-picker-open' },
}

export const OtherBranchSelected: Story = {
  args: { state: 'other-branch-selected' },
}

export const LoadingWorkspaces: Story = {
  args: { state: 'loading-workspaces' },
}

export const NoLocalWorkspace: Story = {
  args: { state: 'no-local-workspace' },
}

export const DirtySource: Story = {
  args: { state: 'dirty-source' },
}

export const RemoteBaseUnavailable: Story = {
  args: { state: 'remote-base-unavailable' },
}

export const CreateFailed: Story = {
  args: { state: 'create-failed' },
}
