'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { PieChart, Pie, Cell, Tooltip, 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 { StatusPill } from '@/components/ui/status-pill';
import { useAuthGuard } from '@/hooks/use-auth-guard';
import { useTaskPoller } from '@/hooks/use-task-poller';
import {
  deleteHolding,
  getLatestPortfolioInsight,
  getTask,
  getPortfolioSummary,
  listHoldings,
  queuePortfolioInsights,
  queuePriceRefresh,
  upsertHolding
} from '@/lib/api';
import type { Holding, PortfolioInsight, PortfolioSummary, Task } from '@/lib/types';
import { asNumber, formatCurrency, formatPercent } from '@/lib/format';

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

const CHART_COLORS = ['#6effd8', '#5fd3ff', '#66ffa1', '#8dbbff', '#f4f88f', '#ff9c9c'];

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 [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 [activeTask, setActiveTask] = useState<Task | null>(null);
  const [form, setForm] = useState<FormState>({ ticker: '', shares: '', avgCost: '', currentPrice: '' });

  const loadPortfolio = useCallback(async () => {
    setLoading(true);
    setError(null);

    try {
      const [holdingsRes, summaryRes, insightRes] = await Promise.all([
        listHoldings(),
        getPortfolioSummary(),
        getLatestPortfolioInsight()
      ]);

      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);
    }
  }, []);

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

  const polledTask = useTaskPoller({
    taskId: activeTask?.id ?? null,
    onTerminalState: async () => {
      setActiveTask(null);
      await loadPortfolio();
    }
  });

  const liveTask = polledTask ?? activeTask;

  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: '' });
      await loadPortfolio();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save holding');
    }
  };

  const queueRefresh = async () => {
    try {
      const { task } = await queuePriceRefresh();
      const latest = await getTask(task.id);
      setActiveTask(latest.task);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to queue price refresh');
    }
  };

  const queueInsights = async () => {
    try {
      const { task } = await queuePortfolioInsights();
      const latest = await getTask(task.id);
      setActiveTask(latest.task);
    } 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 Matrix"
      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>
        </>
      )}
    >
      {liveTask ? (
        <Panel title="Task Runner" subtitle={liveTask.id}>
          <div className="flex items-center justify-between rounded-lg border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] px-3 py-2">
            <p className="text-sm text-[color:var(--terminal-bright)]">{liveTask.task_type}</p>
            <StatusPill status={liveTask.status} />
          </div>
          {liveTask.error ? <p className="mt-2 text-sm text-[#ff9f9f]">{liveTask.error}</p> : null}
        </Panel>
      ) : null}

      {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)} />
                </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="rgba(126, 217, 255, 0.2)" />
                  <XAxis dataKey="name" stroke="#8cb6c5" fontSize={12} />
                  <YAxis stroke="#8cb6c5" fontSize={12} />
                  <Tooltip formatter={(value: number | string | undefined) => `${asNumber(value).toFixed(2)}%`} />
                  <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="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);
                              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>
  );
}
