import { useEffect, useMemo, useState } from "react";
import {
  Accordion,
  AccordionHeader,
  AccordionItem,
  AccordionPanel,
  Field,
  Input,
  Text,
  Textarea,
} from "@fluentui/react-components";
import type { FilterConfig, FilterConfigUpdate } from "../../types/config";
import { useAutoSave } from "../../hooks/useAutoSave";
import { AutoSaveIndicator } from "./AutoSaveIndicator";
import { KVEditor } from "./KVEditor";
import { RegexList } from "./RegexList";
import { useConfigStyles } from "./configStyles";

interface FilterFormEditorProps {
  config: FilterConfig;
  onSave: (update: FilterConfigUpdate) => Promise<void>;
}

export function FilterFormEditor({ config, onSave }: FilterFormEditorProps): React.JSX.Element {
  const styles = useConfigStyles();
  const [before, setBefore] = useState(config.before ?? "");
  const [after, setAfter] = useState(config.after ?? "");
  const [variables, setVariables] = useState<Record<string, string>>(config.variables);
  const [prefregex, setPrefregex] = useState(config.prefregex ?? "");
  const [failregex, setFailregex] = useState<string[]>(config.failregex);
  const [ignoreregex, setIgnoreregex] = useState<string[]>(config.ignoreregex);
  const [maxlines, setMaxlines] = useState(config.maxlines !== null ? String(config.maxlines) : "");
  const [datepattern, setDatepattern] = useState(config.datepattern ?? "");
  const [journalmatch, setJournalmatch] = useState(config.journalmatch ?? "");

  useEffect(() => {
    setBefore(config.before ?? "");
    setAfter(config.after ?? "");
    setVariables(config.variables);
    setPrefregex(config.prefregex ?? "");
    setFailregex(config.failregex);
    setIgnoreregex(config.ignoreregex);
    setMaxlines(config.maxlines !== null ? String(config.maxlines) : "");
    setDatepattern(config.datepattern ?? "");
    setJournalmatch(config.journalmatch ?? "");
  }, [config]);

  const autoSavePayload = useMemo<FilterConfigUpdate>(() => {
    const parsedMax = maxlines.trim() !== "" ? parseInt(maxlines, 10) : null;
    return {
      before: before.trim() || null,
      after: after.trim() || null,
      variables,
      prefregex: prefregex.trim() || null,
      failregex,
      ignoreregex,
      maxlines: parsedMax !== null && !isNaN(parsedMax) ? parsedMax : null,
      datepattern: datepattern.trim() || null,
      journalmatch: journalmatch.trim() || null,
    };
  }, [after, before, datepattern, failregex, ignoreregex, journalmatch, maxlines, prefregex, variables]);

  const { status: saveStatus, errorText: saveErrorText, retry: retrySave } = useAutoSave(autoSavePayload, onSave);

  const hasIncludes = config.before !== null || config.after !== null;
  const varCount = Object.keys(variables).length;

  return (
    <div>
      <div className={styles.buttonRow} style={{ marginBottom: 8 }}>
        <Text size={500} weight="semibold">{config.filename}</Text>
        <AutoSaveIndicator status={saveStatus} errorText={saveErrorText} onRetry={retrySave} />
      </div>

      <Accordion multiple collapsible defaultOpenItems={["definition"]}>
        <AccordionItem value="includes" className={styles.accordionItem}>
          <AccordionHeader>{`Includes${hasIncludes ? "" : " (none)"}`}</AccordionHeader>
          <AccordionPanel>
            <div className={styles.sectionCard}>
              <Field label="before">
                <Input
                  value={before}
                  onChange={(_e, d) => { setBefore(d.value); }}
                  placeholder="e.g. common.conf"
                  className={styles.codeInput}
                />
              </Field>
              <Field label="after">
                <Input
                  value={after}
                  onChange={(_e, d) => { setAfter(d.value); }}
                  placeholder="e.g. sshd-aggressive.conf"
                  className={styles.codeInput}
                />
              </Field>
            </div>
          </AccordionPanel>
        </AccordionItem>

        <AccordionItem value="variables" className={styles.accordionItem}>
          <AccordionHeader>{`Variables (${String(varCount)})`}</AccordionHeader>
          <AccordionPanel>
            <div className={styles.sectionCard}>
              <KVEditor entries={variables} onChange={setVariables} />
            </div>
          </AccordionPanel>
        </AccordionItem>

        <AccordionItem value="definition" className={styles.accordionItem}>
          <AccordionHeader>Definition</AccordionHeader>
          <AccordionPanel>
            <div className={styles.sectionCard}>
              <Field label="prefregex">
                <Textarea
                  value={prefregex}
                  onChange={(_e, d) => { setPrefregex(d.value); }}
                  placeholder="Prefix regex prepended to all failregex patterns"
                  className={styles.codeInput}
                  rows={2}
                />
              </Field>

              <RegexList label="failregex" patterns={failregex} onChange={setFailregex} />
              <RegexList label="ignoreregex" patterns={ignoreregex} onChange={setIgnoreregex} />

              <details style={{ marginTop: 12 }}>
                <summary style={{ cursor: "pointer", userSelect: "none", marginBottom: 8 }}>
                  Advanced options
                </summary>
                <Field label="maxlines">
                  <Input
                    type="number"
                    value={maxlines}
                    onChange={(_e, d) => { setMaxlines(d.value); }}
                    placeholder="e.g. 10"
                    style={{ width: 100 }}
                  />
                </Field>
                <Field label="datepattern">
                  <Input
                    value={datepattern}
                    onChange={(_e, d) => { setDatepattern(d.value); }}
                    placeholder="e.g. %Y-%m-%d %H:%M:%S"
                    className={styles.codeInput}
                  />
                </Field>
                <Field label="journalmatch">
                  <Input
                    value={journalmatch}
                    onChange={(_e, d) => { setJournalmatch(d.value); }}
                    placeholder="e.g. _SYSTEMD_UNIT=sshd.service"
                    className={styles.codeInput}
                  />
                </Field>
              </details>
            </div>
          </AccordionPanel>
        </AccordionItem>
      </Accordion>
    </div>
  );
}
