/**
 * CostView — cost trends + detail + summary.
 *
 * Features:
 * - Date range selector: Today / This month / Custom (SegmentedControl + DateInput).
 * - Recharts AreaChart showing import_cost, export_revenue, net_cost per period.
 * - Table showing per-15min periods with time, kWh values, costs, degraded badge.
 * - Summary cards: metered import/export, fixed costs, credits, total payable.
 * - "Recompute" button with confirmation.
 * - Loading/error/empty states, degraded period highlighting.
 *
 * Recharts imports are isolated to this file only.
 */

import { useState } from 'react'
import {
  Stack,
  Text,
  TextInput,
  Loader,
  Center,
  Alert,
  Table,
  Group,
  Badge,
  ScrollArea,
  SegmentedControl,
  Button,
  Paper,
  SimpleGrid,
  Modal,
  Title,
} from '@mantine/core'
import {
  AreaChart,
  Area,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts'
import { useEnergyCosts, useEnergyCostSummary, useRecomputeCosts } from './hooks'
import { formatLocalTime } from '../utils/datetime'

// ---------------------------------------------------------------------------
// Cost limit — prevent accidental full-table pulls
// ---------------------------------------------------------------------------

const COSTS_MAX_LIMIT = 500

// ---------------------------------------------------------------------------
// Date range helpers
// ---------------------------------------------------------------------------

function getTodayRange(): { start: string; end: string } {
  // Use local date boundary so "today" matches what the user sees in the display.
  const now = new Date()
  const start = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1)
  return { start: start.toISOString(), end: end.toISOString() }
}

function getThisMonthRange(): { start: string; end: string } {
  // Use local date boundary so "this month" matches what the user sees in the display.
  const now = new Date()
  const start = new Date(now.getFullYear(), now.getMonth(), 1)
  const end = new Date(now.getFullYear(), now.getMonth() + 1, 1)
  return { start: start.toISOString(), end: end.toISOString() }
}

// ---------------------------------------------------------------------------
// Summary cards
// ---------------------------------------------------------------------------

interface SummaryCardProps {
  label: string
  value: string
  testId?: string
}

function SummaryCard({ label, value, testId }: SummaryCardProps) {
  return (
    <Paper withBorder p="sm" data-testid={testId}>
      <Stack gap={4}>
        <Text size="xs" c="dimmed">
          {label}
        </Text>
        <Text fw={600} size="lg">
          {value}
        </Text>
      </Stack>
    </Paper>
  )
}

// ---------------------------------------------------------------------------
// CostView — main component
// ---------------------------------------------------------------------------

type RangePreset = 'today' | 'month' | 'custom'

export function CostView() {
  const [rangePreset, setRangePreset] = useState<RangePreset>('today')
  // Date strings in YYYY-MM-DD format for custom range
  const [customStartStr, setCustomStartStr] = useState('')
  const [customEndStr, setCustomEndStr] = useState('')
  const [showRecomputeConfirm, setShowRecomputeConfirm] = useState(false)

  // Compute effective date range
  const { start, end } = (() => {
    if (rangePreset === 'today') return getTodayRange()
    if (rangePreset === 'month') return getThisMonthRange()
    return {
      start: customStartStr ? new Date(customStartStr).toISOString() : undefined,
      end: customEndStr ? new Date(customEndStr).toISOString() : undefined,
    }
  })()

  const costsQuery = useEnergyCosts(start, end, COSTS_MAX_LIMIT)
  const summaryQuery = useEnergyCostSummary(start, end)
  const recomputeMutation = useRecomputeCosts()

  async function handleRecompute() {
    setShowRecomputeConfirm(false)
    await recomputeMutation.mutateAsync({ start, end })
  }

  // ---------------------------------------------------------------------------
  // Render
  // ---------------------------------------------------------------------------

  const currency = costsQuery.data?.items[0]?.currency ?? summaryQuery.data?.currency ?? 'EUR'

  return (
    <Stack gap="lg" data-testid="cost-view">
      {/* Date range selector */}
      <Group align="flex-start" gap="md" wrap="wrap">
        <Stack gap="xs">
          <Text size="sm" fw={500}>
            Date range
          </Text>
          <SegmentedControl
            value={rangePreset}
            onChange={(v) => setRangePreset(v as RangePreset)}
            data={[
              { label: 'Today', value: 'today' },
              { label: 'This month', value: 'month' },
              { label: 'Custom', value: 'custom' },
            ]}
            data-testid="cost-range-control"
          />
        </Stack>

        {rangePreset === 'custom' && (
          <Group gap="sm" align="flex-end">
            <TextInput
              label="From"
              type="date"
              value={customStartStr}
              onChange={(e) => setCustomStartStr(e.currentTarget.value)}
              data-testid="cost-custom-start"
            />
            <TextInput
              label="To"
              type="date"
              value={customEndStr}
              onChange={(e) => setCustomEndStr(e.currentTarget.value)}
              data-testid="cost-custom-end"
            />
          </Group>
        )}

        <Group gap="sm" style={{ marginLeft: 'auto' }} align="flex-end">
          <Button
            variant="outline"
            color="orange"
            size="sm"
            onClick={() => setShowRecomputeConfirm(true)}
            loading={recomputeMutation.isPending}
            data-testid="cost-recompute-button"
          >
            Recompute
          </Button>
        </Group>
      </Group>

      {/* Summary cards */}
      {summaryQuery.isLoading && (
        <Center>
          <Loader size="sm" />
        </Center>
      )}

      {summaryQuery.isError && (
        <Alert color="red" data-testid="summary-error">
          Failed to load cost summary.
        </Alert>
      )}

      {summaryQuery.data && (
        <Stack gap="xs">
          <Title order={6} c="dimmed">
            Summary
          </Title>
          <SimpleGrid cols={{ base: 2, sm: 3 }} spacing="sm" data-testid="cost-summary">
            <SummaryCard
              label="Import (kWh)"
              value={summaryQuery.data.metered_import.toFixed(3)}
              testId="summary-import"
            />
            <SummaryCard
              label="Export (kWh)"
              value={summaryQuery.data.metered_export.toFixed(3)}
              testId="summary-export"
            />
            <SummaryCard
              label={`Fixed costs (${currency})`}
              value={summaryQuery.data.fixed_costs.toFixed(2)}
              testId="summary-fixed"
            />
            <SummaryCard
              label={`Credits (${currency})`}
              value={summaryQuery.data.credits.toFixed(2)}
              testId="summary-credits"
            />
            <SummaryCard
              label={`Total payable (${currency})`}
              value={summaryQuery.data.total_payable.toFixed(2)}
              testId="summary-total"
            />
          </SimpleGrid>
        </Stack>
      )}

      {/* Cost chart */}
      {costsQuery.isLoading && (
        <Center py="xl" data-testid="costs-loading">
          <Loader />
        </Center>
      )}

      {costsQuery.isError && (
        <Alert color="red" data-testid="costs-error">
          Failed to load cost periods. Please refresh.
        </Alert>
      )}

      {costsQuery.data && costsQuery.data.items.length === 0 && (
        <Alert color="gray" data-testid="costs-empty">
          No cost data available for the selected period.
        </Alert>
      )}

      {costsQuery.data && costsQuery.data.items.length > 0 && (
        <>
          {/* Area chart */}
          <Stack gap="xs" data-testid="cost-chart">
            <Title order={6} c="dimmed">
              Cost trends ({currency})
            </Title>
            <ResponsiveContainer width="100%" height={220}>
              <AreaChart
                data={costsQuery.data.items.map((item) => ({
                  time: formatLocalTime(item.period_start),
                  import_cost: item.import_cost,
                  export_revenue: item.export_revenue,
                  net_cost: item.net_cost,
                }))}
                margin={{ top: 4, right: 16, left: 0, bottom: 4 }}
              >
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis dataKey="time" tick={{ fontSize: 10 }} interval="preserveStartEnd" />
                <YAxis tick={{ fontSize: 10 }} tickFormatter={(v: number) => v.toFixed(2)} />
                <Tooltip
                  // eslint-disable-next-line @typescript-eslint/no-explicit-any
                  formatter={(val: any) =>
                    [`${typeof val === 'number' ? val.toFixed(4) : String(val)} ${currency}`, undefined]
                  }
                />
                <Legend />
                <Area
                  type="monotone"
                  dataKey="import_cost"
                  stroke="#2196f3"
                  fill="#bbdefb"
                  name="Import cost"
                  dot={false}
                />
                <Area
                  type="monotone"
                  dataKey="export_revenue"
                  stroke="#4caf50"
                  fill="#c8e6c9"
                  name="Export revenue"
                  dot={false}
                />
                <Area
                  type="monotone"
                  dataKey="net_cost"
                  stroke="#ff9800"
                  fill="#ffe0b2"
                  name="Net cost"
                  dot={false}
                />
              </AreaChart>
            </ResponsiveContainer>
          </Stack>

          {/* Detail table */}
          <Stack gap="xs">
            <Title order={6} c="dimmed">
              Period detail
            </Title>
            <ScrollArea>
              <Table
                striped
                highlightOnHover
                withTableBorder
                withColumnBorders
                style={{ fontSize: 12 }}
                data-testid="costs-table"
              >
                <Table.Thead>
                  <Table.Tr>
                    <Table.Th>Time</Table.Th>
                    <Table.Th>Import kWh</Table.Th>
                    <Table.Th>Export kWh</Table.Th>
                    <Table.Th>Import cost</Table.Th>
                    <Table.Th>Export rev.</Table.Th>
                    <Table.Th>Net cost</Table.Th>
                    <Table.Th></Table.Th>
                  </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                  {costsQuery.data.items.map((item, idx) => (
                    <Table.Tr
                      key={idx}
                      style={item.degraded ? { opacity: 0.6 } : undefined}
                      data-testid={`cost-row-${idx}`}
                    >
                      <Table.Td>
                        <Text size="xs">
                          {formatLocalTime(item.period_start)}
                        </Text>
                      </Table.Td>
                      <Table.Td>{(item.d1_kwh + item.d2_kwh).toFixed(3)}</Table.Td>
                      <Table.Td>{(item.r1_kwh + item.r2_kwh).toFixed(3)}</Table.Td>
                      <Table.Td>{item.import_cost.toFixed(4)}</Table.Td>
                      <Table.Td>{item.export_revenue.toFixed(4)}</Table.Td>
                      <Table.Td>{item.net_cost.toFixed(4)}</Table.Td>
                      <Table.Td>
                        {item.degraded && (
                          <Badge color="orange" size="xs" data-testid={`cost-degraded-${idx}`}>
                            degraded
                          </Badge>
                        )}
                      </Table.Td>
                    </Table.Tr>
                  ))}
                </Table.Tbody>
              </Table>
            </ScrollArea>
          </Stack>
        </>
      )}

      {/* Recompute confirmation modal */}
      {showRecomputeConfirm && (
        <Modal
          opened
          onClose={() => setShowRecomputeConfirm(false)}
          title="Recompute costs?"
          size="sm"
          data-testid="recompute-confirm-modal"
        >
          <Stack gap="md">
            <Text size="sm">
              This will recompute all cost periods for the selected date range. Continue?
            </Text>
            <Group justify="flex-end" gap="sm">
              <Button
                variant="default"
                onClick={() => setShowRecomputeConfirm(false)}
                data-testid="recompute-cancel"
              >
                Cancel
              </Button>
              <Button
                color="orange"
                onClick={handleRecompute}
                data-testid="recompute-confirm"
              >
                Recompute
              </Button>
            </Group>
          </Stack>
        </Modal>
      )}
    </Stack>
  )
}
