/**
 * Array Card Component
 * Displays Unraid array status and disk information
 */

import {
  ActionIcon,
  Badge,
  Card,
  Group,
  Progress,
  Stack,
  Table,
  Text,
  ThemeIcon,
  Title,
  Tooltip,
} from '@mantine/core';
import {
  IconDatabase,
  IconPlayerPlay,
  IconPlayerStop,
  IconTemperature,
  IconHardDrive,
} from '@tabler/icons-react';

import type { UnraidArray, ArrayDisk, ArrayState } from '~/lib/unraid/types';

interface ArrayCardProps {
  array: UnraidArray;
  onStartArray?: () => void;
  onStopArray?: () => void;
  isLoading?: boolean;
}

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function getStatusColor(status: string): string {
  switch (status) {
    case 'DISK_OK':
      return 'green';
    case 'DISK_INVALID':
    case 'DISK_WRONG':
      return 'red';
    case 'DISK_DSBL':
    case 'DISK_DSBL_NEW':
      return 'orange';
    case 'DISK_NEW':
      return 'blue';
    case 'DISK_NP':
      return 'gray';
    default:
      return 'gray';
  }
}

function getArrayStateColor(state: ArrayState): string {
  switch (state) {
    case 'STARTED':
      return 'green';
    case 'STOPPED':
      return 'red';
    default:
      return 'orange';
  }
}

function DiskRow({ disk }: { disk: ArrayDisk }) {
  const usedPercent = disk.fsSize && disk.fsUsed
    ? ((disk.fsUsed / disk.fsSize) * 100).toFixed(1)
    : null;

  return (
    <tr>
      <td>
        <Group spacing="xs">
          <ThemeIcon size="sm" variant="light" color={disk.spunDown ? 'gray' : 'blue'}>
            <IconHardDrive size={14} />
          </ThemeIcon>
          <Text size="sm" weight={500}>
            {disk.name}
          </Text>
        </Group>
      </td>
      <td>
        <Badge size="xs" color={getStatusColor(disk.status)} variant="light">
          {disk.status.replace('DISK_', '')}
        </Badge>
      </td>
      <td>
        <Text size="sm">{formatBytes(disk.size)}</Text>
      </td>
      <td>
        {disk.temp !== null ? (
          <Group spacing={4}>
            <IconTemperature size={14} />
            <Text size="sm" color={disk.temp > 50 ? 'red' : disk.temp > 40 ? 'orange' : undefined}>
              {disk.temp}°C
            </Text>
          </Group>
        ) : (
          <Text size="sm" color="dimmed">
            {disk.spunDown ? 'Spun down' : '-'}
          </Text>
        )}
      </td>
      <td style={{ width: 150 }}>
        {usedPercent ? (
          <Tooltip label={`${formatBytes(disk.fsUsed!)} / ${formatBytes(disk.fsSize!)}`}>
            <Progress
              value={parseFloat(usedPercent)}
              size="sm"
              radius="md"
              color={parseFloat(usedPercent) > 90 ? 'red' : parseFloat(usedPercent) > 75 ? 'orange' : 'blue'}
            />
          </Tooltip>
        ) : (
          <Text size="sm" color="dimmed">-</Text>
        )}
      </td>
    </tr>
  );
}

export function ArrayCard({ array, onStartArray, onStopArray, isLoading }: ArrayCardProps) {
  const usedPercent = ((array.capacity.used / array.capacity.total) * 100).toFixed(1);
  const isStarted = array.state === 'STARTED';

  return (
    <Card shadow="sm" radius="md" withBorder>
      <Card.Section withBorder inheritPadding py="xs">
        <Group position="apart">
          <Group>
            <ThemeIcon size="lg" radius="md" variant="light" color="blue">
              <IconDatabase size={20} />
            </ThemeIcon>
            <div>
              <Title order={4}>Array</Title>
              <Text size="xs" color="dimmed">
                {formatBytes(array.capacity.used)} / {formatBytes(array.capacity.total)}
              </Text>
            </div>
          </Group>
          <Group spacing="xs">
            <Badge color={getArrayStateColor(array.state)} variant="filled">
              {array.state}
            </Badge>
            {isStarted && onStopArray && (
              <Tooltip label="Stop Array">
                <ActionIcon
                  color="red"
                  variant="light"
                  onClick={onStopArray}
                  loading={isLoading}
                >
                  <IconPlayerStop size={16} />
                </ActionIcon>
              </Tooltip>
            )}
            {!isStarted && onStartArray && (
              <Tooltip label="Start Array">
                <ActionIcon
                  color="green"
                  variant="light"
                  onClick={onStartArray}
                  loading={isLoading}
                >
                  <IconPlayerPlay size={16} />
                </ActionIcon>
              </Tooltip>
            )}
          </Group>
        </Group>
      </Card.Section>

      <Stack spacing="md" mt="md">
        {/* Array Capacity */}
        <div>
          <Group position="apart" mb={5}>
            <Text size="sm" weight={500}>
              Total Capacity
            </Text>
            <Text size="xs" color="dimmed">
              {usedPercent}% used
            </Text>
          </Group>
          <Progress
            value={parseFloat(usedPercent)}
            size="lg"
            radius="md"
            color={parseFloat(usedPercent) > 90 ? 'red' : parseFloat(usedPercent) > 75 ? 'orange' : 'blue'}
          />
        </div>

        {/* Parity Check Status */}
        {array.parityCheckStatus?.running && (
          <div>
            <Group position="apart" mb={5}>
              <Text size="sm" weight={500} color="orange">
                Parity Check in Progress
              </Text>
              <Text size="xs" color="dimmed">
                {array.parityCheckStatus.progress.toFixed(1)}% - {array.parityCheckStatus.errors} errors
              </Text>
            </Group>
            <Progress
              value={array.parityCheckStatus.progress}
              size="md"
              radius="md"
              color="orange"
              animate
            />
          </div>
        )}

        {/* Parity Disks */}
        {array.parities.length > 0 && (
          <>
            <Text size="sm" weight={600} mt="xs">
              Parity ({array.parities.length})
            </Text>
            <Table fontSize="sm" verticalSpacing={4}>
              <thead>
                <tr>
                  <th>Disk</th>
                  <th>Status</th>
                  <th>Size</th>
                  <th>Temp</th>
                  <th>Usage</th>
                </tr>
              </thead>
              <tbody>
                {array.parities.map((disk) => (
                  <DiskRow key={disk.id} disk={disk} />
                ))}
              </tbody>
            </Table>
          </>
        )}

        {/* Data Disks */}
        {array.disks.length > 0 && (
          <>
            <Text size="sm" weight={600} mt="xs">
              Data Disks ({array.disks.length})
            </Text>
            <Table fontSize="sm" verticalSpacing={4}>
              <thead>
                <tr>
                  <th>Disk</th>
                  <th>Status</th>
                  <th>Size</th>
                  <th>Temp</th>
                  <th>Usage</th>
                </tr>
              </thead>
              <tbody>
                {array.disks.map((disk) => (
                  <DiskRow key={disk.id} disk={disk} />
                ))}
              </tbody>
            </Table>
          </>
        )}

        {/* Cache Pools */}
        {array.caches.length > 0 && (
          <>
            <Text size="sm" weight={600} mt="xs">
              Cache Pools ({array.caches.length})
            </Text>
            {array.caches.map((cache) => {
              const cacheUsedPercent = ((cache.fsUsed / cache.fsSize) * 100).toFixed(1);
              return (
                <div key={cache.id}>
                  <Group position="apart" mb={5}>
                    <Text size="sm" weight={500}>
                      {cache.name} ({cache.fsType})
                    </Text>
                    <Text size="xs" color="dimmed">
                      {formatBytes(cache.fsUsed)} / {formatBytes(cache.fsSize)}
                    </Text>
                  </Group>
                  <Progress
                    value={parseFloat(cacheUsedPercent)}
                    size="sm"
                    radius="md"
                    color={parseFloat(cacheUsedPercent) > 90 ? 'red' : parseFloat(cacheUsedPercent) > 75 ? 'orange' : 'teal'}
                  />
                </div>
              );
            })}
          </>
        )}
      </Stack>
    </Card>
  );
}

export default ArrayCard;
