import React from 'react';
import { openUrl } from '@tauri-apps/plugin-opener';
import type { FilingsPanelData } from '../../types/financial';

const DEFAULT_PAGE = 1;
const DEFAULT_PAGE_SIZE = 25;
const PAGE_SIZE_OPTIONS = [25, 50, 100] as const;

export interface FilingsCommandState {
  symbol: string;
  page: number;
  pageSize: number;
  query?: string;
}

interface FilingsPanelProps {
  data: FilingsPanelData;
  onRunCommand?: (command: string) => void;
}

const formatQueryToken = (query: string) => {
  const trimmed = query.trim();
  if (!/[\s"\\]/.test(trimmed)) {
    return trimmed;
  }

  return `"${trimmed.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
};

export const buildFilingsCommand = ({
  symbol,
  page,
  pageSize,
  query,
}: FilingsCommandState) => {
  const normalizedSymbol = symbol.trim().toUpperCase();
  const normalizedQuery = query?.trim();
  const tokens = ['/filings', normalizedSymbol];

  if (page > DEFAULT_PAGE) {
    tokens.push('--page', String(page));
  }

  if (pageSize !== DEFAULT_PAGE_SIZE) {
    tokens.push('--page-size', String(pageSize));
  }

  if (normalizedQuery) {
    tokens.push('--query', formatQueryToken(normalizedQuery));
  }

  return tokens.join(' ');
};

export const buildFilingsPaginationCommand = (
  data: FilingsPanelData,
  page: number,
) =>
  buildFilingsCommand({
    symbol: data.symbol,
    page,
    pageSize: data.pageSize,
    query: data.query,
  });

export const buildFilingsPageSizeCommand = (
  data: FilingsPanelData,
  pageSize: number,
) =>
  buildFilingsCommand({
    symbol: data.symbol,
    page: DEFAULT_PAGE,
    pageSize,
    query: data.query,
  });

export const buildFilingsSearchCommand = (
  data: FilingsPanelData,
  query?: string,
) =>
  buildFilingsCommand({
    symbol: data.symbol,
    page: DEFAULT_PAGE,
    pageSize: data.pageSize,
    query,
  });

export const FilingsPanel: React.FC<FilingsPanelProps> = ({
  data,
  onRunCommand,
}) => {
  const [queryDraft, setQueryDraft] = React.useState(data.query ?? '');
  const normalizedCurrentQuery = data.query?.trim() ?? '';

  React.useEffect(() => {
    setQueryDraft(data.query ?? '');
  }, [data.query, data.symbol]);

  const runCommand = React.useCallback(
    (command: string) => {
      if (!onRunCommand) {
        return;
      }

      onRunCommand(command);
    },
    [onRunCommand],
  );

  const openFiling = React.useCallback(async (url: string) => {
    await openUrl(url);
  }, []);

  const goToPage = React.useCallback(
    (page: number) => {
      if (page < 1 || page > data.totalPages || page === data.page) {
        return;
      }

      runCommand(buildFilingsPaginationCommand(data, page));
    },
    [data, runCommand],
  );

  const applySearch = React.useCallback(() => {
    const trimmedDraft = queryDraft.trim();

    if (trimmedDraft === normalizedCurrentQuery) {
      return;
    }

    runCommand(buildFilingsSearchCommand(data, trimmedDraft || undefined));
  }, [data, normalizedCurrentQuery, queryDraft, runCommand]);

  const clearSearch = React.useCallback(() => {
    if (!normalizedCurrentQuery && !queryDraft.trim()) {
      return;
    }

    setQueryDraft('');
    runCommand(buildFilingsSearchCommand(data, undefined));
  }, [data, normalizedCurrentQuery, queryDraft, runCommand]);

  return (
    <div className="filings-panel py-4 overflow-auto">
      <header className="mb-4">
        <div className="flex items-start justify-between">
          <div>
            <div className="flex items-center gap-2">
              <h2 className="text-heading-lg text-term-text">{data.companyName}</h2>
              <span className="rounded border border-[var(--term-status-info-border)] bg-[var(--term-status-info)] px-2 py-1 font-mono text-[11px] uppercase tracking-[0.2em] text-[var(--term-status-info-strong)]">
                {data.symbol}
              </span>
            </div>
            <p className="mt-1 text-body-xs text-term-text-muted">
              SEC filing history
            </p>
          </div>
          <div className="text-right text-body-xs">
            <div className="text-term-text-muted">CIK {data.cik}</div>
            {data.latestFiling && (
              <div className="mt-1 text-term-text-tertiary">
                {data.latestFiling.form} filed {data.latestFiling.filingDate}
              </div>
            )}
          </div>
        </div>
      </header>

      <section className="mb-4">
        <div className="mb-4 flex flex-col gap-3 rounded-lg border border-term-border-subtle bg-term-highlight/40 px-3 py-3 lg:flex-row lg:items-end lg:justify-between">
          <label className="flex min-w-0 flex-1 flex-col gap-2">
            <span className="font-mono text-[11px] uppercase tracking-[0.18em] text-term-text-muted">
              Metadata search
            </span>
            <div className="flex flex-col gap-2 sm:flex-row">
              <input
                type="text"
                value={queryDraft}
                placeholder="Form, filing date, accession, document..."
                aria-label="Search filings metadata"
                className="min-w-0 flex-1 rounded border border-term-border bg-term-bg px-3 py-2 text-sm text-term-text outline-none transition focus:border-term-border-focus"
                onChange={(event) => setQueryDraft(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === 'Enter') {
                    event.preventDefault();
                    applySearch();
                  }
                }}
              />
              <div className="flex gap-2">
                <button
                  type="button"
                  className="rounded border border-[var(--term-status-info-border)] bg-[var(--term-status-info)] px-4 py-2 font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--term-status-info-strong)] transition hover:border-info hover:text-term-text"
                  onClick={applySearch}
                >
                  Apply
                </button>
                <button
                  type="button"
                  className="rounded border border-term-border px-4 py-2 font-mono text-[11px] uppercase tracking-[0.18em] text-term-text-muted transition hover:border-info hover:text-term-text"
                  onClick={clearSearch}
                >
                  Clear
                </button>
              </div>
            </div>
          </label>

          <div className="flex flex-wrap items-center gap-3">
            <label className="flex items-center gap-2 font-mono text-[11px] uppercase tracking-[0.18em] text-term-text-muted">
              Page size
              <select
                aria-label="Filings page size"
                className="rounded border border-term-border bg-term-bg px-3 py-2 text-sm text-term-text"
                value={data.pageSize}
                onChange={(event) => {
                  const nextPageSize = Number(event.target.value);
                  if (nextPageSize === data.pageSize) {
                    return;
                  }

                  runCommand(buildFilingsPageSizeCommand(data, nextPageSize));
                }}
              >
                {PAGE_SIZE_OPTIONS.map((option) => (
                  <option key={option} value={option}>
                    {option}
                  </option>
                ))}
              </select>
            </label>

            <div className="flex items-center gap-2">
              <span className="font-mono text-[11px] text-term-text-muted">
                {data.page}/{data.totalPages}
              </span>
              <button
                type="button"
                className="rounded border border-term-border px-3 py-1.5 font-mono text-[11px] uppercase tracking-[0.18em] text-term-text-muted transition hover:border-info hover:text-term-text disabled:cursor-not-allowed disabled:opacity-40"
                disabled={data.page <= 1}
                onClick={() => goToPage(data.page - 1)}
              >
                Previous
              </button>
              <button
                type="button"
                className="rounded border border-term-border px-3 py-1.5 font-mono text-[11px] uppercase tracking-[0.18em] text-term-text-muted transition hover:border-info hover:text-term-text disabled:cursor-not-allowed disabled:opacity-40"
                disabled={data.page >= data.totalPages}
                onClick={() => goToPage(data.page + 1)}
              >
                Next
              </button>
            </div>
          </div>
        </div>

        {data.items.length === 0 ? (
          <div className="rounded-lg border border-dashed border-term-border bg-term-elevated px-6 py-10 text-center">
            <p className="font-mono text-sm text-term-text-muted">
              {data.query
                ? `No filings matched "${data.query}".`
                : 'No SEC filings were available for this company.'}
            </p>
            <p className="mt-2 font-mono text-[11px] uppercase tracking-[0.16em] text-term-text-tertiary">
              Search matches form, dates, accession number, and document name only.
            </p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="min-w-full border-collapse font-mono text-sm">
              <thead className="text-term-text-muted">
                <tr className="border-b border-term-border-subtle">
                  <th className="px-3 py-2 text-left text-[10px] uppercase tracking-[0.18em]">Form</th>
                  <th className="px-3 py-2 text-left text-[10px] uppercase tracking-[0.18em]">Filed</th>
                  <th className="px-3 py-2 text-left text-[10px] uppercase tracking-[0.18em]">Report</th>
                  <th className="px-3 py-2 text-left text-[10px] uppercase tracking-[0.18em]">Document</th>
                  <th className="px-3 py-2 text-left text-[10px] uppercase tracking-[0.18em]">Overview</th>
                  <th className="px-3 py-2 text-right text-[10px] uppercase tracking-[0.18em]">Action</th>
                </tr>
              </thead>
              <tbody>
                {data.items.map((item) => (
                  <tr
                    key={item.accessionNumber}
                    className="border-b border-term-border-subtle last:border-b-0"
                  >
                    <td className="px-3 py-2 text-term-text">
                      <div className="font-semibold">{item.form}</div>
                      <div className="text-[11px] text-term-text-tertiary">
                        {item.accessionNumber}
                      </div>
                    </td>
                    <td className="px-3 py-2 text-term-text">{item.filingDate}</td>
                    <td className="px-3 py-2 text-term-text-muted">{item.reportDate ?? '—'}</td>
                    <td className="px-3 py-2 text-term-text">
                      <div>{item.primaryDocument || 'Filing directory'}</div>
                      <div className="max-w-[22rem] break-all text-[11px] text-term-text-tertiary">
                        {item.filingUrl}
                      </div>
                    </td>
                    <td className="px-3 py-2 text-term-text-muted">{item.overview}</td>
                    <td className="px-3 py-2 text-right">
                      <button
                        type="button"
                        className="rounded border border-term-border px-2 py-1 font-mono text-[10px] uppercase tracking-[0.16em] text-info transition-colors hover:border-info/40 hover:text-term-text"
                        onClick={() => void openFiling(item.filingUrl)}
                      >
                        Open
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </section>

      <footer className="mt-4 border-t border-term-border-subtle pt-4">
        <div className="font-mono text-[11px] text-term-text-muted">
          SEC EDGAR • companyfilings
          {data.totalResults > 0 && (
            <span> • {data.totalResults} results</span>
          )}
        </div>
      </footer>
    </div>
  );
};
