'use client';

import { useState, useEffect, useCallback } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  ResponsiveContainer,
  BarChart,
  Bar,
  XAxis,
  YAxis,
  Tooltip,
  Legend,
  CartesianGrid,
  RadarChart,
  PolarGrid,
  PolarAngleAxis,
  PolarRadiusAxis,
  Radar,
} from 'recharts';
import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
import { Users, RefreshCw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { cn } from '@/lib/utils';

interface UserOption {
  graphUserId: string;
  displayName: string;
  email: string;
  jobTitle: string | null;
  department: string | null;
}

interface DayData {
  date: string;
  hoursWorked: number;
  billableHours: number;
}

interface MonthData {
  month: string;
  hoursWorked: number;
  billableHours: number;
  daysWorked: number;
  teamsMessages: number;
  teamsPrivateMessages: number;
  teamsCalls: number;
  meetingsAttended: number;
  meetingsOrganized: number;
  emailsSent: number;
  emailsReceived: number;
  totalMeetings: number;
  clientMeetings: number;
  meetingDurationMinutes: number;
  zoomCalls: number;
  zoomClientCalls: number;
}

interface HistoryData {
  user: {
    id: string;
    displayName: string;
    email: string;
    jobTitle: string | null;
    department: string | null;
    autotaskResourceId: number | null;
  };
  daily: DayData[];
  monthly: MonthData[];
}

// Heat level class names — must be full strings for Tailwind to include them
const HEAT_CLASSES = [
  'bg-muted/50',
  'bg-emerald-100 dark:bg-emerald-950',
  'bg-emerald-300 dark:bg-emerald-800',
  'bg-emerald-500 dark:bg-emerald-600',
  'bg-emerald-700 dark:bg-emerald-400',
];

function hoursLevel(h: number): number {
  if (h <= 0) return 0;
  if (h < 2) return 1;
  if (h < 5) return 2;
  if (h < 7) return 3;
  return 4;
}

function ActivityHeatmap({ daily, tz }: { daily: DayData[]; tz: string }) {
  const dailyMap: Record<string, DayData> = {};
  for (const d of daily) dailyMap[d.date] = d;

  const today = new Date();
  today.setHours(0, 0, 0, 0);

  // Start from 52 weeks ago, padded back to Monday
  const startDate = new Date(today);
  startDate.setDate(startDate.getDate() - 363);
  const dow = (startDate.getDay() + 6) % 7; // Mon=0 … Sun=6
  startDate.setDate(startDate.getDate() - dow);

  const yearAgo = new Date(today);
  yearAgo.setFullYear(yearAgo.getFullYear() - 1);

  // Build weeks
  const weeks: Array<Array<{ date: string; inRange: boolean }>> = [];
  const cursor = new Date(startDate);
  while (cursor <= today) {
    const week: Array<{ date: string; inRange: boolean }> = [];
    for (let i = 0; i < 7; i++) {
      const key = cursor.toISOString().slice(0, 10);
      week.push({ date: key, inRange: cursor >= yearAgo && cursor <= today });
      cursor.setDate(cursor.getDate() + 1);
    }
    weeks.push(week);
  }

  // Month label: track where each month starts
  const monthLabels: Array<{ weekIndex: number; label: string }> = [];
  let lastMonth = -1;
  weeks.forEach((week, wi) => {
    const d = new Date(week[0].date + 'T00:00:00');
    const m = d.getMonth();
    if (m !== lastMonth) {
      monthLabels.push({
        weekIndex: wi,
        label: d.toLocaleDateString('en-US', { month: 'short', timeZone: tz }),
      });
      lastMonth = m;
    }
  });

  const DAY_LABELS = ['Mon', '', 'Wed', '', 'Fri', '', 'Sun'];

  return (
    <div className="overflow-x-auto pb-2">
      <div className="inline-flex gap-2 min-w-0">
        {/* Day labels */}
        <div className="flex flex-col gap-[3px] pt-5 shrink-0">
          {DAY_LABELS.map((label, i) => (
            <div key={i} className="h-[13px] flex items-center">
              <span className="text-[10px] text-muted-foreground w-6 text-right pr-1 leading-none">{label}</span>
            </div>
          ))}
        </div>

        {/* Grid */}
        <div className="flex flex-col">
          {/* Month labels */}
          <div className="flex mb-1 h-4 relative">
            {weeks.map((_, wi) => {
              const ml = monthLabels.find(m => m.weekIndex === wi);
              return (
                <div key={wi} className="w-[13px] shrink-0 relative">
                  {ml && (
                    <span className="absolute text-[10px] text-muted-foreground whitespace-nowrap leading-none">
                      {ml.label}
                    </span>
                  )}
                </div>
              );
            })}
          </div>

          {/* Cells */}
          <div className="flex gap-[3px]">
            {weeks.map((week, wi) => (
              <div key={wi} className="flex flex-col gap-[3px]">
                {week.map((cell, di) => {
                  const data = dailyMap[cell.date];
                  const hours = data?.hoursWorked ?? 0;
                  const level = cell.inRange ? hoursLevel(hours) : 0;
                  const isFuture = cell.date > today.toISOString().slice(0, 10);
                  return (
                    <div
                      key={di}
                      className={cn(
                        'w-[13px] h-[13px] rounded-[2px]',
                        isFuture ? 'opacity-0' : HEAT_CLASSES[level]
                      )}
                      title={
                        cell.inRange && !isFuture
                          ? `${cell.date}: ${hours.toFixed(1)}h (${(data?.billableHours ?? 0).toFixed(1)}h billable)`
                          : cell.date
                      }
                    />
                  );
                })}
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Legend */}
      <div className="flex items-center gap-1.5 mt-3 ml-8">
        <span className="text-[10px] text-muted-foreground">Less</span>
        {HEAT_CLASSES.map((cls, i) => (
          <div key={i} className={cn('w-[13px] h-[13px] rounded-[2px]', cls)} />
        ))}
        <span className="text-[10px] text-muted-foreground">More</span>
      </div>
    </div>
  );
}

function buildRadarData(monthly: MonthData[]) {
  const active = monthly.filter(m => m.hoursWorked > 0 || m.teamsMessages > 0 || m.emailsSent > 0);
  if (active.length === 0) return [];

  const avg = (fn: (m: MonthData) => number) =>
    active.reduce((s, m) => s + fn(m), 0) / active.length;

  const avgHours = avg(m => m.hoursWorked);
  const avgBillable = avg(m => m.billableHours);
  const avgMeetings = avg(m => m.totalMeetings);
  const avgComms = avg(m => m.teamsMessages + m.emailsSent);
  const avgCalls = avg(m => m.zoomClientCalls + m.teamsCalls);

  return [
    {
      subject: 'Utilization',
      value: Math.min(100, Math.round((avgHours / 160) * 100)),
      fullMark: 100,
    },
    {
      subject: 'Billable %',
      value: avgHours > 0 ? Math.round((avgBillable / avgHours) * 100) : 0,
      fullMark: 100,
    },
    {
      subject: 'Meetings',
      value: Math.min(100, Math.round((avgMeetings / 25) * 100)),
      fullMark: 100,
    },
    {
      subject: 'Comms',
      value: Math.min(100, Math.round((avgComms / 400) * 100)),
      fullMark: 100,
    },
    {
      subject: 'Client Calls',
      value: Math.min(100, Math.round((avgCalls / 15) * 100)),
      fullMark: 100,
    },
  ];
}

function monthLabel(m: string, tz: string) {
  return new Date(m + '-02').toLocaleDateString('en-US', { month: 'short', year: 'numeric', timeZone: tz });
}

interface BackfillStatus {
  running: boolean;
  started: string | null;
  processed: number;
  total: number;
  currentUser: string | null;
  errors: number;
  done: boolean;
  log: string[];
}

export default function EngagementProfilePage() {
  const tz = useUserTimezone();
  const [users, setUsers] = useState<UserOption[]>([]);
  const [usersLoading, setUsersLoading] = useState(true);
  const [selectedUserId, setSelectedUserId] = useState<string>('');
  const [history, setHistory] = useState<HistoryData | null>(null);
  const [historyLoading, setHistoryLoading] = useState(false);
  const [backfill, setBackfill] = useState<BackfillStatus | null>(null);
  const [backfillStarting, setBackfillStarting] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const res = await fetch('/api/engagement/users?period=D30&sort=display_name&order=asc');
        const data = await res.json();
        setUsers(data.users ?? []);
      } catch {}
      setUsersLoading(false);
    })();
  }, []);

  const loadHistory = useCallback(async (userId: string) => {
    setHistoryLoading(true);
    setHistory(null);
    try {
      const res = await fetch(`/api/engagement/user/${userId}/history`);
      const data = await res.json();
      setHistory(data);
    } catch {}
    setHistoryLoading(false);
  }, []);

  const handleSelect = (userId: string) => {
    setSelectedUserId(userId);
    loadHistory(userId);
  };

  const startBackfill = async () => {
    setBackfillStarting(true);
    try {
      await fetch('/api/engagement/backfill-meetings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ monthsBack: 12 }),
      });
      pollBackfill();
    } catch {}
    setBackfillStarting(false);
  };

  const pollBackfill = useCallback(async () => {
    const res = await fetch('/api/engagement/backfill-meetings').catch(() => null);
    if (!res) return;
    const data: BackfillStatus = await res.json();
    setBackfill(data);
    if (data.running) setTimeout(pollBackfill, 2000);
    else if (data.done && selectedUserId) loadHistory(selectedUserId);
  }, [selectedUserId, loadHistory]);

  useEffect(() => {
    fetch('/api/engagement/backfill-meetings').then(r => r.json()).then((d: BackfillStatus) => {
      setBackfill(d);
      if (d.running) setTimeout(pollBackfill, 2000);
    }).catch(() => {});
  }, [pollBackfill]);

  const monthly = history?.monthly ?? [];
  const radarData = buildRadarData(monthly);

  const totalHours = monthly.reduce((s, m) => s + m.hoursWorked, 0);
  const totalBillable = monthly.reduce((s, m) => s + m.billableHours, 0);
  const billablePct = totalHours > 0 ? Math.round((totalBillable / totalHours) * 100) : 0;
  const activeMonths = monthly.filter(m => m.hoursWorked > 0).length;
  const peakMonth = monthly.reduce(
    (best, m) => (m.hoursWorked > (best?.hoursWorked ?? 0) ? m : best),
    null as MonthData | null
  );

  const barData = monthly.map(m => ({
    name: m.month.slice(5),
    billable: parseFloat(m.billableHours.toFixed(1)),
    nonBillable: parseFloat((m.hoursWorked - m.billableHours).toFixed(1)),
  }));

  return (
    <div className="container mx-auto px-6 py-8 space-y-6">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold">Employee Profile</h1>
          <p className="text-muted-foreground text-sm mt-1">12-month activity overview</p>
        </div>

        <Select value={selectedUserId} onValueChange={handleSelect} disabled={usersLoading}>
          <SelectTrigger className="w-64">
            <SelectValue placeholder={usersLoading ? 'Loading…' : 'Select employee…'} />
          </SelectTrigger>
          <SelectContent>
            {users.map(u => (
              <SelectItem key={u.graphUserId} value={u.graphUserId}>
                <div className="flex flex-col items-start">
                  <span>{u.displayName}</span>
                  {u.jobTitle && (
                    <span className="text-xs text-muted-foreground">{u.jobTitle}</span>
                  )}
                </div>
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {/* Backfill panel */}
      {backfill && (backfill.running || backfill.done) ? (
        <Card className={cn('border', backfill.running ? 'border-blue-400' : backfill.errors > 0 ? 'border-yellow-400' : 'border-green-400')}>
          <CardContent className="py-3 px-4 space-y-2">
            <div className="flex items-center justify-between gap-4">
              <div className="flex items-center gap-2 text-sm font-medium">
                {backfill.running && <RefreshCw className="h-4 w-4 animate-spin text-blue-500" />}
                {backfill.running
                  ? `Backfilling meetings… ${backfill.processed}/${backfill.total} users`
                  : `Backfill complete — ${backfill.processed} users, ${backfill.errors} errors`}
              </div>
              {backfill.running && backfill.currentUser && (
                <span className="text-xs text-muted-foreground truncate">{backfill.currentUser}</span>
              )}
            </div>
            {backfill.running && backfill.total > 0 && (
              <div className="w-full bg-muted rounded-full h-1.5">
                <div
                  className="bg-blue-500 h-1.5 rounded-full transition-all"
                  style={{ width: `${Math.round((backfill.processed / backfill.total) * 100)}%` }}
                />
              </div>
            )}
            {backfill.log.length > 0 && (
              <pre className="text-[10px] text-muted-foreground max-h-24 overflow-y-auto bg-muted/30 rounded p-2">
                {backfill.log.slice(-20).join('\n')}
              </pre>
            )}
          </CardContent>
        </Card>
      ) : (
        <div className="flex justify-end">
          <Button
            variant="outline"
            size="sm"
            onClick={startBackfill}
            disabled={backfillStarting}
            className="gap-2"
          >
            <RefreshCw className={cn('h-3.5 w-3.5', backfillStarting && 'animate-spin')} />
            Backfill 12 months of meetings
          </Button>
        </div>
      )}

      {!selectedUserId && (
        <Card className="border-dashed">
          <CardContent className="flex flex-col items-center justify-center py-20 text-center">
            <Users className="h-10 w-10 text-muted-foreground mb-4" />
            <p className="font-medium">Select an employee</p>
            <p className="text-sm text-muted-foreground mt-1">
              Choose an employee above to see their 12-month activity profile
            </p>
          </CardContent>
        </Card>
      )}

      {selectedUserId && historyLoading && (
        <div className="space-y-4">
          {[...Array(4)].map((_, i) => (
            <Skeleton key={i} className="h-48" />
          ))}
        </div>
      )}

      {selectedUserId && !historyLoading && history && (
        <>
          {/* User header */}
          <div>
            <h2 className="text-xl font-semibold">{history.user.displayName}</h2>
            <div className="flex flex-wrap items-center gap-x-2 gap-y-0.5 mt-0.5 text-sm text-muted-foreground">
              {history.user.jobTitle && <span>{history.user.jobTitle}</span>}
              {history.user.jobTitle && history.user.department && <span>·</span>}
              {history.user.department && <span>{history.user.department}</span>}
              {(history.user.jobTitle || history.user.department) && <span>·</span>}
              <span>{history.user.email}</span>
            </div>
          </div>

          {/* Year stats */}
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
            <Card>
              <CardContent className="pt-4 pb-4">
                <p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">Total Hours</p>
                <p className="text-2xl font-bold tabular-nums">{totalHours.toFixed(0)}</p>
                <p className="text-xs text-muted-foreground">over 12 months</p>
              </CardContent>
            </Card>
            <Card>
              <CardContent className="pt-4 pb-4">
                <p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">Billable Rate</p>
                <p className="text-2xl font-bold tabular-nums">{billablePct}%</p>
                <p className="text-xs text-muted-foreground">{totalBillable.toFixed(0)}h billable</p>
              </CardContent>
            </Card>
            <Card>
              <CardContent className="pt-4 pb-4">
                <p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">Avg hrs / month</p>
                <p className="text-2xl font-bold tabular-nums">
                  {activeMonths > 0 ? (totalHours / activeMonths).toFixed(0) : '—'}
                </p>
                <p className="text-xs text-muted-foreground">{activeMonths} active months</p>
              </CardContent>
            </Card>
            <Card>
              <CardContent className="pt-4 pb-4">
                <p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">Peak Month</p>
                <p className="text-2xl font-bold tabular-nums">
                  {peakMonth ? peakMonth.hoursWorked.toFixed(0) + 'h' : '—'}
                </p>
                <p className="text-xs text-muted-foreground">
                  {peakMonth ? monthLabel(peakMonth.month, tz) : ''}
                </p>
              </CardContent>
            </Card>
          </div>

          {/* Activity heatmap */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm font-medium">Activity Calendar</CardTitle>
              <p className="text-xs text-muted-foreground">Daily hours worked — last 12 months</p>
            </CardHeader>
            <CardContent>
              {history.daily.length > 0 ? (
                <ActivityHeatmap daily={history.daily} tz={tz} />
              ) : (
                <p className="text-sm text-muted-foreground py-6 text-center">
                  No time entry data available
                </p>
              )}
            </CardContent>
          </Card>

          {/* Monthly bar chart + radar */}
          <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
            <Card className="lg:col-span-2">
              <CardHeader className="pb-3">
                <CardTitle className="text-sm font-medium">Monthly Hours</CardTitle>
                <p className="text-xs text-muted-foreground">Billable vs non-billable</p>
              </CardHeader>
              <CardContent>
                <ResponsiveContainer width="100%" height={220}>
                  <BarChart data={barData} margin={{ top: 5, right: 10, left: -20, bottom: 5 }}>
                    <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
                    <XAxis dataKey="name" tick={{ fontSize: 11 }} />
                    <YAxis tick={{ fontSize: 11 }} />
                    <Tooltip
                      formatter={(value, name) => [
                        `${value}h`,
                        name === 'billable' ? 'Billable' : 'Non-billable',
                      ]}
                      contentStyle={{ fontSize: 12 }}
                    />
                    <Legend
                      formatter={v => (v === 'billable' ? 'Billable' : 'Non-billable')}
                      wrapperStyle={{ fontSize: 11 }}
                    />
                    <Bar dataKey="billable" stackId="a" fill="#10b981" name="billable" />
                    <Bar dataKey="nonBillable" stackId="a" fill="#94a3b8" name="nonBillable" radius={[2, 2, 0, 0]} />
                  </BarChart>
                </ResponsiveContainer>
              </CardContent>
            </Card>

            <Card>
              <CardHeader className="pb-3">
                <CardTitle className="text-sm font-medium">Activity Signature</CardTitle>
                <p className="text-xs text-muted-foreground">12-month average profile</p>
              </CardHeader>
              <CardContent className="flex items-center justify-center pt-0">
                {radarData.length > 0 ? (
                  <RadarChart width={240} height={220} data={radarData}>
                    <PolarGrid />
                    <PolarAngleAxis dataKey="subject" tick={{ fontSize: 10 }} />
                    <PolarRadiusAxis
                      angle={90}
                      domain={[0, 100]}
                      tick={false}
                      axisLine={false}
                    />
                    <Radar
                      name="Profile"
                      dataKey="value"
                      stroke="#10b981"
                      fill="#10b981"
                      fillOpacity={0.3}
                    />
                  </RadarChart>
                ) : (
                  <p className="text-sm text-muted-foreground text-center py-8">No data</p>
                )}
              </CardContent>
            </Card>
          </div>

          {/* Monthly breakdown table */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm font-medium">Monthly Breakdown</CardTitle>
            </CardHeader>
            <CardContent className="p-0">
              <Table>
                <TableHeader>
                  <TableRow className="text-xs text-muted-foreground uppercase tracking-wide">
                    <TableHead>Month</TableHead>
                    <TableHead className="text-right">Hours</TableHead>
                    <TableHead className="text-right">Billable</TableHead>
                    <TableHead className="text-right">Bill %</TableHead>
                    <TableHead className="text-right hidden sm:table-cell">Days</TableHead>
                    <TableHead className="text-right hidden md:table-cell">Meetings</TableHead>
                    <TableHead className="text-right hidden md:table-cell">Messages</TableHead>
                    <TableHead className="text-right hidden lg:table-cell">Emails</TableHead>
                    <TableHead className="text-right hidden lg:table-cell">Calls</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {[...monthly].reverse().map(m => {
                    const pct = m.hoursWorked > 0 ? Math.round((m.billableHours / m.hoursWorked) * 100) : 0;
                    const isEmpty =
                      m.hoursWorked === 0 && m.teamsMessages === 0 && m.emailsSent === 0;
                    const totalCalls = m.zoomClientCalls + m.teamsCalls;
                    return (
                      <TableRow
                        key={m.month}
                        className={cn(isEmpty && 'opacity-40')}
                      >
                        <TableCell className="font-medium">{monthLabel(m.month, tz)}</TableCell>
                        <TableCell className="text-right num">
                          {m.hoursWorked > 0 ? m.hoursWorked.toFixed(1) : '—'}
                        </TableCell>
                        <TableCell className="text-right num text-emerald-600 dark:text-emerald-400">
                          {m.billableHours > 0 ? m.billableHours.toFixed(1) : '—'}
                        </TableCell>
                        <TableCell className="text-right num">
                          {m.hoursWorked > 0 ? `${pct}%` : '—'}
                        </TableCell>
                        <TableCell className="text-right num hidden sm:table-cell">
                          {m.daysWorked > 0 ? m.daysWorked : '—'}
                        </TableCell>
                        <TableCell className="text-right num hidden md:table-cell">
                          {m.totalMeetings > 0 ? m.totalMeetings : '—'}
                        </TableCell>
                        <TableCell className="text-right num hidden md:table-cell">
                          {m.teamsMessages > 0 ? m.teamsMessages : '—'}
                        </TableCell>
                        <TableCell className="text-right num hidden lg:table-cell">
                          {m.emailsSent > 0 ? m.emailsSent : '—'}
                        </TableCell>
                        <TableCell className="text-right num hidden lg:table-cell">
                          {totalCalls > 0 ? totalCalls : '—'}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </>
      )}
    </div>
  );
}
