"use client";

import Link from "next/link";
import { useMemo, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Kpi, KpiStrip } from "@/components/ui/kpi";
import { EmptyState } from "@/components/ui/empty-state";
import {
  SegmentedControl,
  SegmentedControlItem,
} from "@/components/ui/segmented-control";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import type { EntityStatus, EntityType, Organization } from "@/lib/sag/types";

// ──────────────────────────────────────────────────────────────────────────
// Constants
// ──────────────────────────────────────────────────────────────────────────

const SOS_FILING_URL = "https://www.sosnc.gov/online_services/business_registration";

// Entity types that owe an NC annual report.
const FILING_ENTITY_TYPES = new Set<EntityType>(["LLC", "C-Corp", "S-Corp", "Corp", "Series LLC"]);

const STATUS_TONE: Record<EntityStatus, "outline" | "info" | "success" | "destructive" | "warning"> = {
  Active: "success",
  Forming: "info",
  "Administratively Dissolved": "destructive",
  Dissolved: "outline",
  "On Hold": "warning",
};

type FilterMode = "all" | "missing" | "byType";
type SortMode = "name" | "formationDate";

// ──────────────────────────────────────────────────────────────────────────
// Field model — every value the NC SoS annual report asks for. `present` is
// derived from the Organization record; "—" if missing. Anything not on the
// Organization type today is flagged `availableInModel: false` so the gap is
// visible in the UI and reported back to the maintainer.
// ──────────────────────────────────────────────────────────────────────────

interface ReportField {
  label: string;
  value: string | undefined;
  /** True when the Organization type carries this field today. */
  availableInModel: boolean;
}

function buildFields(org: Organization): ReportField[] {
  return [
    { label: "Entity Name", value: org.name, availableInModel: true },
    {
      label: "Entity Type",
      value: org.entityType,
      availableInModel: true,
    },
    {
      label: "NC SoS ID",
      value: org.ncSosFileNumber,
      availableInModel: true,
    },
    {
      label: "State of formation",
      value: org.state,
      availableInModel: true,
    },
    {
      label: "Formation date",
      value: org.formationDate,
      availableInModel: true,
    },
    // The fields below are not yet on `Organization`. They show as missing so
    // Glenn can see the gap; once added to entities.ts they will fill in.
    {
      label: "Principal Office Address",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "Mailing Address",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "Registered Agent",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "Registered Agent Address",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "Managers / Members / Officers",
      value: org.coOwners,
      availableInModel: true,
    },
    {
      label: "Email",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "Phone",
      value: undefined,
      availableInModel: false,
    },
    {
      label: "NAICS code",
      value: undefined,
      availableInModel: false,
    },
  ];
}

function isComplete(fields: ReportField[]): boolean {
  return fields.every((f) => f.value && f.value.trim() !== "");
}

function countMissing(fields: ReportField[]): number {
  return fields.filter((f) => !f.value || f.value.trim() === "").length;
}

function buildPlainTextSummary(org: Organization, fields: ReportField[]): string {
  const header = `NC SoS annual report — ${org.name}${org.dba ? ` (dba ${org.dba})` : ""}`;
  const lines = fields.map((f) => `${f.label}: ${f.value ?? "(missing — fill in entity record)"}`);
  const footer = `\nFile online: ${SOS_FILING_URL}`;
  return [header, "", ...lines, footer].join("\n");
}

// ──────────────────────────────────────────────────────────────────────────
// Main component
// ──────────────────────────────────────────────────────────────────────────

export function AnnualReportPrefill() {
  const [filterMode, setFilterMode] = useState<FilterMode>("all");
  const [typeFilter, setTypeFilter] = useState<EntityType | "all">("all");
  const [sortMode, setSortMode] = useState<SortMode>("name");
  const [copiedSlug, setCopiedSlug] = useState<string | null>(null);

  // Eligible entities: only LLCs / Corps. Skip Sole Prop / Non-profit /
  // owner-investment / external-employer entries.
  const eligibleEntities = useMemo(
    () =>
      ALL_ORGANIZATIONS.filter(
        (o) =>
          FILING_ENTITY_TYPES.has(o.entityType) &&
          (o.parentRelationship === undefined ||
            o.parentRelationship === "subsidiary" ||
            o.parentRelationship === "joint-venture" ||
            o.parentId === null), // SAG parent itself has parentId null + no relationship.
      ).filter(
        // Drop owner-investment and external-employer rows even though they
        // are C-Corps — SAG isn't the one filing those reports.
        (o) =>
          o.parentRelationship !== "owner-investment" &&
          o.parentRelationship !== "external-employer" &&
          o.parentRelationship !== "managed-artist",
      ),
    [],
  );

  // KPI rollups.
  const stats = useMemo(() => {
    let complete = 0;
    let missing = 0;
    for (const org of eligibleEntities) {
      const fields = buildFields(org);
      if (isComplete(fields)) complete += 1;
      else missing += 1;
    }
    return {
      total: eligibleEntities.length,
      complete,
      missing,
    };
  }, [eligibleEntities]);

  // Apply filter + sort.
  const visible = useMemo(() => {
    let list = eligibleEntities.slice();

    if (filterMode === "missing") {
      list = list.filter((o) => !isComplete(buildFields(o)));
    } else if (filterMode === "byType" && typeFilter !== "all") {
      list = list.filter((o) => o.entityType === typeFilter);
    }

    list.sort((a, b) => {
      if (sortMode === "formationDate") {
        const da = a.formationDate ?? "";
        const db = b.formationDate ?? "";
        // Empty formation dates float to the bottom.
        if (!da && !db) return a.name.localeCompare(b.name);
        if (!da) return 1;
        if (!db) return -1;
        return da.localeCompare(db);
      }
      return a.name.localeCompare(b.name);
    });

    return list;
  }, [eligibleEntities, filterMode, typeFilter, sortMode]);

  // Distinct entity types found in the eligible list (for the type filter).
  const availableTypes = useMemo(() => {
    const s = new Set<EntityType>();
    for (const o of eligibleEntities) s.add(o.entityType);
    return Array.from(s).sort();
  }, [eligibleEntities]);

  async function copySummary(org: Organization, fields: ReportField[]) {
    const text = buildPlainTextSummary(org, fields);
    try {
      await navigator.clipboard.writeText(text);
      setCopiedSlug(org.slug);
      window.setTimeout(() => {
        setCopiedSlug((s) => (s === org.slug ? null : s));
      }, 1800);
    } catch {
      // Fallback: if clipboard API is blocked, drop the text in a prompt the
      // user can copy from manually. Keeps the UX usable in restricted
      // browser contexts without throwing.
      window.prompt("Copy the summary below:", text);
    }
  }

  return (
    <div className="space-y-6">
      {/* Header explainer */}
      <Card>
        <CardContent className="p-6">
          <p className="text-sm text-muted-foreground">
            North Carolina requires LLCs and corporations to file an annual report each
            year. This page surfaces the required fields per entity, pre-filled from the
            entity registry, plus the online filing link. SAG&apos;s LLCs file by April
            15; C-corps file by the 15th day of the 4th month after fiscal year-end
            (typically April 15). This view is read-only — edits happen on the entity
            record itself.
          </p>
        </CardContent>
      </Card>

      {/* KPI strip */}
      <KpiStrip cols={3}>
        <Kpi label="Filing entities" value={String(stats.total)} />
        <Kpi
          label="All required fields populated"
          value={String(stats.complete)}
          tone={stats.complete > 0 ? "emerald" : "neutral"}
        />
        <Kpi
          label="Missing one or more fields"
          value={String(stats.missing)}
          tone={stats.missing > 0 ? "rose" : "neutral"}
        />
      </KpiStrip>

      {/* Filter / sort bar */}
      <Card>
        <CardContent className="p-4 flex flex-wrap items-center gap-3">
          <SegmentedControl
            value={filterMode}
            onValueChange={(v) => setFilterMode(v as FilterMode)}
            aria-label="Filter entities"
          >
            <SegmentedControlItem value="all">All</SegmentedControlItem>
            <SegmentedControlItem value="missing">
              Missing fields only
            </SegmentedControlItem>
            <SegmentedControlItem value="byType">
              By entity type
            </SegmentedControlItem>
          </SegmentedControl>

          {filterMode === "byType" && (
            <select
              value={typeFilter}
              onChange={(e) => setTypeFilter(e.target.value as EntityType | "all")}
              className="h-9 rounded-md border border-input bg-background px-3 text-sm"
            >
              <option value="all">All types</option>
              {availableTypes.map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </select>
          )}

          <div className="ml-auto flex items-center gap-2">
            <label className="text-xs text-muted-foreground">Sort by</label>
            <select
              value={sortMode}
              onChange={(e) => setSortMode(e.target.value as SortMode)}
              className="h-9 rounded-md border border-input bg-background px-3 text-sm"
            >
              <option value="name">Name</option>
              <option value="formationDate">Formation date</option>
            </select>
          </div>
        </CardContent>
      </Card>

      {/* Cards */}
      {visible.length === 0 ? (
        <EmptyState
          icon="📄"
          title="No entities match this filter"
          description="Try clearing or adjusting your filters."
        />
      ) : (
        <section className="grid gap-4 lg:grid-cols-2">
          {visible.map((org) => {
            const fields = buildFields(org);
            const missingCount = countMissing(fields);
            const allGood = missingCount === 0;
            return (
              <Card key={org.id} className={!allGood ? "border-yellow-300/60" : undefined}>
                <CardContent className="p-5 space-y-4">
                  <header className="flex items-start justify-between gap-3">
                    <div className="min-w-0">
                      <div className="flex items-center gap-2 flex-wrap">
                        <h3 className="text-base font-semibold truncate">
                          {org.emoji ? <span className="mr-1">{org.emoji}</span> : null}
                          {org.name}
                        </h3>
                        <Badge variant="outline" className="text-[10px]">
                          {org.entityType}
                        </Badge>
                        <Badge variant={STATUS_TONE[org.status]} className="text-[10px]">
                          {org.status}
                        </Badge>
                      </div>
                      {org.dba && (
                        <p className="mt-0.5 text-xs text-muted-foreground">
                          dba {org.dba}
                        </p>
                      )}
                    </div>
                    <div className="shrink-0 text-right">
                      {allGood ? (
                        <Badge variant="success" className="text-[10px]">
                          Ready to file
                        </Badge>
                      ) : (
                        <Badge variant="warning" className="text-[10px]">
                          {missingCount} missing
                        </Badge>
                      )}
                    </div>
                  </header>

                  <div className="rounded-md border overflow-hidden">
                    <table className="w-full text-sm">
                      <tbody>
                        {fields.map((f) => {
                          const isMissing = !f.value || f.value.trim() === "";
                          return (
                            <tr
                              key={f.label}
                              className="border-b last:border-0 align-top"
                            >
                              <th
                                scope="row"
                                className="px-3 py-2 text-left text-xs font-medium text-muted-foreground w-[44%]"
                              >
                                {f.label}
                              </th>
                              <td className="px-3 py-2 text-xs">
                                {isMissing ? (
                                  <span className="inline-flex items-center gap-2">
                                    <span className="text-muted-foreground">—</span>
                                    <span
                                      className="inline-flex items-center rounded-full border border-yellow-300/70 bg-yellow-100/60 px-1.5 py-0.5 text-[10px] font-medium text-yellow-900 dark:bg-yellow-900/30 dark:text-yellow-100"
                                      title={
                                        f.availableInModel
                                          ? "Fill this in on the entity record."
                                          : "This field is not yet on the Organization model — add it to src/lib/sag/types.ts."
                                      }
                                    >
                                      {f.availableInModel ? "missing" : "not in model"}
                                    </span>
                                  </span>
                                ) : (
                                  <span className="font-mono break-all">{f.value}</span>
                                )}
                              </td>
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                  </div>

                  <div className="flex flex-wrap items-center gap-2 pt-1">
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={() => copySummary(org, fields)}
                    >
                      {copiedSlug === org.slug ? "Copied" : "Copy summary to clipboard"}
                    </Button>
                    <Button asChild size="sm" variant="brand">
                      <a
                        href={SOS_FILING_URL}
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                        Open NC SoS filing portal ↗
                      </a>
                    </Button>
                    <Button asChild size="sm" variant="ghost">
                      <Link href={`/app/entities/${org.slug}`}>Edit entity record</Link>
                    </Button>
                  </div>
                </CardContent>
              </Card>
            );
          })}
        </section>
      )}

      <p className="text-xs text-muted-foreground">
        Source: NC Department of the Secretary of State —{" "}
        <a
          href={SOS_FILING_URL}
          target="_blank"
          rel="noopener noreferrer"
          className="underline hover:text-foreground"
        >
          sosnc.gov
        </a>
        . Pre-filled values are read from the entity registry (
        <code className="font-mono">src/lib/sag/entities.ts</code>) and shown read-only
        here. Edits to registered agent, principal office, managers, NAICS, and contact
        info must happen on the entity record itself.
      </p>
    </div>
  );
}

