'use client';

/**
 * F-148 — Reporting dashboard: KPIs, trends, channel breakdown, store/terminal rankings.
 * Built on F-147 shell components and F-146 ReportingService.
 */

import { Suspense, useCallback, useEffect, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { DateRangePicker, DATE_PRESETS } from '@/components/reporting/DateRangePicker';
import { TrendChart } from '@/components/reporting/TrendChart';
import { ChannelBreakdown } from '@/components/reporting/ChannelBreakdown';
import { reportingClient, type SalesResponse, type ReportingChannel } from '@/lib/reporting-client';

function formatCents(cents: number) {
  return `€${(cents / 100).toFixed(2)}`;
}

function buildDefaultRange() {
  return DATE_PRESETS[1].getValue(); // 30 days
}

interface FilterState {
  from: string;
  to: string;
  channel: ReportingChannel;
  trendPeriod: '7' | '30' | '90';
}

function TrendDashboard({ filters }: { filters: FilterState }) {
  const [data, setData] = useState<SalesResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    const days = parseInt(filters.trendPeriod, 10);
    const from = new Date(filters.to);
    from.setDate(from.getDate() - days);
    from.setUTCHours(0, 0, 0, 0);
    const fromStr = from.toISOString();
    const toStr = filters.to;

    try {
      const result = await reportingClient.fetchSales({
        from: fromStr,
        to: toStr,
        channel: filters.channel,
        groupBy: 'day',
        pageSize: days + 5,
        page: 1,
      });
      setData(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error');
    } finally {
      setLoading(false);
    }
  }, [filters]);

  useEffect(() => { load(); }, [load]);

  if (loading) {
    return <div className="h-56 bg-gray-100 rounded-xl animate-pulse" />;
  }
  if (error) {
    return (
      <div className="h-56 bg-red-50 border border-red-200 rounded-xl flex items-center justify-center">
        <p className="text-red-600 text-sm">{error}</p>
      </div>
    );
  }

  const points = (data?.items ?? []).map((item) => ({
    label: item.period ?? '',
    value: item.metrics.grossSalesCents,
  }));

  const maxValue = Math.max(...points.map((p) => p.value), 1);

  return <TrendChart data={points} maxValue={maxValue} height={220} />;
}

function ChannelDashboard({ filters }: { filters: FilterState }) {
  const [data, setData] = useState<SalesResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const result = await reportingClient.fetchSales({
        from: filters.from,
        to: filters.to,
        channel: filters.channel,
        groupBy: 'channel',
        pageSize: 10,
        page: 1,
      });
      setData(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error');
    } finally {
      setLoading(false);
    }
  }, [filters]);

  useEffect(() => { load(); }, [load]);

  if (loading) {
    return (
      <div className="grid grid-cols-3 gap-4">
        {[...Array(3)].map((_, i) => (
          <div key={i} className="h-32 bg-gray-100 rounded-xl animate-pulse" />
        ))}
      </div>
    );
  }
  if (error) return <p className="text-red-500 text-sm">{error}</p>;

  const channelData = (data?.items ?? []).map((item) => ({
    channel: item.channel ?? 'all' as ReportingChannel,
    orders: item.metrics.orders,
    grossSalesCents: item.metrics.grossSalesCents,
  }));

  const total = data?.totals.grossSalesCents ?? 0;

  return <ChannelBreakdown data={channelData} totalSalesCents={total} />;
}

function StoresTable({ filters }: { filters: FilterState }) {
  const [data, setData] = useState<SalesResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const result = await reportingClient.fetchSales({
        from: filters.from,
        to: filters.to,
        channel: filters.channel,
        groupBy: 'store',
        pageSize: 10,
        page: 1,
      });
      setData(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error');
    } finally {
      setLoading(false);
    }
  }, [filters]);

  useEffect(() => { load(); }, [load]);

  if (loading) {
    return <div className="h-48 bg-gray-100 rounded-xl animate-pulse" />;
  }
  if (error) return <p className="text-red-500 text-sm">{error}</p>;

  const items = (data?.items ?? []).sort((a, b) => b.metrics.grossSalesCents - a.metrics.grossSalesCents);
  const total = data?.totals.grossSalesCents ?? 1;

  if (items.length === 0) {
    return <p className="text-gray-400 text-sm">No hay datos de tiendas</p>;
  }

  return (
    <table className="w-full text-sm">
      <thead>
        <tr className="border-b border-gray-200">
          <th className="text-left py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Tienda</th>
          <th className="text-right py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Pedidos</th>
          <th className="text-right py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Ventas</th>
          <th className="text-right py-2 px-3 font-semibold text-gray-500 uppercase text-xs">%</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-50">
        {items.map((row, i) => (
          <tr key={i} className="hover:bg-gray-50">
            <td className="py-2.5 px-3 font-medium text-gray-800">
              {row.storeId ? row.storeId.slice(0, 8) + '...' : 'Sin tienda'}
            </td>
            <td className="py-2.5 px-3 text-right text-gray-600">{row.metrics.orders}</td>
            <td className="py-2.5 px-3 text-right font-medium text-gray-900">
              {formatCents(row.metrics.grossSalesCents)}
            </td>
            <td className="py-2.5 px-3 text-right text-gray-500">
              {((row.metrics.grossSalesCents / total) * 100).toFixed(1)}%
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function TerminalsTable({ filters }: { filters: FilterState }) {
  const [data, setData] = useState<SalesResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const result = await reportingClient.fetchSales({
        from: filters.from,
        to: filters.to,
        channel: 'pos',
        groupBy: 'terminal',
        pageSize: 10,
        page: 1,
      });
      setData(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error');
    } finally {
      setLoading(false);
    }
  }, [filters]);

  useEffect(() => { load(); }, [load]);

  if (loading) {
    return <div className="h-48 bg-gray-100 rounded-xl animate-pulse" />;
  }
  if (error) return <p className="text-red-500 text-sm">{error}</p>;

  const items = (data?.items ?? []).sort((a, b) => b.metrics.grossSalesCents - a.metrics.grossSalesCents);

  if (items.length === 0) {
    return <p className="text-gray-400 text-sm">No hay datos de terminales</p>;
  }

  return (
    <table className="w-full text-sm">
      <thead>
        <tr className="border-b border-gray-200">
          <th className="text-left py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Terminal</th>
          <th className="text-right py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Pedidos</th>
          <th className="text-right py-2 px-3 font-semibold text-gray-500 uppercase text-xs">Ventas</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-50">
        {items.map((row, i) => (
          <tr key={i} className="hover:bg-gray-50">
            <td className="py-2.5 px-3 font-medium text-gray-800">
              {row.terminalId ? row.terminalId.slice(0, 8) + '...' : 'Sin terminal'}
            </td>
            <td className="py-2.5 px-3 text-right text-gray-600">{row.metrics.orders}</td>
            <td className="py-2.5 px-3 text-right font-medium text-gray-900">
              {formatCents(row.metrics.grossSalesCents)}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function DashboardContent() {
  const router = useRouter();
  const searchParams = useSearchParams();

  const getInitial = (): FilterState => ({
    from: searchParams.get('from') ?? buildDefaultRange().from,
    to: searchParams.get('to') ?? buildDefaultRange().to,
    channel: (searchParams.get('channel') as ReportingChannel) ?? 'all',
    trendPeriod: (searchParams.get('trend') as FilterState['trendPeriod']) ?? '30',
  });

  const [filters, setFilters] = useState<FilterState>(getInitial);

  const updateSearchParams = useCallback(
    (f: FilterState) => {
      const params = new URLSearchParams();
      params.set('from', f.from);
      params.set('to', f.to);
      if (f.channel !== 'all') params.set('channel', f.channel);
      if (f.trendPeriod !== '30') params.set('trend', f.trendPeriod);
      router.replace(`/reporting/dashboard?${params}`, { scroll: false });
    },
    [router],
  );

  const handleFiltersChange = (f: FilterState) => {
    setFilters(f);
    updateSearchParams(f);
  };

  return (
    <div className="flex flex-col gap-6">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-gray-900">Dashboard de ventas</h1>
        <p className="text-sm text-gray-500 mt-0.5">
          Tendencias, canales y rendimiento por tienda/terminal
        </p>
      </div>

      {/* Filters */}
      <div className="bg-white border border-gray-200 rounded-xl p-4 flex flex-col gap-4">
        <div className="flex flex-wrap gap-4 items-end">
          {/* Channel */}
          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-semibold text-gray-500 uppercase tracking-wide">Canal</label>
            <select
              value={filters.channel}
              onChange={(e) => handleFiltersChange({ ...filters, channel: e.target.value as ReportingChannel })}
              className="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#2D6A4F] outline-none bg-white"
            >
              <option value="all">Todos</option>
              <option value="ecommerce">Ecommerce</option>
              <option value="pos">TPV</option>
            </select>
          </div>

          {/* Trend period */}
          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-semibold text-gray-500 uppercase tracking-wide">Período tendencia</label>
            <select
              value={filters.trendPeriod}
              onChange={(e) => handleFiltersChange({ ...filters, trendPeriod: e.target.value as FilterState['trendPeriod'] })}
              className="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#2D6A4F] outline-none bg-white"
            >
              <option value="7">7 días</option>
              <option value="30">30 días</option>
              <option value="90">90 días</option>
            </select>
          </div>
        </div>

        <div>
          <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">Rango de fechas</p>
          <DateRangePicker
            from={filters.from}
            to={filters.to}
            onChange={(from, to) => handleFiltersChange({ ...filters, from, to })}
          />
        </div>
      </div>

      {/* Channel breakdown */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h2 className="text-base font-semibold text-gray-800 mb-4">Canales</h2>
        <ChannelDashboard filters={filters} />
      </div>

      {/* Trend chart */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h2 className="text-base font-semibold text-gray-800 mb-4">
          Tendencia ({filters.trendPeriod === '7' ? '7 días' : filters.trendPeriod === '30' ? '30 días' : '90 días'})
        </h2>
        <TrendDashboard filters={filters} />
      </div>

      {/* Store and terminal tables */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        <div className="bg-white border border-gray-200 rounded-xl p-5">
          <h2 className="text-base font-semibold text-gray-800 mb-4">Top tiendas</h2>
          <StoresTable filters={filters} />
        </div>

        <div className="bg-white border border-gray-200 rounded-xl p-5">
          <h2 className="text-base font-semibold text-gray-800 mb-4">Top terminales (TPV)</h2>
          <TerminalsTable filters={filters} />
        </div>
      </div>
    </div>
  );
}

export default function DashboardPage() {
  return (
    <Suspense fallback={
      <div className="p-8 animate-pulse space-y-4">
        <div className="h-8 bg-gray-200 rounded w-1/3" />
        <div className="h-48 bg-gray-200 rounded-xl" />
        <div className="h-64 bg-gray-200 rounded-xl" />
      </div>
    }>
      <DashboardContent />
    </Suspense>
  );
}
