import { useMemo, useState } from 'react';
import { Card, Group, SegmentedControl, SimpleGrid, Text, ThemeIcon } from '@mantine/core';
import { BarChart3, CalendarRange, PieChart as PieChartIcon } from 'lucide-react';
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';

import { useQuery } from '@tanstack/react-query';

import { api } from '@/services/api';
import type { WarehouseDashboard, WarehouseInventoryItem } from '@/types/warehouse';

interface WarehouseDashboardChartsProps {
  data?: WarehouseDashboard;
}

const ORANGE = '#f08c00';
const GREEN = '#22c55e'; // green from bookings

/** Inventory lifecycle status series — one distinct color per status (aligned with status badges). */
const STATUS_SERIES = [
  { key: 'stored', label: 'Stored', color: '#228be6' }, // blue
  { key: 'reserved', label: 'Reserved', color: '#ae3ec9' }, // grape
  { key: 'readyForLoading', label: 'Ready', color: '#f08c00' }, // orange
  { key: 'loaded', label: 'Loaded', color: '#12b886' }, // teal
  { key: 'dispatched', label: 'Dispatched', color: GREEN }, // green (bookings)
] as const;

type Granularity = 'week' | 'month' | 'year';

export function WarehouseDashboardCharts({ data }: WarehouseDashboardChartsProps) {
  const [granularity, setGranularity] = useState<Granularity>('month');
  const { data: inventory } = useQuery(
    api.warehouses.listInventory.queryOptions({ input: {} }),
  );

  const statusData = STATUS_SERIES.map((s) => ({
    name: s.label,
    value: data ? Number(data[s.key as keyof WarehouseDashboard] ?? 0) : 0,
    color: s.color,
  }));
  const hasStatus = statusData.some((d) => d.value > 0);

  const trend = useMemo(
    () => buildTrend(inventory ?? [], granularity),
    [inventory, granularity],
  );
  const hasTrend = trend.some((b) => b.received > 0 || b.dispatched > 0);

  return (
    <SimpleGrid cols={{ base: 1, lg: 2 }} spacing="md">
      {/* Time-filtered throughput */}
      <Card withBorder radius="lg" padding="lg" style={{ gridColumn: '1 / -1' }}>
        <Group justify="space-between" mb="md" wrap="wrap">
          <Group gap="sm">
            <ThemeIcon size="lg" radius="md" style={{ backgroundColor: ORANGE, color: '#fff' }}>
              <CalendarRange size={20} />
            </ThemeIcon>
            <div>
              <Text fw={700}>Throughput Over Time</Text>
              <Text size="xs" c="dimmed">
                Received vs dispatched inventory
              </Text>
            </div>
          </Group>
          <SegmentedControl
            value={granularity}
            onChange={(v) => setGranularity(v as Granularity)}
            data={[
              { label: 'Weekly', value: 'week' },
              { label: 'Monthly', value: 'month' },
              { label: 'Yearly', value: 'year' },
            ]}
          />
        </Group>

        {hasTrend ? (
          <ResponsiveContainer width="100%" height={300}>
            <BarChart data={trend} margin={{ top: 8, right: 8, left: -16, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="var(--mantine-color-gray-2)" />
              <XAxis dataKey="label" tick={{ fontSize: 12 }} />
              <YAxis allowDecimals={false} tick={{ fontSize: 12 }} />
              <Tooltip cursor={{ fill: 'var(--mantine-color-gray-1)' }} />
              <Legend iconType="circle" />
              <Bar dataKey="received" name="Received" fill={ORANGE} radius={[6, 6, 0, 0]} />
              <Bar dataKey="dispatched" name="Dispatched" fill={GREEN} radius={[6, 6, 0, 0]} />
            </BarChart>
          </ResponsiveContainer>
        ) : (
          <EmptyChart />
        )}
      </Card>

      {/* Status distribution bar */}
      <Card withBorder radius="lg" padding="lg">
        <Group gap="sm" mb="md">
          <ThemeIcon size="lg" radius="md" style={{ backgroundColor: GREEN, color: '#fff' }}>
            <BarChart3 size={20} />
          </ThemeIcon>
          <div>
            <Text fw={700}>Inventory by Status</Text>
            <Text size="xs" c="dimmed">
              Items at each lifecycle stage
            </Text>
          </div>
        </Group>

        {hasStatus ? (
          <ResponsiveContainer width="100%" height={280}>
            <BarChart data={statusData} margin={{ top: 8, right: 8, left: -16, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="var(--mantine-color-gray-2)" />
              <XAxis dataKey="name" tick={{ fontSize: 12 }} />
              <YAxis allowDecimals={false} tick={{ fontSize: 12 }} />
              <Tooltip cursor={{ fill: 'var(--mantine-color-gray-1)' }} />
              <Bar dataKey="value" name="Items" radius={[6, 6, 0, 0]}>
                {statusData.map((entry) => (
                  <Cell key={entry.name} fill={entry.color} />
                ))}
              </Bar>
            </BarChart>
          </ResponsiveContainer>
        ) : (
          <EmptyChart />
        )}
      </Card>

      {/* Status distribution donut */}
      <Card withBorder radius="lg" padding="lg">
        <Group gap="sm" mb="md">
          <ThemeIcon size="lg" radius="md" style={{ backgroundColor: ORANGE, color: '#fff' }}>
            <PieChartIcon size={20} />
          </ThemeIcon>
          <div>
            <Text fw={700}>Lifecycle Distribution</Text>
            <Text size="xs" c="dimmed">
              Share of inventory across statuses
            </Text>
          </div>
        </Group>

        {hasStatus ? (
          <ResponsiveContainer width="100%" height={280}>
            <PieChart>
              <Pie
                data={statusData}
                dataKey="value"
                nameKey="name"
                cx="50%"
                cy="50%"
                innerRadius={55}
                outerRadius={95}
                paddingAngle={2}
              >
                {statusData.map((entry) => (
                  <Cell key={entry.name} fill={entry.color} />
                ))}
              </Pie>
              <Tooltip />
              <Legend verticalAlign="bottom" height={36} iconType="circle" />
            </PieChart>
          </ResponsiveContainer>
        ) : (
          <EmptyChart />
        )}
      </Card>
    </SimpleGrid>
  );
}

interface TrendBucket {
  label: string;
  received: number;
  dispatched: number;
}

/** Bucket inventory by arrived/dispatched timestamps into recent week/month/year periods. */
function buildTrend(items: WarehouseInventoryItem[], granularity: Granularity): TrendBucket[] {
  const now = new Date();
  const buckets: { label: string; start: Date; end: Date }[] = [];

  if (granularity === 'week') {
    for (let i = 7; i >= 0; i--) {
      const end = new Date(now);
      end.setDate(now.getDate() - i * 7);
      const start = new Date(end);
      start.setDate(end.getDate() - 7);
      buckets.push({ label: `W${8 - i}`, start, end });
    }
  } else if (granularity === 'month') {
    for (let i = 11; i >= 0; i--) {
      const start = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const end = new Date(now.getFullYear(), now.getMonth() - i + 1, 1);
      buckets.push({
        label: start.toLocaleString('en', { month: 'short' }),
        start,
        end,
      });
    }
  } else {
    for (let i = 4; i >= 0; i--) {
      const year = now.getFullYear() - i;
      buckets.push({
        label: String(year),
        start: new Date(year, 0, 1),
        end: new Date(year + 1, 0, 1),
      });
    }
  }

  const inRange = (iso: string | null | undefined, start: Date, end: Date) => {
    if (!iso) return false;
    const t = new Date(iso).getTime();
    return t >= start.getTime() && t < end.getTime();
  };

  return buckets.map((b) => ({
    label: b.label,
    received: items.filter((it) => inRange(it.arrivedAt, b.start, b.end)).length,
    dispatched: items.filter((it) => inRange(it.dispatchedAt, b.start, b.end)).length,
  }));
}

function EmptyChart() {
  return (
    <Group justify="center" align="center" h={280}>
      <Text c="dimmed" size="sm">
        No inventory data to chart yet.
      </Text>
    </Group>
  );
}
