import { useEffect, useState } from "react";
import { RefreshButton } from "@/components/ui/Button";
import { extractLogFilter, formatLogRegionMeta, formatText, formatUtc8Time } from "../lib/formatters";
import { QueryErrorBanner } from "../components/query-error-banner";
import { RegionStatusDot } from "../components/region-status-dot";
import { SectionLoadingCard } from "../components/section-loading-card";
import type { AcsObserveLogs } from "@/lib/observe/logs";

const EMPTY_VALUE_LABEL = "-";

function formatCount(value: number | null): string {
  return value === null ? EMPTY_VALUE_LABEL : String(value);
}

export function LogsSection({
  logs,
  logsLoading,
  logsError,
  logsFilterMode,
  logsFilterKeyword,
  logsRangeMinutes,
  setLogsRangeMinutes,
  onRefresh,
}: {
  logs: AcsObserveLogs | null;
  logsLoading: boolean;
  logsError?: string;
  logsFilterMode: "include" | "exclude";
  logsFilterKeyword: string;
  logsRangeMinutes: number;
  setLogsRangeMinutes: (value: number) => void;
  onRefresh: (filter: { mode: "include" | "exclude"; keyword: string }) => void;
}) {
  const [logsFilterModeDraft, setLogsFilterModeDraft] = useState(logsFilterMode);
  const [logsFilterKeywordDraft, setLogsFilterKeywordDraft] = useState(logsFilterKeyword);

  useEffect(() => {
    setLogsFilterModeDraft(logsFilterMode);
    setLogsFilterKeywordDraft(logsFilterKeyword);
  }, [logsFilterKeyword, logsFilterMode]);

  return (
    <section data-testid="logs-section" className="space-y-4">
      <div data-testid="logs-header" className="flex items-center justify-between gap-4">
        <div>
          <h3 className="text-lg font-semibold">Logs</h3>
          {logs ? (
            <p className="text-sm text-text-secondary mt-1" data-testid="logs-coverage-summary">
              <span className="font-medium text-text-primary">{logs.coverage.selected}</span> selected ·{" "}
              <span className="font-medium text-success">{logs.coverage.ready}</span> ready ·{" "}
              <span
                className={`font-medium ${logs.coverage.missingDatasource > 0 ? "text-danger" : "text-success"}`}
              >
                {logs.coverage.missingDatasource}
              </span>{" "}
              datasource missing
              {logs.coverage.queryError > 0 ? (
                <>
                  {" · "}
                  <span className="font-medium text-danger">{logs.coverage.queryError}</span> query error
                </>
              ) : null}
            </p>
          ) : null}
        </div>

        <div data-testid="logs-controls" className="flex items-end gap-3">
          <label className="grid gap-1 text-xs uppercase tracking-wider text-text-muted">
            Filter
            <select
              aria-label="Logs filter mode"
              value={logsFilterModeDraft}
              onChange={(event) => setLogsFilterModeDraft(event.target.value as "include" | "exclude")}
              className="h-8 px-2.5 rounded-md bg-surface-0 border border-surface-2 text-sm text-text-primary normal-case tracking-normal"
            >
              <option value="include">Include</option>
              <option value="exclude">Exclude</option>
            </select>
          </label>
          <label className="grid gap-1 text-xs uppercase tracking-wider text-text-muted">
            Keyword
            <input
              aria-label="Logs filter keyword"
              type="text"
              value={logsFilterKeywordDraft}
              onChange={(event) => setLogsFilterKeywordDraft(event.target.value)}
              className="h-8 w-36 px-2.5 rounded-md bg-surface-0 border border-surface-2 text-sm text-text-primary normal-case tracking-normal"
            />
          </label>
          <label className="grid gap-1 text-xs uppercase tracking-wider text-text-muted">
            Range
            <select
              aria-label="Logs time range"
              value={logsRangeMinutes}
              onChange={(event) => setLogsRangeMinutes(Number(event.target.value))}
              className="h-8 px-2.5 rounded-md bg-surface-0 border border-surface-2 text-sm text-text-primary normal-case tracking-normal"
            >
              <option value={60}>1h</option>
              <option value={120}>2h</option>
              <option value={360}>6h</option>
              <option value={1440}>24h</option>
              <option value={4320}>3d</option>
              <option value={10080}>7d</option>
            </select>
          </label>
          <RefreshButton
            aria-label="Refresh Logs"
            onClick={() => onRefresh({
              mode: logsFilterModeDraft,
              keyword: logsFilterKeywordDraft,
            })}
            disabled={logsLoading}
            busy={logsLoading}
          />
        </div>
      </div>

      <QueryErrorBanner title="Failed to load Logs" message={logsError ?? ""} />

      {!logs && logsLoading ? (
        <SectionLoadingCard
          label="Loading Logs"
          testId="logs-loading"
        />
      ) : null}

      {logs && <AcsErrorLogsTable logs={logs} />}
    </section>
  );
}

function AcsErrorLogsTable({ logs }: { logs: AcsObserveLogs }) {
  const [expandedRegionIds, setExpandedRegionIds] = useState<Set<string>>(new Set());
  const firstLogql = logs.regions.find((region) => region.logql)?.logql ?? null;
  const logFilter = extractLogFilter(firstLogql);

  const toggleRegionSamples = (regionId: string) => {
    setExpandedRegionIds((current) => {
      const next = new Set(current);
      if (next.has(regionId)) {
        next.delete(regionId);
      } else {
        next.add(regionId);
      }
      return next;
    });
  };

  return (
    <div className="space-y-3">
      <div className="rounded-md border border-surface-2 bg-surface-1 px-3 py-2">
        <span className="mr-2 text-xs font-medium text-text-muted">LogQL</span>
        <span className="font-mono text-[12px] text-text-secondary" title={firstLogql ?? undefined}>
          {formatText(logFilter)}
        </span>
      </div>

      <section className="bg-surface-0 border border-surface-2 rounded-lg overflow-x-auto">
        <table aria-label="ACS logs" className="w-full min-w-[64rem] table-fixed text-sm">
          <colgroup>
            <col className="w-56" />
            <col className="w-16" />
            <col className="w-56" />
            <col />
          </colgroup>
          <thead>
            <tr className="border-b border-surface-2">
              <th className="px-4 py-2.5 text-left text-xs font-semibold uppercase tracking-wider text-text-muted">
                Region
              </th>
              <th className="px-4 py-2.5 text-left text-xs font-semibold uppercase tracking-wider text-text-muted">
                Count
              </th>
              <th className="px-4 py-2.5 text-left text-xs font-semibold uppercase tracking-wider text-text-muted">
                Latest
              </th>
              <th className="pl-6 pr-4 py-2.5 text-left text-xs font-semibold uppercase tracking-wider text-text-muted">
                Samples
              </th>
            </tr>
          </thead>
          <tbody>
            {logs.regions.map((region) => (
              <tr
                key={region.regionId}
                className="border-b border-surface-2/50 last:border-0 align-top hover:bg-surface-1 transition-colors"
              >
                <td className="px-4 py-2.5">
                  <div className="flex items-center gap-2 font-medium">
                    <span>{region.regionName}</span>
                    <RegionStatusDot
                      status={region.status}
                      errorMessage={region.errorMessage}
                      fallbackErrorMessage="Loki query failed"
                    />
                  </div>
                  <div className="text-xs text-text-muted">{formatLogRegionMeta(region.regionId)}</div>
                </td>
                <td className="px-4 py-2.5 font-mono text-[13px] text-text-secondary">
                  {formatCount(region.errorCount)}
                </td>
                <td className="px-4 py-2.5 font-mono text-[13px] text-text-secondary whitespace-nowrap">
                  {formatUtc8Time(region.latestTimestamp)}
                </td>
                <td className="pl-6 pr-4 py-2.5">
                  {region.status === "query-error" || region.samples.length === 0 ? (
                    <span className="font-mono text-[13px] text-text-muted">{EMPTY_VALUE_LABEL}</span>
                  ) : (
                    <div className="space-y-2">
                      <div className="rounded-md border border-surface-2 bg-surface-1">
                        <div className="px-3 py-2">
                          <div className="font-mono text-[11px] text-text-muted">
                            {formatUtc8Time(region.samples[0]?.timestamp ?? null)}
                          </div>
                          <div className="mt-1 font-mono text-[12px] text-text-secondary break-words">
                            {region.samples[0]?.line ?? EMPTY_VALUE_LABEL}
                          </div>
                        </div>
                        {region.samples.length > 1 ? (
                          <button
                            type="button"
                            onClick={() => toggleRegionSamples(region.regionId)}
                            aria-expanded={expandedRegionIds.has(region.regionId)}
                            className="w-full border-t border-surface-2 px-3 py-1.5 text-left text-[11px] text-text-secondary hover:bg-surface-2/60 hover:text-text-primary transition-colors"
                          >
                            {expandedRegionIds.has(region.regionId)
                              ? `Hide ${region.samples.length - 1} older`
                              : `Show ${region.samples.length - 1} more`}
                          </button>
                        ) : null}
                      </div>
                      {region.samples.length > 1 && expandedRegionIds.has(region.regionId) ? (
                        <div className="space-y-2">
                          {region.samples.slice(1).map((sample) => (
                            <div
                              key={`${region.regionId}:${sample.timestamp}:${sample.line}`}
                              className="rounded-md border border-surface-2 bg-surface-1 px-3 py-2"
                            >
                              <div className="font-mono text-[11px] text-text-muted">
                                {formatUtc8Time(sample.timestamp)}
                              </div>
                              <div className="mt-1 font-mono text-[12px] text-text-secondary break-words">
                                {sample.line}
                              </div>
                            </div>
                          ))}
                        </div>
                      ) : null}
                    </div>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </section>
    </div>
  );
}
