'use client';

import { useQueryClient } from '@tanstack/react-query';
import Link from 'next/link';
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, SquarePen, 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 { useLinkPrefetch } from '@/hooks/use-link-prefetch';
import {
  deleteHolding,
  queuePortfolioInsights,
  queuePriceRefresh,
  updateHolding,
  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;
  companyName: 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 { prefetchResearchTicker } = useLinkPrefetch();

  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 [editingHoldingId, setEditingHoldingId] = useState<number | null>(null);
  const [form, setForm] = useState<FormState>({ ticker: '', companyName: '', 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.fetchQuery(holdingsOptions),
        queryClient.fetchQuery(summaryOptions),
        queryClient.fetchQuery(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 resetHoldingForm = useCallback(() => {
    setEditingHoldingId(null);
    setForm({ ticker: '', companyName: '', shares: '', avgCost: '', currentPrice: '' });
  }, []);

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

    try {
      if (editingHoldingId === null) {
        await upsertHolding({
          ticker: form.ticker.toUpperCase(),
          companyName: form.companyName.trim() || undefined,
          shares: Number(form.shares),
          avgCost: Number(form.avgCost),
          currentPrice: form.currentPrice ? Number(form.currentPrice) : undefined
        });
      } else {
        await updateHolding(editingHoldingId, {
          companyName: form.companyName.trim() || undefined,
          shares: Number(form.shares),
          avgCost: Number(form.avgCost),
          currentPrice: form.currentPrice ? Number(form.currentPrice) : undefined
        });
      }

      resetHoldingForm();
      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={(
        <div className="flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:flex-wrap sm:justify-end">
          <Button variant="secondary" className="w-full sm:w-auto" onClick={() => void queueRefresh()}>
            <RefreshCcw className="size-4" />
            Queue price refresh
          </Button>
          <Button className="w-full sm:w-auto" onClick={() => void queueInsights()}>
            <BrainCircuit className="size-4" />
            Generate AI brief
          </Button>
        </div>
      )}
    >
      {error ? (
        <Panel variant="surface">
          <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" variant="surface">
          {loading ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">Loading chart...</p>
          ) : allocationData.length > 0 ? (
            <div className="h-[260px] sm: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 %" variant="surface">
          {loading ? (
            <p className="text-sm text-[color:var(--terminal-muted)]">Loading chart...</p>
          ) : performanceData.length > 0 ? (
            <div className="h-[260px] sm: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." variant="surface">
          {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="space-y-3">
              <div className="space-y-3 lg:hidden">
                {holdings.map((holding) => (
                  <article key={holding.id} className="rounded-xl border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] p-4">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div>
                        <p className="text-sm font-semibold text-[color:var(--terminal-bright)]">{holding.ticker}</p>
                        <p className="mt-1 text-sm text-[color:var(--terminal-muted)]">{holding.company_name ?? 'Company name unavailable'}</p>
                      </div>
                      <p className={`text-sm font-medium ${asNumber(holding.gain_loss) >= 0 ? 'text-[#96f5bf]' : 'text-[#ff9898]'}`}>
                        {formatCurrency(holding.gain_loss)}
                      </p>
                    </div>

                    <dl className="mt-3 grid grid-cols-2 gap-2 text-xs">
                      <div className="rounded-md border border-[color:var(--line-weak)] px-2 py-1.5">
                        <dt className="text-[color:var(--terminal-muted)]">Shares</dt>
                        <dd className="mt-1 text-sm text-[color:var(--terminal-bright)]">{asNumber(holding.shares).toLocaleString()}</dd>
                      </div>
                      <div className="rounded-md border border-[color:var(--line-weak)] px-2 py-1.5">
                        <dt className="text-[color:var(--terminal-muted)]">Avg Cost</dt>
                        <dd className="mt-1 text-sm text-[color:var(--terminal-bright)]">{formatCurrency(holding.avg_cost)}</dd>
                      </div>
                      <div className="rounded-md border border-[color:var(--line-weak)] px-2 py-1.5">
                        <dt className="text-[color:var(--terminal-muted)]">Price</dt>
                        <dd className="mt-1 text-sm text-[color:var(--terminal-bright)]">{holding.current_price ? formatCurrency(holding.current_price) : 'n/a'}</dd>
                      </div>
                      <div className="rounded-md border border-[color:var(--line-weak)] px-2 py-1.5">
                        <dt className="text-[color:var(--terminal-muted)]">Value</dt>
                        <dd className="mt-1 text-sm text-[color:var(--terminal-bright)]">{formatCurrency(holding.market_value)}</dd>
                      </div>
                    </dl>

                    <p className={`mt-3 text-xs ${asNumber(holding.gain_loss) >= 0 ? 'text-[#96f5bf]' : 'text-[#ff9898]'}`}>
                      Return {formatPercent(holding.gain_loss_pct)}
                    </p>

                    <div className="mt-3 flex flex-wrap gap-2">
                      <Link
                        href={`/analysis?ticker=${holding.ticker}`}
                        onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                        onFocus={() => prefetchResearchTicker(holding.ticker)}
                        className="inline-flex items-center rounded-md border border-[color:var(--line-weak)] px-2 py-1 text-xs text-[color:var(--accent)] transition hover:border-[color:var(--line-strong)] hover:text-[color:var(--accent-strong)]"
                      >
                        Analysis
                      </Link>
                      <Link
                        href={`/financials?ticker=${holding.ticker}`}
                        onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                        onFocus={() => prefetchResearchTicker(holding.ticker)}
                        className="inline-flex items-center rounded-md border border-[color:var(--line-weak)] px-2 py-1 text-xs text-[color:var(--accent)] transition hover:border-[color:var(--line-strong)] hover:text-[color:var(--accent-strong)]"
                      >
                        Financials
                      </Link>
                      <Link
                        href={`/filings?ticker=${holding.ticker}`}
                        onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                        onFocus={() => prefetchResearchTicker(holding.ticker)}
                        className="inline-flex items-center rounded-md border border-[color:var(--line-weak)] px-2 py-1 text-xs text-[color:var(--accent)] transition hover:border-[color:var(--line-strong)] hover:text-[color:var(--accent-strong)]"
                      >
                        Filings
                      </Link>
                    </div>

                    <div className="mt-3 grid grid-cols-1 gap-2 sm:grid-cols-2">
                      <Button
                        variant="ghost"
                        className="px-2 py-1 text-xs"
                        onClick={() => {
                          setEditingHoldingId(holding.id);
                          setForm({
                            ticker: holding.ticker,
                            companyName: holding.company_name ?? '',
                            shares: String(asNumber(holding.shares)),
                            avgCost: String(asNumber(holding.avg_cost)),
                            currentPrice: holding.current_price ? String(asNumber(holding.current_price)) : ''
                          });
                        }}
                      >
                        <SquarePen className="size-3" />
                        Edit
                      </Button>
                      <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();
                            if (editingHoldingId === holding.id) {
                              resetHoldingForm();
                            }
                          } catch (err) {
                            setError(err instanceof Error ? err.message : 'Failed to delete holding');
                          }
                        }}
                      >
                        <Trash2 className="size-3" />
                        Delete
                      </Button>
                    </div>
                  </article>
                ))}
              </div>

              <div className="data-table-wrap hidden max-w-full lg:block">
                <table className="data-table min-w-[1020px]">
                  <thead>
                    <tr>
                      <th>Ticker</th>
                      <th>Company</th>
                      <th>Shares</th>
                      <th>Avg Cost</th>
                      <th>Price</th>
                      <th>Value</th>
                      <th>Gain/Loss</th>
                      <th>Research</th>
                      <th>Action</th>
                    </tr>
                  </thead>
                  <tbody>
                    {holdings.map((holding) => (
                      <tr key={holding.id}>
                        <td>{holding.ticker}</td>
                        <td>{holding.company_name ?? 'n/a'}</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>
                          <div className="flex flex-wrap gap-2">
                            <Link
                              href={`/analysis?ticker=${holding.ticker}`}
                              onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                              onFocus={() => prefetchResearchTicker(holding.ticker)}
                              className="text-xs text-[color:var(--accent)] hover:text-[color:var(--accent-strong)]"
                            >
                              Analysis
                            </Link>
                            <Link
                              href={`/financials?ticker=${holding.ticker}`}
                              onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                              onFocus={() => prefetchResearchTicker(holding.ticker)}
                              className="text-xs text-[color:var(--accent)] hover:text-[color:var(--accent-strong)]"
                            >
                              Financials
                            </Link>
                            <Link
                              href={`/filings?ticker=${holding.ticker}`}
                              onMouseEnter={() => prefetchResearchTicker(holding.ticker)}
                              onFocus={() => prefetchResearchTicker(holding.ticker)}
                              className="text-xs text-[color:var(--accent)] hover:text-[color:var(--accent-strong)]"
                            >
                              Filings
                            </Link>
                          </div>
                        </td>
                        <td>
                          <div className="flex flex-wrap gap-2">
                            <Button
                              variant="ghost"
                              className="px-2 py-1 text-xs"
                              onClick={() => {
                                setEditingHoldingId(holding.id);
                                setForm({
                                  ticker: holding.ticker,
                                  companyName: holding.company_name ?? '',
                                  shares: String(asNumber(holding.shares)),
                                  avgCost: String(asNumber(holding.avg_cost)),
                                  currentPrice: holding.current_price ? String(asNumber(holding.current_price)) : ''
                                });
                              }}
                            >
                              <SquarePen className="size-3" />
                              Edit
                            </Button>
                            <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();
                                  if (editingHoldingId === holding.id) {
                                    resetHoldingForm();
                                  }
                                } catch (err) {
                                  setError(err instanceof Error ? err.message : 'Failed to delete holding');
                                }
                              }}
                            >
                              <Trash2 className="size-3" />
                              Delete
                            </Button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </Panel>

        <Panel title={editingHoldingId === null ? 'Add Holding' : 'Edit Holding'} variant="surface">
          <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}
                aria-label="Holding ticker"
                disabled={editingHoldingId !== null}
                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)]">Company Name (optional)</label>
              <Input
                value={form.companyName}
                aria-label="Holding company name"
                onChange={(event) => setForm((prev) => ({ ...prev, companyName: event.target.value }))}
                placeholder="Resolved from coverage or filings if left blank"
              />
            </div>
            <div>
              <label className="mb-1 block text-xs uppercase tracking-[0.16em] text-[color:var(--terminal-muted)]">Shares</label>
              <Input aria-label="Holding shares" 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 aria-label="Holding average cost" 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 aria-label="Holding current price" type="number" step="0.0001" min="0" value={form.currentPrice} onChange={(event) => setForm((prev) => ({ ...prev, currentPrice: event.target.value }))} />
            </div>
            <div className="flex flex-wrap gap-2">
              <Button type="submit" className="w-full sm:flex-1">
                <Plus className="size-4" />
                {editingHoldingId === null ? 'Save holding' : 'Update holding'}
              </Button>
              {editingHoldingId !== null ? (
                <Button type="button" variant="ghost" className="w-full sm:w-auto" onClick={resetHoldingForm}>
                  Cancel
                </Button>
              ) : null}
            </div>
          </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>
  );
}
