import type { Meta, StoryObj } from '@storybook/react'
import { Home, Users, Settings, Key, Webhook, BarChart, Package, FileText } from 'lucide-react'
import { App } from '../components/app'
import { AppShell } from '../components/app-shell'
import { NavMain } from '../components/nav-main'
import { NavUser } from '../components/nav-user'
import { AppBreadcrumbs } from '../components/app-breadcrumbs'
import type {
  DataProvider,
  AuthProvider as AuthProviderInterface,
  NavItem,
  ResourceDefinition,
  GetOneParams,
  CreateParams,
  UpdateParams,
  DeleteParams,
} from '../types'

// =============================================================================
// Mock Data Provider
// =============================================================================

const mockDataProvider: DataProvider = {
  getList: async <T = unknown>(resource: string) => {
    // Return mock data for demo purposes
    if (resource === 'users') {
      return {
        data: [
          { id: '1', name: 'John Doe', email: 'john@example.com' },
          { id: '2', name: 'Jane Smith', email: 'jane@example.com' },
        ] as T[],
        total: 2,
      }
    }
    return { data: [] as T[], total: 0 }
  },
  getOne: async <T = unknown>(_resource: string, params: GetOneParams) => {
    return { data: { id: params.id, name: 'Mock Record' } as T }
  },
  getMany: async <T = unknown>() => {
    return { data: [] as T[] }
  },
  create: async <T = unknown>(_resource: string, params: CreateParams<T>) => {
    return { data: { id: 'new-id', ...params.data } as T }
  },
  update: async <T = unknown>(_resource: string, params: UpdateParams<T>) => {
    return { data: { id: params.id, ...params.data } as T }
  },
  delete: async <T = unknown>(_resource: string, params: DeleteParams) => {
    return { data: { id: params.id } as T }
  },
}

// =============================================================================
// Mock Auth Provider
// =============================================================================

const mockAuthProvider: AuthProviderInterface = {
  login: async () => {},
  logout: async () => {},
  checkAuth: async () => {},
  checkError: async () => {},
  getIdentity: async () => ({
    id: '1',
    fullName: 'John Doe',
    email: 'john@example.com',
    avatar: 'https://github.com/shadcn.png',
  }),
  getPermissions: async () => ['admin'],
}

// =============================================================================
// Mock Navigation Items
// =============================================================================

const navItems: NavItem[] = [
  { title: 'Dashboard', url: '/admin', icon: Home },
  { title: 'Users', url: '/admin/users', icon: Users },
  { title: 'API Keys', url: '/admin/api-keys', icon: Key },
  {
    title: 'Webhooks',
    url: '/admin/webhooks',
    icon: Webhook,
    items: [
      { title: 'Endpoints', url: '/admin/webhooks/endpoints' },
      { title: 'Logs', url: '/admin/webhooks/logs' },
    ],
  },
  { title: 'Analytics', url: '/admin/analytics', icon: BarChart },
  { title: 'Settings', url: '/admin/settings', icon: Settings },
]

// =============================================================================
// Mock Resources
// =============================================================================

const UsersListMock = () => (
  <div className="p-6">
    <h2 className="text-xl font-semibold">Users List</h2>
    <p className="text-muted-foreground">Mock users list component</p>
  </div>
)

const ProductsListMock = () => (
  <div className="p-6">
    <h2 className="text-xl font-semibold">Products List</h2>
    <p className="text-muted-foreground">Mock products list component</p>
  </div>
)

const mockResources: ResourceDefinition[] = [
  {
    name: 'users',
    label: 'User',
    labelPlural: 'Users',
    icon: Users,
    list: UsersListMock,
  },
  {
    name: 'products',
    label: 'Product',
    labelPlural: 'Products',
    icon: Package,
    list: ProductsListMock,
  },
]

// =============================================================================
// Story Meta
// =============================================================================

const meta: Meta<typeof App> = {
  title: 'App/App',
  component: App,
  tags: ['autodocs'],
  parameters: {
    layout: 'fullscreen',
  },
}

export default meta
type Story = StoryObj<typeof App>

// =============================================================================
// Stories
// =============================================================================

/**
 * The App component is the root provider that sets up all necessary contexts.
 * It wraps the application with Theme, Navigation, Data, Auth, and Resource providers.
 */
export const Default: Story = {
  args: {
    config: {
      name: 'Admin',
      description: 'Dashboard',
      basePath: '/admin',
    },
    dataProvider: mockDataProvider,
    authProvider: mockAuthProvider,
  },
  render: (args) => (
    <App {...args}>
      <AppShell
        config={args.config}
        nav={<NavMain items={navItems} label="Platform" currentPath="/admin" />}
        footer={<NavUser accountPath="/admin/settings" billingPath="/admin/settings/billing" />}
        pageHeader={<AppBreadcrumbs basePath="/admin" />}
      >
        <div className="p-6">
          <h1 className="text-2xl font-bold">Dashboard</h1>
          <p className="text-muted-foreground mt-2">Welcome to the admin dashboard.</p>
        </div>
      </AppShell>
    </App>
  ),
}

/**
 * App with resources defined. Resources are automatically converted to navigation items.
 */
export const WithResources: Story = {
  args: {
    config: {
      name: 'Admin',
      description: 'Resource Management',
      basePath: '/admin',
    },
    dataProvider: mockDataProvider,
    authProvider: mockAuthProvider,
    resources: mockResources,
  },
  render: (args) => (
    <App {...args}>
      <AppShell
        config={args.config}
        nav={<NavMain items={navItems} label="Platform" currentPath="/admin/users" />}
        footer={<NavUser accountPath="/admin/settings" billingPath="/admin/settings/billing" />}
        pageHeader={
          <AppBreadcrumbs
            items={[
              { label: 'Dashboard', href: '/admin' },
              { label: 'Users' },
            ]}
          />
        }
      >
        <div className="p-6">
          <h1 className="text-2xl font-bold">Users</h1>
          <p className="text-muted-foreground mt-2">
            Resources defined: {args.resources?.map((r) => r.name).join(', ')}
          </p>
        </div>
      </AppShell>
    </App>
  ),
}

/**
 * App with custom logo in the configuration.
 */
export const WithCustomLogo: Story = {
  args: {
    config: {
      name: 'My App',
      description: 'Custom Branding',
      basePath: '/app',
      logo: (
        <div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-purple-600 text-white">
          <FileText className="size-4" />
        </div>
      ),
    },
    dataProvider: mockDataProvider,
    authProvider: mockAuthProvider,
  },
  render: (args) => (
    <App {...args}>
      <AppShell
        config={args.config}
        nav={<NavMain items={navItems} label="Platform" currentPath="/app" />}
        footer={<NavUser accountPath="/app/settings" billingPath="/app/settings/billing" />}
        pageHeader={<AppBreadcrumbs basePath="/app" />}
      >
        <div className="p-6">
          <h1 className="text-2xl font-bold">My App Dashboard</h1>
          <p className="text-muted-foreground mt-2">App with custom logo and branding.</p>
        </div>
      </AppShell>
    </App>
  ),
}

/**
 * Minimal App setup without shell - shows just the provider composition.
 */
export const MinimalSetup: Story = {
  args: {
    config: {
      name: 'Minimal',
      basePath: '/',
    },
    dataProvider: mockDataProvider,
    authProvider: mockAuthProvider,
  },
  render: (args) => (
    <App {...args}>
      <div className="flex min-h-screen items-center justify-center">
        <div className="text-center">
          <h1 className="text-2xl font-bold">Minimal App Setup</h1>
          <p className="text-muted-foreground mt-2">
            App provides context - you build the UI.
          </p>
          <p className="text-muted-foreground mt-1 text-sm">
            Config: {args.config.name} at {args.config.basePath}
          </p>
        </div>
      </div>
    </App>
  ),
}
