'use client';

import { useQueryClient } from '@tanstack/react-query';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Bar } from 'recharts';
import { BrainCircuit, Plus, RefreshCcw, Trash2 } from 'lucide-react';
import { AppShell } from '@/components/shell/app-shell';
import { Panel } from '@/components/ui/panel';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useAuthGuard } from '@/hooks/use-auth-guard';
import {
  deleteHolding,
  queuePortfolioInsights,
  queuePriceRefresh,
  upsertHolding
} from '@/lib/api';
import type { Holding, PortfolioInsight, PortfolioSummary } from '@/lib/types';
import { asNumber, formatCurrency, formatPercent } from '@/lib/format';
import { queryKeys } from '@/lib/query/keys';
import {
  holdingsQueryOptions,
  latestPortfolioInsightQueryOptions,
  portfolioSummaryQueryOptions
} from '@/lib/query/options';

type FormState = {
  ticker: string;
  shares: string;
  avgCost: string;
  currentPrice: string;
};

const CHART_COLORS = ['#6effd8', '#5fd3ff', '#66ffa1', '#8dbbff', '#f4f88f', '#ff9c9c'];
const CHART_TEXT = '#e8fff8';
const CHART_MUTED = '#b4ced9';
const CHART_GRID = 'rgba(126, 217, 255, 0.24)';
const CHART_TOOLTIP_BG = 'rgba(6, 17, 24, 0.95)';
const CHART_TOOLTIP_BORDER = 'rgba(123, 255, 217, 0.45)';

const EMPTY_SUMMARY: PortfolioSummary = {
  positions: 0,
  total_value: '0',
  total_gain_loss: '0',
  total_cost_basis: '0',
  avg_return_pct: '0'
};

export default function PortfolioPage() {
  const { isPending, isAuthenticated } = useAuthGuard();
  const queryClient = useQueryClient();

  const [holdings, setHoldings] = useState<Holding[]>([]);
  const [summary, setSummary] = useState<PortfolioSummary>(EMPTY_SUMMARY);
  const [latestInsight, setLatestInsight] = useState<PortfolioInsight | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [form, setForm] = useState<FormState>({ ticker: '', shares: '', avgCost: '', currentPrice: '' });

  const loadPortfolio = useCallback(async () => {
    const holdingsOptions = holdingsQueryOptions();
    const summaryOptions = portfolioSummaryQueryOptions();
    const insightOptions = latestPortfolioInsightQueryOptions();

    if (!queryClient.getQueryData(summaryOptions.queryKey)) {
      setLoading(true);
    }

    setError(null);

    try {
      const [holdingsRes, summaryRes, insightRes] = await Promise.all([
        queryClient.ensureQueryData(holdingsOptions),
        queryClient.ensureQueryData(summaryOptions),
        queryClient.ensureQueryData(insightOptions)
      ]);

      setHoldings(holdingsRes.holdings);
      setSummary(summaryRes.summary);
      setLatestInsight(insightRes.insight);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Could not fetch portfolio data');
    } finally {
      setLoading(false);
    }
  }, [queryClient]);

  useEffect(() => {
    if (!isPending && isAuthenticated) {
      void loadPortfolio();
    }
  }, [isPending, isAuthenticated, loadPortfolio]);

  const allocationData = useMemo(
    () => holdings.map((holding) => ({
      name: holding.ticker,
      value: asNumber(holding.market_value)
    })),
    [holdings]
  );

  const performanceData = useMemo(
    () => holdings.map((holding) => ({
      name: holding.ticker,
      value: asNumber(holding.gain_loss_pct)
    })),
    [holdings]
  );

  const submitHolding = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    try {
      await upsertHolding({
        ticker: form.ticker.toUpperCase(),
        shares: Number(form.shares),
        avgCost: Number(form.avgCost),
        currentPrice: form.currentPrice ? Number(form.currentPrice) : undefined
      });

      setForm({ ticker: '', shares: '', avgCost: '', currentPrice: '' });
      void queryClient.invalidateQueries({ queryKey: queryKeys.holdings() });
      void queryClient.invalidateQueries({ queryKey: queryKeys.portfolioSummary() });
      await loadPortfolio();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save holding');
    }
  };

  const queueRefresh = async () => {
    try {
      await queuePriceRefresh();
      void queryClient.invalidateQueries({ queryKey: queryKeys.recentTasks(20) });
      void queryClient.invalidateQueries({ queryKey: queryKeys.portfolioSummary() });
      await loadPortfolio();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to queue price refresh');
    }
  };

  const queueInsights = async () => {
    try {
      await queuePortfolioInsights();
      void queryClient.invalidateQueries({ queryKey: queryKeys.recentTasks(20) });
      void queryClient.invalidateQueries({ queryKey: queryKeys.latestPortfolioInsight() });
      await loadPortfolio();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to queue portfolio insights');
    }
  };

  if (isPending || !isAuthenticated) {
    return <div className="flex min-h-screen items-center justify-center text-sm text-[color:var(--terminal-muted)]">Loading portfolio matrix...</div>;
  }

  return (
    <AppShell
      title="Portfolio"
      subtitle="Position management, market valuation, and AI generated portfolio commentary."
      actions={(
        <>
          <Button variant="secondary" onClick={() => void queueRefresh()}>
            <RefreshCcw className="size-4" />
            Queue price refresh
          </Button>
          <Button onClick={() => void queueInsights()}>
            <BrainCircuit className="size-4" />
            Generate AI brief
          </Button>
        </>
      )}
    >
      {error ? (
        <Panel>
          <p className="text-sm text-[#ffb5b5]">{error}</p>
        </Panel>
      ) : null}

      <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
        <Panel title="Total Value" className="lg:col-span-1">
          <p className="text-3xl font-semibold text-[color:var(--terminal-bright)]">{formatCurrency(summary.total_value)}</p>
          <p className="mt-2 text-sm text-[color:var(--terminal-muted)]">Cost basis {formatCurrency(summary.total_cost_basis)}</p>
        </Panel>
        <Panel title="Unrealized P&L" className="lg:col-span-1">
          <p className={`text-3xl font-semibold ${asNumber(summary.total_gain_loss) >= 0 ? 'text-[#96f5bf]' : 'text-[#ff9f9f]'}`}>
            {formatCurrency(summary.total_gain_loss)}
          </p>
          <p className="mt-2 text-sm text-[color:var(--terminal-muted)]">Average return {formatPercent(summary.avg_return_pct)}</p>
        </Panel>
        <Panel title="Positions" className="lg:col-span-1">
          <p className="text-3xl font-semibold text-[color:var(--terminal-bright)]">{summary.positions}</p>
          <p className="mt-2 text-sm text-[color:var(--terminal-muted)]">Active symbols in portfolio.</p>
        </Panel>
      </div>

      <div className="grid grid-cols-1 gap-6 xl:grid-cols-2">
        <Panel title="Allocation">
          {loading ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">Loading chart...</p>
          ) : allocationData.length > 0 ? (
            <div className="h-[300px]">
              <ResponsiveContainer width="100%" height="100%">
                <PieChart>
                  <Pie data={allocationData} dataKey="value" nameKey="name" innerRadius={56} outerRadius={104} paddingAngle={2}>
                    {allocationData.map((entry, index) => (
                      <Cell key={`${entry.name}-${index}`} fill={CHART_COLORS[index % CHART_COLORS.length]} />
                    ))}
                  </Pie>
                  <Tooltip
                    formatter={(value: number | string | undefined) => formatCurrency(value)}
                    contentStyle={{
                      backgroundColor: CHART_TOOLTIP_BG,
                      border: `1px solid ${CHART_TOOLTIP_BORDER}`,
                      borderRadius: '0.75rem'
                    }}
                    labelStyle={{ color: CHART_TEXT }}
                    itemStyle={{ color: CHART_TEXT }}
                  />
                  <Legend
                    verticalAlign="bottom"
                    iconType="circle"
                    wrapperStyle={{ paddingTop: '0.75rem' }}
                    formatter={(value) => <span style={{ color: CHART_TEXT }}>{value}</span>}
                  />
                </PieChart>
              </ResponsiveContainer>
            </div>
          ) : (
            <p className="text-sm text-[color:var(--terminal-muted)]">No holdings yet.</p>
          )}
        </Panel>

        <Panel title="Performance %">
          {loading ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">Loading chart...</p>
          ) : performanceData.length > 0 ? (
            <div className="h-[300px]">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart data={performanceData}>
                  <CartesianGrid strokeDasharray="2 2" stroke={CHART_GRID} />
                  <XAxis
                    dataKey="name"
                    stroke={CHART_MUTED}
                    fontSize={12}
                    axisLine={{ stroke: CHART_MUTED }}
                    tickLine={{ stroke: CHART_MUTED }}
                    tick={{ fill: CHART_MUTED }}
                  />
                  <YAxis
                    stroke={CHART_MUTED}
                    fontSize={12}
                    axisLine={{ stroke: CHART_MUTED }}
                    tickLine={{ stroke: CHART_MUTED }}
                    tick={{ fill: CHART_MUTED }}
                  />
                  <Tooltip
                    formatter={(value: number | string | undefined) => `${asNumber(value).toFixed(2)}%`}
                    contentStyle={{
                      backgroundColor: CHART_TOOLTIP_BG,
                      border: `1px solid ${CHART_TOOLTIP_BORDER}`,
                      borderRadius: '0.75rem'
                    }}
                    labelStyle={{ color: CHART_TEXT }}
                    itemStyle={{ color: CHART_TEXT }}
                    cursor={{ fill: 'rgba(104, 255, 213, 0.08)' }}
                  />
                  <Bar dataKey="value" fill="#68ffd5" radius={[4, 4, 0, 0]} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          ) : (
            <p className="text-sm text-[color:var(--terminal-muted)]">No performance data yet.</p>
          )}
        </Panel>
      </div>

      <div className="grid grid-cols-1 gap-6 xl:grid-cols-[1.5fr_1fr]">
        <Panel title="Holdings Table" subtitle="Live mark-to-market values from latest refresh.">
          {loading ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">Loading holdings...</p>
          ) : holdings.length === 0 ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">No holdings added yet.</p>
          ) : (
            <div className="max-w-full overflow-x-auto">
              <table className="data-table min-w-[780px]">
                <thead>
                  <tr>
                    <th>Ticker</th>
                    <th>Shares</th>
                    <th>Avg Cost</th>
                    <th>Price</th>
                    <th>Value</th>
                    <th>Gain/Loss</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  {holdings.map((holding) => (
                    <tr key={holding.id}>
                      <td>{holding.ticker}</td>
                      <td>{asNumber(holding.shares).toLocaleString()}</td>
                      <td>{formatCurrency(holding.avg_cost)}</td>
                      <td>{holding.current_price ? formatCurrency(holding.current_price) : 'n/a'}</td>
                      <td>{formatCurrency(holding.market_value)}</td>
                      <td className={asNumber(holding.gain_loss) >= 0 ? 'text-[#96f5bf]' : 'text-[#ff9898]'}>
                        {formatCurrency(holding.gain_loss)} ({formatPercent(holding.gain_loss_pct)})
                      </td>
                      <td>
                        <Button
                          variant="danger"
                          className="px-2 py-1 text-xs"
                          onClick={async () => {
                            try {
                              await deleteHolding(holding.id);
                              void queryClient.invalidateQueries({ queryKey: queryKeys.holdings() });
                              void queryClient.invalidateQueries({ queryKey: queryKeys.portfolioSummary() });
                              await loadPortfolio();
                            } catch (err) {
                              setError(err instanceof Error ? err.message : 'Failed to delete holding');
                            }
                          }}
                        >
                          <Trash2 className="size-3" />
                          Delete
                        </Button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Panel>

        <Panel title="Add / Update Holding">
          <form onSubmit={submitHolding} className="space-y-3">
            <div>
              <label className="mb-1 block text-xs uppercase tracking-[0.16em] text-[color:var(--terminal-muted)]">Ticker</label>
              <Input value={form.ticker} onChange={(event) => setForm((prev) => ({ ...prev, ticker: event.target.value.toUpperCase() }))} required />
            </div>
            <div>
              <label className="mb-1 block text-xs uppercase tracking-[0.16em] text-[color:var(--terminal-muted)]">Shares</label>
              <Input type="number" step="0.0001" min="0.0001" value={form.shares} onChange={(event) => setForm((prev) => ({ ...prev, shares: event.target.value }))} required />
            </div>
            <div>
              <label className="mb-1 block text-xs uppercase tracking-[0.16em] text-[color:var(--terminal-muted)]">Average Cost</label>
              <Input type="number" step="0.0001" min="0.0001" value={form.avgCost} onChange={(event) => setForm((prev) => ({ ...prev, avgCost: event.target.value }))} required />
            </div>
            <div>
              <label className="mb-1 block text-xs uppercase tracking-[0.16em] text-[color:var(--terminal-muted)]">Current Price (optional)</label>
              <Input type="number" step="0.0001" min="0" value={form.currentPrice} onChange={(event) => setForm((prev) => ({ ...prev, currentPrice: event.target.value }))} />
            </div>
            <Button type="submit" className="w-full">
              <Plus className="size-4" />
              Save holding
            </Button>
          </form>

          <div className="mt-5 border-t border-[color:var(--line-weak)] pt-4">
            <p className="text-xs uppercase tracking-[0.2em] text-[color:var(--terminal-muted)]">Latest AI Insight</p>
            <p className="mt-2 whitespace-pre-wrap text-sm leading-6 text-[color:var(--terminal-bright)]">
              {latestInsight?.content ?? 'No insight available yet. Queue an AI brief from the header.'}
            </p>
          </div>
        </Panel>
      </div>
    </AppShell>
  );
}
