import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import {
  Loader2,
  TrendingUp,
  TrendingDown,
  Minus,
  AlertTriangle,
  Calendar,
  Sparkles,
  CheckCircle2,
  Circle,
  CircleDot,
  Clock,
  ArrowRight,
  ChevronDown,
} from "lucide-react";
import { AppShell } from "@/components/AppShell";
import { PageHeader } from "@/components/PageHeader";
import { BriefingSkeleton } from "@/components/BriefingSkeleton";
import { Button } from "@/components/ui/button";
import { Sources } from "@/components/Sources";
import { useBriefing } from "@/hooks/useBriefing";
import { useHotels } from "@/hooks/useHotels";
import { useT } from "@/hooks/useSettings";
import { actionId, useActionMonitor, type ActionStatus } from "@/lib/actionMonitor";
import { useDismissedActions } from "@/lib/dismissedActions";
import { dailyDismissKey } from "@/hooks/useActionPlanSummary";
import { XCircle, Undo2 } from "lucide-react";
import type { Action, Alert, MarketSignal, NewsItem, Summary } from "@/lib/briefing.functions";
import { ExternalLink } from "lucide-react";

export const Route = createFileRoute("/")({
  head: () => ({
    meta: [
      { title: "Today's Brief — The Daily Ledger" },
      {
        name: "description",
        content:
          "30-second daily briefing for hoteliers — outlook, demand, competitor pricing, and the 3 moves to make today.",
      },
      { property: "og:title", content: "Today's Brief — The Daily Ledger" },
      {
        property: "og:description",
        content: "Your hotel's daily summary plus the 3 moves to take today.",
      },
    ],
  }),
  component: TodayPage,
});

function TodayPage() {
  const { hotel, hotels, isAllHotels, briefing, core, isHotelLoading, isCoreLoading, isBriefingLoading, coreError, refresh } = useBriefing();
  const error = coreError;
  const monitor = useActionMonitor();
  const dismissed = useDismissedActions();
  const t = useT();

  if (isHotelLoading) {
    return (
      <div className="flex min-h-dvh items-center justify-center">
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  if (isAllHotels || !hotel) {
    return (
      <AppShell hotel={null} isLoading={false} onRefresh={refresh}>
        <PageHeader
          eyebrow={t("portfolio.eyebrow")}
          title={t(hotels.length === 1 ? "portfolio.titleSingular" : "portfolio.titlePlural", { n: hotels.length })}
          subtitle={t("portfolio.subtitleHint")}
        />
        <div className="grid gap-4 sm:grid-cols-2">
          {hotels.map((h) => (
            <PortfolioHotelCard key={h.id} hotel={h} />
          ))}
        </div>
      </AppShell>
    );
  }

  return (
    <AppShell hotel={hotel} isLoading={isBriefingLoading} onRefresh={refresh}>
      <PageHeader
        eyebrow={t("today.eyebrow")}
        title={core?.greeting ?? t("today.title.fallback", { name: hotel.hotelier_name })}
        subtitle={core?.headline ?? t("today.subtitle.fallback", { hotel: hotel.hotel_name })}
      />

      {error && !core ? (
        <ErrorBlock message={(error as Error).message} onRetry={refresh} />
      ) : isCoreLoading || !core ? (
        <BriefingSkeleton />
      ) : (
        <div className="space-y-8">
          {core.alerts.length > 0 ? (
            <div className="grid gap-2">
              {core.alerts.map((a, i) => (
                <AlertRow key={i} alert={a} />
              ))}
            </div>
          ) : null}

          <section>
            <SectionLabel>{t("today.summary.title")}</SectionLabel>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
              <SummaryCard
                label={t("today.summary.occupancy")}
                value={t(`occupancy.${core.summary.occupancy_outlook}`, core.summary.occupancy_outlook)}
                tone={summaryTone(core.summary, "occupancy")}
                note={core.summary.occupancy_outlook_note}
              />
              <SummaryCard
                label={t("today.summary.demand")}
                value={t(`demand.${core.summary.market_demand}`, core.summary.market_demand)}
                tone={summaryTone(core.summary, "demand")}
                note={core.summary.market_demand_note}
              />
              <SummaryCard
                label={t("today.summary.pricing")}
                value={`${t(`pricing.${core.summary.competitor_pricing}`, core.summary.competitor_pricing)}${
                  core.summary.pricing_delta_pct
                    ? ` (${core.summary.pricing_delta_pct > 0 ? "+" : ""}${core.summary.pricing_delta_pct.toFixed(0)}%)`
                    : ""
                }`}
                tone={summaryTone(core.summary, "pricing")}
                note={core.summary.competitor_pricing_note}
              />
            </div>
            <Sources items={core.summary.sources} label={t("common.backedBy")} />
          </section>

          <section>
            <SectionLabel>{t("today.recommendedActions")}</SectionLabel>
            <div className="space-y-3">
              {core.actions
                .filter((a) => !dismissed.has(dailyDismissKey(a)))
                .map((a, i) => (
                  <ActionRow
                    key={actionId(a)}
                    index={i + 1}
                    action={a}
                    status={monitor.getStatus(actionId(a))}
                    onChange={(s) => monitor.setStatus(actionId(a), s)}
                    onDismiss={() => dismissed.dismiss(dailyDismissKey(a), a.title)}
                  />
                ))}
            </div>
            {core.actions.some((a) => dismissed.has(dailyDismissKey(a))) && (
              <div className="mt-3 rounded-xl border border-dashed bg-muted/20 p-3">
                <div className="mb-2 flex items-center gap-1.5 text-[10px] uppercase tracking-wider text-muted-foreground">
                  <XCircle className="h-3 w-3" /> Dismissed
                </div>
                <ul className="space-y-1.5">
                  {core.actions
                    .filter((a) => dismissed.has(dailyDismissKey(a)))
                    .map((a) => (
                      <li key={actionId(a)} className="flex items-center justify-between gap-3 text-xs">
                        <span className="line-through text-muted-foreground">{a.title}</span>
                        <Button
                          size="sm"
                          variant="ghost"
                          className="h-6 gap-1 px-2 text-[11px]"
                          onClick={() => dismissed.restore(dailyDismissKey(a))}
                        >
                          <Undo2 className="h-3 w-3" /> Restore
                        </Button>
                      </li>
                    ))}
                </ul>
              </div>
            )}
          </section>

          <section>
            <SectionLabel>{t("today.marketSignals")}</SectionLabel>
            <div className="grid gap-3 sm:grid-cols-2">
              {core.market_signals.map((s, i) => (
                <MarketSignalCard key={i} signal={s} />
              ))}
            </div>
          </section>

          {core.industry_news && core.industry_news.length > 0 ? (
            <section>
              <SectionLabel>Malaysia hotel industry news</SectionLabel>
              <ul className="grid gap-3">
                {core.industry_news.map((n, i) => (
                  <IndustryNewsCard key={i} item={n} />
                ))}
              </ul>
            </section>
          ) : null}
        </div>
      )}
    </AppShell>
  );
}


function PortfolioHotelCard({ hotel }: { hotel: { id: string; hotel_name: string; location: string; rooms: number; segment: string | null; star_rating: number | null } }) {
  const { selectHotel } = useHotels();
  const t = useT();
  return (
    <article className="flex flex-col gap-3 rounded-2xl border bg-card p-5 shadow-[var(--shadow-elegant)]">
      <div>
        <div className="text-[10px] uppercase tracking-wider text-muted-foreground">{hotel.segment ?? t("portfolio.defaultProperty")}</div>
        <h3 className="mt-1 font-serif text-lg font-medium text-foreground">{hotel.hotel_name}</h3>
        <div className="text-xs text-muted-foreground">{hotel.location}</div>
      </div>
      <div className="flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground">
        {hotel.rooms ? <span>{hotel.rooms} {t("portfolio.rooms")}</span> : null}
        {hotel.star_rating ? <span>{hotel.star_rating}★</span> : null}
      </div>
      <Button
        size="sm"
        className="mt-auto"
        onClick={() => selectHotel(hotel.id)}
      >
        {t("portfolio.viewBriefBtn")}
      </Button>
    </article>
  );
}

// ============= Helpers =============


function summaryTone(summary: Summary, key: "occupancy" | "demand" | "pricing"): "good" | "warn" | "neutral" {
  if (key === "occupancy") {
    if (summary.occupancy_outlook === "HIGH") return "good";
    if (summary.occupancy_outlook === "LOW") return "warn";
    return "neutral";
  }
  if (key === "demand") {
    if (summary.market_demand === "STRONG") return "good";
    if (summary.market_demand === "WEAK") return "warn";
    return "neutral";
  }
  // pricing — being LOWER (priced below market) is a warn for revenue
  if (summary.competitor_pricing === "HIGHER") return "warn"; // we're above market
  if (summary.competitor_pricing === "LOWER") return "warn"; // we're below market
  return "good"; // INLINE
}

function SectionLabel({ children }: { children: React.ReactNode }) {
  return (
    <div className="mb-3 text-[11px] font-medium uppercase tracking-[0.2em] text-accent">
      {children}
    </div>
  );
}

function SummaryCard({
  label,
  value,
  tone,
  note,
}: {
  label: string;
  value: string;
  tone: "good" | "warn" | "neutral";
  note: string;
}) {
  const styles = {
    good: "border-emerald-500/30 bg-emerald-500/5",
    warn: "border-amber-500/40 bg-amber-500/5",
    neutral: "border-border bg-card",
  }[tone];
  const valueColor = {
    good: "text-emerald-700",
    warn: "text-amber-800",
    neutral: "text-foreground",
  }[tone];
  const Icon = tone === "good" ? TrendingUp : tone === "warn" ? TrendingDown : Minus;
  return (
    <article className={`rounded-2xl border p-5 shadow-[var(--shadow-elegant)] ${styles}`}>
      <div className="flex items-center justify-between text-[11px] uppercase tracking-wider text-muted-foreground">
        <span>{label}</span>
        <Icon className="h-3.5 w-3.5" />
      </div>
      <div className={`mt-2 font-serif text-2xl font-medium tracking-tight ${valueColor}`}>
        {value}
      </div>
      <p className="mt-2 text-sm leading-relaxed text-muted-foreground">{note}</p>
    </article>
  );
}

function AlertRow({ alert }: { alert: Alert }) {
  const t = useT();
  const [open, setOpen] = useState(false);
  const styles = {
    info: "border-accent/30 bg-accent/5 text-foreground",
    warning: "border-amber-500/40 bg-amber-500/10 text-amber-900",
    critical: "border-destructive/40 bg-destructive/10 text-destructive",
  }[alert.level];
  const emoji = {
    occupancy_low: "⚠️",
    comp_price_drop: "📉",
    demand_spike: "📈",
    event: "🎫",
    holiday: "🎉",
  }[alert.icon];
  const hasDetails = (alert.sources?.length ?? 0) > 0;
  return (
    <div className={`rounded-xl border px-4 py-3 text-sm leading-relaxed ${styles}`}>
      <button
        type="button"
        onClick={() => hasDetails && setOpen((v) => !v)}
        disabled={!hasDetails}
        aria-expanded={open}
        className="flex w-full items-center gap-3 text-left"
      >
        <span className="text-base leading-none">{emoji}</span>
        <span className="flex-1">{alert.message}</span>
        {hasDetails ? (
          <ChevronDown
            className={`h-4 w-4 shrink-0 opacity-70 transition-transform ${open ? "rotate-180" : ""}`}
          />
        ) : null}
      </button>
      {open && hasDetails ? (
        <div className="mt-3 border-t border-current/15 pt-3">
          <Sources items={alert.sources} label={t("common.backedBy")} />
        </div>
      ) : null}
    </div>
  );
}

function ActionRow({
  index,
  action,
  status,
  onChange,
  onDismiss,
}: {
  index: number;
  action: Action;
  status: ActionStatus;
  onChange: (s: ActionStatus) => void;
  onDismiss?: () => void;
}) {
  const t = useT();
  const urgencyLabel = t(`urgency.${action.urgency}`);
  const urgencyColor = {
    today: "text-destructive",
    this_week: "text-amber-700",
    this_month: "text-muted-foreground",
  }[action.urgency];
  const wrapperStyles: Record<ActionStatus, string> = {
    todo: "border-border bg-card",
    in_progress: "border-accent/40 bg-accent/5",
    done: "border-emerald-500/30 bg-emerald-500/5",
  };
  return (
    <article
      className={`rounded-2xl border p-4 shadow-[var(--shadow-elegant)] transition-colors sm:p-5 ${wrapperStyles[status]}`}
    >
      <div className="flex items-start gap-3 sm:gap-4">
        <div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-brand font-serif text-sm font-medium text-primary-foreground sm:h-9 sm:w-9 sm:text-base">
          {index}
        </div>
        <div className="min-w-0 flex-1">
          <div className="mb-1 flex flex-wrap items-center gap-x-3 gap-y-1">
            <span className="text-[10px] font-medium uppercase tracking-wider text-accent">
              {action.category}
            </span>
            <span
              className={`inline-flex items-center gap-1 text-[10px] font-medium uppercase tracking-wider ${urgencyColor}`}
            >
              <Clock className="h-3 w-3" /> {urgencyLabel}
            </span>
          </div>
          <h3
            className={`font-serif text-base font-medium leading-snug sm:text-lg ${
              status === "done" ? "text-muted-foreground line-through" : "text-foreground"
            }`}
          >
            {action.title}
          </h3>
          <p className="mt-1.5 text-sm leading-relaxed text-muted-foreground">{action.why}</p>
          <Sources items={action.sources} label={t("common.why")} />
        </div>
        {onDismiss ? (
          <Button
            size="sm"
            variant="ghost"
            className="h-7 shrink-0 gap-1 px-2 text-xs text-muted-foreground"
            onClick={onDismiss}
            title="Dismiss this action"
          >
            <XCircle className="h-3.5 w-3.5" /> Dismiss
          </Button>
        ) : null}
      </div>

      {/* status switcher — equal thirds, never overflow */}
      <div className="mt-4 grid w-full grid-cols-3 gap-0.5 rounded-lg border bg-background/60 p-0.5 sm:mt-3">
        {(
          [
            { v: "todo" as const, label: t("status.todo"), Icon: Circle },
            { v: "in_progress" as const, label: t("status.doing"), Icon: CircleDot },
            { v: "done" as const, label: t("status.done"), Icon: CheckCircle2 },
          ]
        ).map(({ v, label, Icon }) => (
          <button
            key={v}
            onClick={() => onChange(v)}
            className={`inline-flex min-w-0 items-center justify-center gap-1 rounded-md px-1 py-1.5 text-[11px] font-medium transition-colors ${
              status === v
                ? "bg-brand text-primary-foreground shadow-sm"
                : "text-muted-foreground hover:text-foreground"
            }`}
          >
            <Icon className="h-3 w-3 shrink-0" />
            <span className="truncate">{label}</span>
          </button>
        ))}
      </div>
    </article>
  );
}

function MarketSignalCard({ signal }: { signal: MarketSignal }) {
  const t = useT();
  const typeLabel = t(`signal.${signal.type}`);
  const impactStyle = {
    surge: "bg-emerald-500/10 text-emerald-700 border-emerald-500/30",
    uptick: "bg-accent/15 text-accent border-accent/30",
    soft: "bg-amber-500/10 text-amber-800 border-amber-500/30",
    neutral: "bg-muted text-muted-foreground border-border",
  }[signal.expected_impact];
  const Icon =
    signal.type === "event" ? Sparkles : signal.type === "tourism_trend" ? TrendingUp : Calendar;
  return (
    <article className="rounded-2xl border bg-card p-5 shadow-[var(--shadow-elegant)]">
      <div className="flex items-start justify-between gap-3">
        <div className="inline-flex items-center gap-2 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
          <Icon className="h-3.5 w-3.5 text-accent" />
          {typeLabel}
        </div>
        <span
          className={`shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-medium uppercase tracking-wider ${impactStyle}`}
        >
          {t(`impact.${signal.expected_impact}`)}
        </span>
      </div>
      <h3 className="mt-2 font-serif text-base font-medium text-foreground">{signal.title}</h3>
      <div className="mt-1 text-xs text-muted-foreground">{signal.date_range}</div>
      <div className="mt-3 flex items-start gap-2 rounded-lg bg-brand-soft/40 px-3 py-2 text-sm text-brand">
        <ArrowRight className="mt-0.5 h-3.5 w-3.5 shrink-0" />
        <span>{signal.recommended_move}</span>
      </div>
      <Sources items={signal.sources} />
    </article>
  );
}

function IndustryNewsCard({ item }: { item: NewsItem }) {
  const primary = item.sources?.[0];
  const Wrap: React.ElementType = primary?.url ? "a" : "div";
  const linkProps = primary?.url
    ? { href: primary.url, target: "_blank", rel: "noopener noreferrer" }
    : {};
  return (
    <li>
      <article className="rounded-2xl border bg-card p-5 shadow-[var(--shadow-elegant)]">
        <div className="flex items-center justify-between gap-3">
          <span className="inline-flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
            {item.category}
          </span>
          {primary?.publisher ? (
            <span className="truncate text-[10px] uppercase tracking-wider text-muted-foreground">
              {primary.publisher}
            </span>
          ) : null}
        </div>
        <Wrap {...linkProps} className="group mt-2 block">
          <h3 className="font-serif text-base font-medium text-foreground group-hover:text-brand">
            {item.headline}
            {primary?.url ? <ExternalLink className="ml-1 inline h-3 w-3 opacity-60" /> : null}
          </h3>
        </Wrap>
        <p className="mt-1 text-sm text-muted-foreground">{item.summary}</p>
        {item.insight ? (
          <div className="mt-3 flex items-start gap-2 rounded-lg bg-brand-soft/40 px-3 py-2 text-sm text-brand">
            <ArrowRight className="mt-0.5 h-3.5 w-3.5 shrink-0" />
            <span>{item.insight}</span>
          </div>
        ) : null}
        <Sources items={item.sources} />
      </article>
    </li>
  );
}

function ErrorBlock({ message, onRetry }: { message: string; onRetry: () => void }) {
  const t = useT();
  return (
    <div className="rounded-2xl border border-destructive/30 bg-destructive/5 p-6 text-sm text-destructive">
      <div className="flex items-center gap-2">
        <AlertTriangle className="h-4 w-4" />
        <strong className="font-semibold">{t("today.error.title")}</strong>
      </div>
      <p className="mt-1 text-destructive/80">{message}</p>
      <Button size="sm" variant="outline" className="mt-4" onClick={onRetry}>
        {t("common.tryAgain")}
      </Button>
    </div>
  );
}
