// Channel Edit screen — left sub-nav rail (General / Playout / Streaming / Stream
// selection / Music video / Branding) + one focused form pane per section, dense
// label+help / control rows inside a flush Card (mirrors Settings.jsx). A floating
// save bar surfaces validation state and appears only while the draft is dirty.
(function () {
  const NS = window.ChicoryTVDesignSystem_eb3b61;
  const { Card, Button, Badge, ChannelLogo, Input, Select, Switch } = NS;
  const Ico = window.Ico;
  const mono = { fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums" };

  const SECTIONS = [
    { id: "general",   label: "General",           icon: "Tv",                hint: "Number, name, group" },
    { id: "playout",   label: "Playout",           icon: "ListVideo",         hint: "Source & scheduling" },
    { id: "streaming", label: "Streaming",         icon: "SlidersHorizontal", hint: "FFmpeg & output" },
    { id: "selection", label: "Stream selection",  icon: "AudioLines",        hint: "Audio & subtitles" },
    { id: "music",     label: "Music video",       icon: "Music",             hint: "Credits & songs" },
    { id: "branding",  label: "Branding",          icon: "Image",             hint: "Logo & watermark" },
  ];

  const FFMPEG_PROFILES = ["1080p H.264", "1080p HEVC", "720p H.264", "Copy (no transcode)"];
  const WATERMARKS = ["(none)", "Station bug — corner", "Station bug — large"];
  const FILLER_PRESETS = ["(none)", "Retro Bumpers", "Ad Break Pool", "Test Pattern"];
  const LANGUAGES = ["(none)", "English", "Japanese", "Spanish", "French", "German"];
  const CREDITS_TEMPLATES = ["(none)", "Classic Credits", "Minimal Credits"];
  const STREAM_SELECTORS = ["(none)", "prefer-commentary.py", "anime-dual-audio.py"];
  const MIRROR_CHANNELS = ["(none)", "(1.1) - News 24", "(3.1) - Movie Vault", "(9.1) - Kids Classics"];
  const SLUG_OPTIONS = ["(none)", "0.5 seconds", "1 second", "2 seconds", "3 seconds", "5 seconds"];

  const SAVED = {
    number: "5.1", name: "Retro Cartoons", group: "Entertainment", categories: "Animation, Kids",
    isEnabled: true, showInEpg: true,
    playoutSource: "Generated", playoutMode: "Continuous", mirrorSourceChannel: "(none)", playoutOffsetHours: "0",
    idleBehavior: "Stop On Disconnect",
    streamingMode: "MPEG-TS", ffmpegProfile: "1080p H.264", slugSeconds: "1 second",
    streamSelectorMode: "Default", preferredAudioLanguage: "English", preferredAudioTitle: "",
    preferredSubtitleLanguage: "(none)", subtitleMode: "None", streamSelector: "(none)",
    musicVideoCreditsMode: "None", musicVideoCreditsTemplate: "(none)", songVideoMode: "Default",
    externalLogoUrl: "", watermark: "(none)", fallbackFiller: "Retro Bumpers",
  };
  const PLAYOUT_LOCKED = true; // this channel already has a generated playout

  /* ---------- shared row primitives (mirror Settings.jsx / ChannelEditScreen) ---------- */

  function Pane({ title, subtitle, children }) {
    return (
      <div style={{ maxWidth: 720, display: "flex", flexDirection: "column", gap: 16, animation: "ctv-fade-in 240ms cubic-bezier(0.16,1,0.3,1)" }}>
        <div>
          <div style={{ font: "var(--weight-semibold) var(--text-lg)/1.2 var(--font-sans)", color: "var(--text-primary)" }}>{title}</div>
          <div style={{ marginTop: 5, font: "var(--text-sm)/1.45 var(--font-sans)", color: "var(--text-secondary)" }}>{subtitle}</div>
        </div>
        {children}
      </div>
    );
  }

  function Row({ label, help, children, first, control = 300 }) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 20, padding: "13px 16px", borderTop: first ? "none" : "1px solid var(--border-hairline)" }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ font: "var(--weight-medium) var(--text-sm)/1.3 var(--font-sans)", color: "var(--text-primary)" }}>{label}</div>
          {help && <div style={{ marginTop: 3, font: "var(--text-xs)/1.45 var(--font-sans)", color: "var(--text-disabled)" }}>{help}</div>}
        </div>
        <div style={{ flex: `0 0 ${control}px`, display: "flex", justifyContent: "flex-end" }}>{children}</div>
      </div>
    );
  }

  /* ---------- panes ---------- */

  function GeneralPane({ v, set }) {
    return (
      <Pane title="General" subtitle="Identity shown in the lineup, guide and IPTV playlist.">
        <Card padded={false}>
          <Row first control={200} label="Number" help="Displayed channel number, e.g. 5 or 5.1.">
            <Input size="sm" fullWidth value={v.number} onChange={(e) => set("number", e.target.value)}
              error={v.number.trim() ? null : "Number is required"} />
          </Row>
          <Row label="Name" help="Channel display name.">
            <Input size="sm" fullWidth value={v.name} onChange={(e) => set("name", e.target.value)}
              error={v.name.trim() ? null : "Name is required"} />
          </Row>
          <Row label="Group" help="Groups channels in clients that support it.">
            <Input size="sm" fullWidth value={v.group} onChange={(e) => set("group", e.target.value)} />
          </Row>
          <Row label="Categories" help="Comma-separated list of categories.">
            <Input size="sm" fullWidth placeholder="News, Sports" value={v.categories} onChange={(e) => set("categories", e.target.value)} />
          </Row>
          <Row label="Enabled" help="Whether this channel is served to clients.">
            <Switch size="sm" checked={v.isEnabled} onChange={(next) => set(next ? "isEnabled" : ["isEnabled", "showInEpg"], next)} />
          </Row>
          <Row label="Show in EPG" help="Include this channel in the XMLTV guide.">
            <Switch size="sm" checked={v.showInEpg} disabled={!v.isEnabled} onChange={(next) => set("showInEpg", next)} />
          </Row>
        </Card>
      </Pane>
    );
  }

  function PlayoutPane({ v, set }) {
    const isMirror = v.playoutSource === "Mirror";
    return (
      <Pane title="Playout" subtitle="Where the channel's content comes from and how it progresses.">
        <Card padded={false}>
          <Row first label="Playout source"
            help={PLAYOUT_LOCKED ? "Cannot be changed once a generated channel has a playout." : "Generated builds its own schedule; Mirror follows another channel."}>
            <Select size="sm" fullWidth disabled={PLAYOUT_LOCKED} value={v.playoutSource}
              onChange={(e) => set("playoutSource", e.target.value)} options={["Generated", "Mirror"]} />
          </Row>
          {isMirror ? (
            <React.Fragment>
              <Row label="Mirror source channel" help="The generated channel this channel mirrors.">
                <Select size="sm" fullWidth value={v.mirrorSourceChannel} onChange={(e) => set("mirrorSourceChannel", e.target.value)} options={MIRROR_CHANNELS} />
              </Row>
              <Row control={160} label="Playout offset" help="Shift the mirrored playout by this many hours.">
                <Input size="sm" fullWidth type="number" style={mono} value={v.playoutOffsetHours}
                  onChange={(e) => set("playoutOffsetHours", e.target.value)}
                  trailing={<span style={{ font: "var(--text-2xs)/1 var(--font-sans)", color: "var(--text-disabled)" }}>hours</span>} />
              </Row>
            </React.Fragment>
          ) : (
            <Row label="Playout mode" help="Controls how the generated playout progresses.">
              <Select size="sm" fullWidth value={v.playoutMode} onChange={(e) => set("playoutMode", e.target.value)} options={["Continuous", "On Demand"]} />
            </Row>
          )}
          <Row label="Idle behavior" help="How the transcoder behaves once all clients disconnect.">
            <Select size="sm" fullWidth value={v.idleBehavior} onChange={(e) => set("idleBehavior", e.target.value)} options={["Stop On Disconnect", "Keep Running"]} />
          </Row>
          <Row label="Transcode mode" help="When the transcoding process is active. Only On Demand is supported.">
            <Select size="sm" fullWidth disabled value="On Demand" options={["On Demand"]} onChange={() => {}} />
          </Row>
        </Card>
      </Pane>
    );
  }

  function StreamingPane({ v, set }) {
    const hlsDirect = v.streamingMode === "HLS Direct";
    return (
      <Pane title="Streaming" subtitle="Output container and the transcoding profile applied to this channel.">
        <Card padded={false}>
          <Row first label="Streaming mode" help="Delivery container / protocol served to clients.">
            <Select size="sm" fullWidth value={v.streamingMode} onChange={(e) => set("streamingMode", e.target.value)}
              options={["MPEG-TS", "MPEG-TS (Legacy)", "HLS Direct", "HLS Segmenter"]} />
          </Row>
          <Row label="FFmpeg profile" help={hlsDirect ? "Not used in HLS Direct mode." : "Transcoding preset for this channel."}>
            <Select size="sm" fullWidth disabled={hlsDirect} value={v.ffmpegProfile} onChange={(e) => set("ffmpegProfile", e.target.value)} options={FFMPEG_PROFILES} />
          </Row>
          <Row label="Slug seconds" help="Black video / silent audio inserted between every playout item.">
            <Select size="sm" fullWidth value={v.slugSeconds} onChange={(e) => set("slugSeconds", e.target.value)} options={SLUG_OPTIONS} />
          </Row>
        </Card>
      </Pane>
    );
  }

  function SelectionPane({ v, set }) {
    const isDefault = v.streamSelectorMode === "Default";
    return (
      <Pane title="Stream selection" subtitle="How audio and subtitle tracks are chosen for playback.">
        <Card padded={false}>
          <Row first label="Stream selector mode" help="Default picks tracks by preference; Custom uses a selector script.">
            <Select size="sm" fullWidth value={v.streamSelectorMode} onChange={(e) => set("streamSelectorMode", e.target.value)} options={["Default", "Custom"]} />
          </Row>
          {isDefault ? (
            <React.Fragment>
              <Row label="Preferred audio language" help="Blank keeps the file order.">
                <Select size="sm" fullWidth value={v.preferredAudioLanguage} onChange={(e) => set("preferredAudioLanguage", e.target.value)} options={LANGUAGES} />
              </Row>
              <Row label="Preferred audio title" help="Prefer an audio track whose title contains this text.">
                <Input size="sm" fullWidth value={v.preferredAudioTitle} onChange={(e) => set("preferredAudioTitle", e.target.value)} />
              </Row>
              <Row label="Preferred subtitle language" help="Blank disables preference.">
                <Select size="sm" fullWidth value={v.preferredSubtitleLanguage} onChange={(e) => set("preferredSubtitleLanguage", e.target.value)} options={LANGUAGES} />
              </Row>
              <Row label="Subtitle mode" help="When subtitle tracks are burned in.">
                <Select size="sm" fullWidth value={v.subtitleMode} onChange={(e) => set("subtitleMode", e.target.value)} options={["None", "Forced", "Default", "Any"]} />
              </Row>
            </React.Fragment>
          ) : (
            <Row label="Stream selector" help="Name of a custom stream-selector script in the config folder.">
              <Select size="sm" fullWidth value={v.streamSelector} onChange={(e) => set("streamSelector", e.target.value)} options={STREAM_SELECTORS} />
            </Row>
          )}
        </Card>
      </Pane>
    );
  }

  function MusicPane({ v, set }) {
    const creditsOn = v.musicVideoCreditsMode === "Generate Subtitles";
    return (
      <Pane title="Music video" subtitle="Overlays and progress behavior for music video and song content.">
        <Card padded={false}>
          <Row first label="Credits mode" help="Generate on-screen credits for music videos.">
            <Select size="sm" fullWidth value={v.musicVideoCreditsMode} onChange={(e) => set("musicVideoCreditsMode", e.target.value)} options={["None", "Generate Subtitles"]} />
          </Row>
          <Row label="Credits template" help="Name of the credits template. Only used when credits are generated.">
            <Select size="sm" fullWidth disabled={!creditsOn} value={v.musicVideoCreditsTemplate} onChange={(e) => set("musicVideoCreditsTemplate", e.target.value)} options={CREDITS_TEMPLATES} />
          </Row>
          <Row label="Song video mode" help="Optional progress bar overlay for song content.">
            <Select size="sm" fullWidth value={v.songVideoMode} onChange={(e) => set("songVideoMode", e.target.value)} options={["Default", "With Progress"]} />
          </Row>
        </Card>
      </Pane>
    );
  }

  function BrandingPane({ v, set }) {
    const hlsDirect = v.streamingMode === "HLS Direct";
    const urlValid = !v.externalLogoUrl.trim() || /^https?:\/\//i.test(v.externalLogoUrl.trim());
    const previewSrc = v.externalLogoUrl.trim() || undefined;
    return (
      <Pane title="Branding" subtitle="Channel logo and the overlays applied while streaming.">
        <Card padded={false}>
          <Row first control={340} label="Logo" help="Shown in the guide and as the on-screen bug.">
            <div style={{ display: "flex", alignItems: "center", gap: 12, width: "100%" }}>
              <ChannelLogo name={v.name} size={48} src={previewSrc} />
              <Button size="sm" variant="secondary" startIcon={<Ico n="Upload" s={14} />}>Upload logo</Button>
            </div>
          </Row>
          <Row control={340} label="External logo URL" help="An external image URL wins over an uploaded logo when both are set.">
            <Input size="sm" fullWidth placeholder="https://example.com/logo.png" value={v.externalLogoUrl}
              onChange={(e) => set("externalLogoUrl", e.target.value)}
              error={urlValid ? null : "Enter a valid http(s) URL"} />
          </Row>
          <Row label="Watermark" help={hlsDirect ? "Not used in HLS Direct mode." : "Overlay applied to the channel."}>
            <Select size="sm" fullWidth disabled={hlsDirect} value={v.watermark} onChange={(e) => set("watermark", e.target.value)} options={WATERMARKS} />
          </Row>
          <Row label="Fallback filler" help="Plays when the playout has nothing scheduled.">
            <Select size="sm" fullWidth value={v.fallbackFiller} onChange={(e) => set("fallbackFiller", e.target.value)} options={FILLER_PRESETS} />
          </Row>
        </Card>
      </Pane>
    );
  }

  const PANES = {
    general: GeneralPane, playout: PlayoutPane, streaming: StreamingPane,
    selection: SelectionPane, music: MusicPane, branding: BrandingPane,
  };

  /* ---------- screen ---------- */

  function ChannelEdit() {
    const [section, setSection] = React.useState("general");
    const [saved, setSaved] = React.useState(SAVED);
    const [draft, setDraft] = React.useState(SAVED);
    const [saving, setSaving] = React.useState(false);
    const [justSaved, setJustSaved] = React.useState(false);

    const set = (key, val) => {
      setJustSaved(false);
      if (Array.isArray(key)) {
        setDraft((d) => ({ ...d, [key[0]]: val, [key[1]]: val ? d[key[1]] : false }));
      } else {
        setDraft((d) => ({ ...d, [key]: val }));
      }
    };

    const nameValid = Boolean(draft.name.trim());
    const numberValid = Boolean(draft.number.trim());
    const urlValid = !draft.externalLogoUrl.trim() || /^https?:\/\//i.test(draft.externalLogoUrl.trim());
    const valid = nameValid && numberValid && urlValid;
    const dirty = JSON.stringify(draft) !== JSON.stringify(saved);

    const PaneCmp = PANES[section];

    return (
      <div style={{ display: "flex", height: "100%", minHeight: 0 }}>
        {/* sub-nav rail */}
        <div style={{ width: 224, flex: "0 0 auto", borderRight: "1px solid var(--border-hairline)", overflow: "auto", padding: "12px 8px" }}>
          {SECTIONS.map((s) => {
            const active = s.id === section;
            return (
              <button key={s.id} type="button" onClick={() => setSection(s.id)} className="ctv-press"
                style={{ display: "flex", alignItems: "center", gap: 10, width: "100%", padding: "9px 10px", marginBottom: 2, border: "none", borderRadius: "var(--radius-sm)", cursor: "pointer", textAlign: "left",
                  background: active ? "var(--ctv-accent-soft)" : "transparent" }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--ctv-surface-2)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}>
                <Ico n={s.icon} s={16} color={active ? "var(--ctv-accent)" : "var(--text-secondary)"} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ font: "var(--weight-medium) var(--text-sm)/1 var(--font-sans)", color: active ? "var(--text-primary)" : "var(--text-secondary)" }}>{s.label}</div>
                  <div style={{ marginTop: 3, font: "var(--text-2xs)/1 var(--font-sans)", color: "var(--text-disabled)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.hint}</div>
                </div>
              </button>
            );
          })}
        </div>

        {/* pane */}
        <div style={{ flex: 1, minWidth: 0, minHeight: 0, position: "relative", display: "flex", flexDirection: "column" }}>
          <div style={{ flex: 1, minHeight: 0, overflow: "auto", padding: "20px 24px 96px" }}>
            <PaneCmp key={section} v={draft} set={set} />
          </div>

          {/* floating save bar */}
          {(dirty || justSaved) && (
            <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, display: "flex", justifyContent: "center", padding: "0 24px 18px", pointerEvents: "none" }}>
              <div className="ctv-lift" style={{ pointerEvents: "auto", display: "flex", alignItems: "center", gap: 14, padding: "10px 12px 10px 16px", borderRadius: "var(--radius-pill)", background: "var(--surface-raised)", border: "1px solid var(--border-control)", boxShadow: "var(--shadow-pop)", animation: "ctv-fade-in 200ms cubic-bezier(0.16,1,0.3,1)" }}>
                {justSaved ? (
                  <React.Fragment>
                    <Ico n="CircleCheck" s={15} color="var(--status-ok)" />
                    <span style={{ font: "var(--weight-medium) var(--text-sm)/1 var(--font-sans)", color: "var(--text-primary)" }}>Channel saved</span>
                  </React.Fragment>
                ) : (
                  <React.Fragment>
                    <span style={{ font: "var(--weight-medium) var(--text-sm)/1 var(--font-sans)", color: "var(--text-primary)" }}>Unsaved changes</span>
                    {(!nameValid || !numberValid) && <Badge tone="neutral">Name and number are required</Badge>}
                    {!urlValid && <Badge tone="neutral">Logo URL must be http(s)</Badge>}
                    <span style={{ width: 1, height: 18, background: "var(--border-hairline)" }} />
                    <Button size="sm" variant="ghost" onClick={() => setDraft(saved)}>Discard</Button>
                    <Button size="sm" variant="primary" loading={saving} disabled={!valid || saving} startIcon={<Ico n="Check" s={14} />}
                      onClick={() => {
                        setSaving(true);
                        window.setTimeout(() => {
                          setSaving(false);
                          setSaved(draft);
                          setJustSaved(true);
                          window.setTimeout(() => setJustSaved(false), 1800);
                        }, 500);
                      }}>
                      Save changes
                    </Button>
                  </React.Fragment>
                )}
              </div>
            </div>
          )}
        </div>
      </div>
    );
  }

  window.CTVChannelEdit = ChannelEdit;
})();
