import React from 'react';
import { Button, Checkbox, Input, Paragraph, ScrollView, Text, XStack, YStack } from 'tamagui';
import { getIcon } from '../IconMapper.jsx';
import { useGridView } from './context.js';
import { formatValueByColumn } from './utils.js';
import { getTypographyRoleProps } from '../../styles/index.js';

function renderToolbarItem(item) {
  if (!item) {
    return null;
  }

  if (React.isValidElement(item)) {
    return item;
  }

  if (item.kind === 'button') {
    const IconComponent = item.icon ? getIcon(item.icon) : null;
    return (
      <Button
        key={item.key || item.label}
        size="$3"
        theme={item.theme}
        chromeless={item.chromeless}
        disabled={item.disabled}
        icon={IconComponent ? <IconComponent size="sm" /> : undefined}
        onPress={item.onClick || item.onPress}
      >
        {item.label}
      </Button>
    );
  }

  if (item.kind === 'text') {
    return (
      <Text key={item.key || item.text} color="$textSecondary">
        {item.text}
      </Text>
    );
  }

  if (item.kind === 'search') {
    const SearchIcon = getIcon('search');
    return (
      <XStack key={item.key || item.placeholder || 'search'} alignItems="center" gap="$2">
        {SearchIcon ? <SearchIcon size="sm" color="$textMuted" /> : null}
        <Input
          width={item.width || 240}
          value={item.value}
          placeholder={item.placeholder || 'Search'}
          onChangeText={(value) => item.onChange?.(value)}
          backgroundColor="$bgPanel"
          borderColor="$lineSubtle"
          focusStyle={{ borderColor: '$accent' }}
        />
      </XStack>
    );
  }

  if (item.kind === 'node') {
    return <React.Fragment key={item.key || 'node'}>{item.node}</React.Fragment>;
  }

  return <React.Fragment key={item.key || 'item'}>{item}</React.Fragment>;
}

function DefaultPanelRecordRenderer({ row }) {
  const grid = useGridView();
  const titleColumn =
    grid.resolvedColumns.find((column) =>
      ['customer', 'name', 'title', 'label'].includes(column.field)
    ) ||
    grid.resolvedColumns.find((column) => column.type === 'text') ||
    grid.resolvedColumns[0];
  const subtitleColumn = grid.resolvedColumns.find((column) =>
    ['description', 'region', 'owner', 'status'].includes(column.field)
  );
  const summaryColumns = grid.resolvedColumns.filter(
    (column) => ![titleColumn?.field, subtitleColumn?.field, 'description'].includes(column.field)
  );

  return (
    <YStack gap="$3">
      <YStack gap="$1">
        <Text fontSize="$2" letterSpacing={1} textTransform="uppercase" color="$textSecondary">
          Record Summary
        </Text>
        <Text {...getTypographyRoleProps('sectionTitle')}>
          {titleColumn ? row?.[titleColumn.field] : row?.id}
        </Text>
        {subtitleColumn ? (
          <Paragraph color="$textSecondary">
            {row?.[subtitleColumn.field] || ''}
          </Paragraph>
        ) : null}
      </YStack>

      <XStack gap="$2" flexWrap="wrap">
        {summaryColumns.slice(0, 3).map((column) => (
          <YStack
            key={`${row.id}-${column.field}-chip`}
            paddingHorizontal="$3"
            paddingVertical="$2"
            borderRadius="$radiusMd"
            backgroundColor="$bgPanel"
            borderWidth={1}
            borderColor="$lineSubtle"
          >
            <Text fontSize="$2" color="$textMuted">
              {column.label}
            </Text>
            <Text {...getTypographyRoleProps('tableHeader', { color: '$textPrimary' })}>
              {formatValueByColumn(row?.[column.field], column)}
            </Text>
          </YStack>
        ))}
      </XStack>

      <XStack gap="$3" flexWrap="wrap">
        {summaryColumns.map((column) => (
          <YStack
            key={`${row.id}-${column.field}`}
            minWidth={160}
            flex={1}
            padding="$3"
            borderRadius="$radiusMd"
            borderWidth={1}
            borderColor="$lineSubtle"
            backgroundColor="$bgPanel"
            gap="$1"
          >
            <Text fontSize="$3" color="$textMuted">
              {column.label}
            </Text>
            <Text color="$textPrimary">{formatValueByColumn(row?.[column.field], column)}</Text>
          </YStack>
        ))}
      </XStack>
    </YStack>
  );
}

export function PanelToolBar({ items = [], visible = true }) {
  if (visible === false) {
    return null;
  }

  return (
    <XStack gap="$2" alignItems="center" justifyContent="flex-end" flexWrap="wrap">
      {items.map((item, index) => (
        <React.Fragment key={item?.key || item?.label || item?.text || index}>
          {renderToolbarItem(item)}
        </React.Fragment>
      ))}
    </XStack>
  );
}

export function PanelFooterStatusBar({ text, visible = true }) {
  const grid = useGridView();
  if (visible === false) {
    return null;
  }

  return (
    <Text color="$textMuted">
      {text || grid.statusText}
    </Text>
  );
}

export function PanelHeader({ title, toolbarItems = [], visible = true, showDivider = true }) {
  const grid = useGridView();
  const RefreshIcon = getIcon('refresh');
  const CloseIcon = getIcon('close');

  if (visible === false) {
    return null;
  }

  return (
    <XStack
      alignItems="center"
      justifyContent="space-between"
      gap="$3"
      padding="$3"
      minHeight={64}
      borderBottomWidth={showDivider ? 1 : 0}
      borderBottomColor="$lineSubtle"
      backgroundColor="$bgPanel"
    >
      <Text {...getTypographyRoleProps('panelTitle', { fontSize: '$6' })}>
        {title}
      </Text>

      <XStack gap="$2" alignItems="center" flexWrap="wrap" justifyContent="flex-end">
        <PanelToolBar items={toolbarItems} />
        <Button
          size="$3"
          chromeless
          circular
          icon={RefreshIcon ? <RefreshIcon size="sm" color="$textSecondary" /> : undefined}
          onPress={grid.reload}
        />
        {grid.closeable !== false ? (
          <Button
            size="$3"
            chromeless
            circular
            disabled={!grid.close}
            icon={CloseIcon ? <CloseIcon size="sm" color="$textSecondary" /> : undefined}
            onPress={grid.close}
          />
        ) : null}
      </XStack>
    </XStack>
  );
}

export function PanelFooter({ toolbarItems = [], visible = true }) {
  if (visible === false) {
    return null;
  }

  return (
    <XStack
      alignItems="center"
      justifyContent="space-between"
      gap="$3"
      padding="$3"
      minHeight={56}
      borderTopWidth={1}
      borderTopColor="$lineSubtle"
      backgroundColor="$bgPanel"
      flexWrap="wrap"
    >
      <PanelFooterStatusBar />
      <PanelToolBar items={toolbarItems} />
    </XStack>
  );
}

export function PanelBodyView({
  visible = true,
  recordRenderer: RecordRenderer = DefaultPanelRecordRenderer,
  columns = 2
}) {
  const grid = useGridView();

  if (visible === false) {
    return null;
  }

  if (grid.error) {
    const ErrorIcon = getIcon('error');
    return (
      <YStack flex={1} alignItems="center" justifyContent="center" padding="$5" gap="$2">
        {ErrorIcon ? <ErrorIcon size="lg" color="$danger" /> : null}
        <Text color="$danger" fontWeight="600">{grid.error}</Text>
      </YStack>
    );
  }

  if (grid.isLoading && !grid.rows.length) {
    return (
      <YStack flex={1} alignItems="center" justifyContent="center" padding="$5">
        <Text color="$textMuted">Loading cards...</Text>
      </YStack>
    );
  }

  if (!grid.rows.length) {
    const EmptyIcon = getIcon('folder');
    return (
      <YStack flex={1} alignItems="center" justifyContent="center" padding="$5" gap="$2">
        {EmptyIcon ? <EmptyIcon size="xl" color="$textMuted" /> : null}
        <Text color="$textSecondary" fontWeight="600">No records available</Text>
        <Text color="$textMuted" fontSize="$3">There's nothing to show here yet.</Text>
      </YStack>
    );
  }

  const responsiveColumns = typeof columns === 'number' ? columns : 2;

  return (
    <ScrollView flex={1}>
      <YStack padding="$4" gap="$3">
        <XStack gap="$3" flexWrap="wrap">
          {grid.rows.map((row) => {
            const isSelected = grid.selectedIds.has(row.id);
            return (
              <YStack
                key={row.id}
                minWidth={responsiveColumns > 1 ? 320 : 240}
                flex={1}
                flexBasis={responsiveColumns > 1 ? '48%' : '100%'}
                padding="$4"
                borderWidth={1}
                borderColor={isSelected ? '$accent' : '$lineSubtle'}
                backgroundColor={isSelected ? '$accentBg' : '$bgPanel'}
                borderRadius="$radiusLg"
                gap="$3"
                hoverStyle={isSelected ? undefined : { borderColor: '$lineStrong' }}
              >
                {grid.selectable ? (
                  <XStack justifyContent="flex-start">
                    <Checkbox
                      checked={isSelected}
                      onCheckedChange={() => grid.toggleSelectRow(row.id)}
                      borderColor="$lineStrong"
                      backgroundColor="$bgPanel"
                      focusStyle={{ borderColor: '$accent' }}
                    >
                      <Checkbox.Indicator>
                        {(() => {
                          const Check = getIcon('check');
                          return Check ? <Check size="sm" color="$accent" /> : null;
                        })()}
                      </Checkbox.Indicator>
                    </Checkbox>
                  </XStack>
                ) : null}

                <RecordRenderer row={row} />
              </YStack>
            );
          })}
        </XStack>

        {grid.isLoading ? (
          <Text color="$textMuted">
            Refreshing records...
          </Text>
        ) : null}
      </YStack>
    </ScrollView>
  );
}
