import { Plus, Trash2 } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import type { FormEvent } from "react";
import { useConfigStore } from "@/stores/configStore";
import type { AppConfigUpdate, MediaMtxConfigView } from "@/types/api";
import { apiJson } from "@/utils/api";

export default function Settings() {
  const { config, isLoading, error, load } = useConfigStore();

  const [rtspUrl, setRtspUrl] = useState("");
  const [mtx, setMtx] = useState<MediaMtxConfigView | null>(null);
  const [mtxBusy, setMtxBusy] = useState(false);
  const [mtxError, setMtxError] = useState<string | null>(null);
  const [restartMsg, setRestartMsg] = useState<string | null>(null);
  const schedule = config?.schedule;
  const [weekdaysFrom, setWeekdaysFrom] = useState("18:00");
  const [weekdaysTo, setWeekdaysTo] = useState("08:00");
  const [weekendAllDay, setWeekendAllDay] = useState(true);
  const [mediamtxApiUrl, setMediamtxApiUrl] = useState("http://127.0.0.1:9997");
  const [mediamtxWebrtcUrl, setMediamtxWebrtcUrl] = useState("http://127.0.0.1:8889");
  const [mediamtxApiUser, setMediamtxApiUser] = useState("");
  const [mediamtxApiPass, setMediamtxApiPass] = useState("");
  const [recordingsDir, setRecordingsDir] = useState("");
  const [apiPort, setApiPort] = useState("8008");
  const [recordDeleteAfterDays, setRecordDeleteAfterDays] = useState("7");
  const [recordEnabled, setRecordEnabled] = useState(false);
  const [schedulerEnabled, setSchedulerEnabledState] = useState(true);

  const loadMtx = async () => {
    setMtxBusy(true);
    setMtxError(null);
    try {
      const data = await apiJson<MediaMtxConfigView>("/mediamtx/config", { method: "GET" });
      setMtx(data);
      setRecordEnabled(Boolean(data.record_enabled));
      const d = data.record_delete_after_days;
      setRecordDeleteAfterDays(d === 1 || d === 3 || d === 7 ? String(d) : "7");
    } catch (e) {
      if (typeof e === "object" && e && "status" in e) {
        const ex = e as { status: number; bodyText?: string };
        setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
      } else {
        setMtxError("failed_to_load_mediamtx_config");
      }
    } finally {
      setMtxBusy(false);
    }
  };

  useEffect(() => {
    if (!config) void load();
    void loadMtx();
  }, [config, load]);

  useEffect(() => {
    if (!schedule) return;
    setWeekdaysFrom(schedule.weekdays_from);
    setWeekdaysTo(schedule.weekdays_to);
    setWeekendAllDay(schedule.weekend_all_day);
    setSchedulerEnabledState(Boolean(schedule.enabled));
  }, [schedule]);

  useEffect(() => {
    if (!config) return;
    setMediamtxApiUrl(config.mediamtx_api_url);
    setMediamtxWebrtcUrl(config.mediamtx_webrtc_url);
    setMediamtxApiUser(config.mediamtx_api_user ?? "");
    setMediamtxApiPass(config.mediamtx_api_pass ?? "");
    setRecordingsDir(config.recordings_dir);
    setApiPort(String(config.api_port ?? 8008));
  }, [config]);

  const canAdd = useMemo(() => rtspUrl.trim().length > 0, [rtspUrl]);

  const onAdd = async (e: FormEvent) => {
    e.preventDefault();
    if (!canAdd) return;
    setMtxBusy(true);
    setMtxError(null);
    try {
      const data = await apiJson<MediaMtxConfigView>("/mediamtx/cameras", {
        method: "POST",
        body: JSON.stringify({ rtsp_url: rtspUrl.trim() }),
      });
      setMtx(data);
      setRtspUrl("");
      await load();
    } catch (e) {
      if (typeof e === "object" && e && "status" in e) {
        const ex = e as { status: number; bodyText?: string };
        setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
      } else {
        setMtxError("failed_to_add_camera");
      }
    } finally {
      setMtxBusy(false);
    }
  };

  const onSaveAll = async () => {
    setMtxBusy(true);
    setMtxError(null);
    setRestartMsg(null);
    const payload: AppConfigUpdate = {
      mediamtx_api_url: mediamtxApiUrl.trim(),
      mediamtx_webrtc_url: mediamtxWebrtcUrl.trim(),
      mediamtx_api_user: mediamtxApiUser.trim() || null,
      mediamtx_api_pass: mediamtxApiPass.trim() || null,
      recordings_dir: recordingsDir.trim(),
      api_port: Number(apiPort) || 8008,
    };
    try {
      await apiJson("/config/basic", {
        method: "POST",
        body: JSON.stringify(payload),
      });
      await apiJson("/mediamtx/record-delete-after", {
        method: "POST",
        body: JSON.stringify({ days: Number(recordDeleteAfterDays) }),
      });
      await apiJson("/scheduler/schedule", {
        method: "POST",
        body: JSON.stringify({
          weekdays_from: weekdaysFrom,
          weekdays_to: weekdaysTo,
          weekend_all_day: weekendAllDay,
        }),
      });
      await apiJson("/scheduler/enabled", {
        method: "POST",
        body: JSON.stringify({ enabled: schedulerEnabled }),
      });
      await apiJson("/mediamtx/recording", {
        method: "POST",
        body: JSON.stringify({ enabled: recordEnabled }),
      });
      await load();
      await loadMtx();
      setRestartMsg("Lưu config.json và mediamtx.yml thành công");
    } catch (e) {
      if (typeof e === "object" && e && "status" in e) {
        const ex = e as { status: number; bodyText?: string };
        setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
      } else {
        setMtxError("failed_to_save_all");
      }
    } finally {
      setMtxBusy(false);
    }
  };

  const onDelete = async (name: string) => {
    setMtxBusy(true);
    setMtxError(null);
    try {
      const data = await apiJson<MediaMtxConfigView>(`/mediamtx/cameras/${encodeURIComponent(name)}`, {
        method: "DELETE",
      });
      setMtx(data);
      await load();
    } catch (e) {
      if (typeof e === "object" && e && "status" in e) {
        const ex = e as { status: number; bodyText?: string };
        setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
      } else {
        setMtxError("failed_to_delete_camera");
      }
    } finally {
      setMtxBusy(false);
    }
  };

  const onRestartDocker = async () => {
    setMtxBusy(true);
    setRestartMsg(null);
    setMtxError(null);
    try {
      const res = await apiJson<{ ok: boolean; output?: string }>("/mediamtx/restart", {
        method: "POST",
      });
      setRestartMsg(res.ok ? "Docker restart thành công" : "Docker restart thất bại");
    } catch (e) {
      if (typeof e === "object" && e && "status" in e) {
        const ex = e as { status: number; bodyText?: string };
        setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
      } else {
        setMtxError("failed_to_restart_docker");
      }
    } finally {
      setMtxBusy(false);
    }
  };

  return (
    <div className="space-y-4">
      <div>
        <div className="text-sm font-semibold">Settings</div>
        <div className="text-xs text-zinc-400">Camera management + recording schedule</div>
      </div>

      {error ? (
        <div className="rounded-lg border border-rose-900/60 bg-rose-950/30 px-4 py-3 text-sm text-rose-200">
          {error}
        </div>
      ) : null}
      {mtxError ? (
        <div className="rounded-lg border border-rose-900/60 bg-rose-950/30 px-4 py-3 text-sm text-rose-200">
          {mtxError}
        </div>
      ) : null}
      {restartMsg ? (
        <div className="rounded-lg border border-emerald-900/60 bg-emerald-950/30 px-4 py-3 text-sm text-emerald-200">
          {restartMsg}
        </div>
      ) : null}

      <div className="grid gap-3 lg:grid-cols-2">
        <div className="rounded-lg border border-zinc-800 bg-zinc-900/20 p-4">
          <div className="text-xs font-semibold text-zinc-200">Cameras</div>
          <div className="mt-1 text-xs text-zinc-400">Đọc và chỉnh trực tiếp từ `mediamtx.yml`</div>

          <div className="mt-3 space-y-2">
            {(mtx?.cameras ?? []).map((camera) => (
              <div
                key={camera.name}
                className="flex items-center justify-between gap-3 rounded-md border border-zinc-800 bg-zinc-950/10 px-3 py-2"
              >
                <div className="min-w-0">
                  <div className="truncate text-sm text-zinc-100">{camera.name}</div>
                  <div className="truncate text-xs text-zinc-500">{camera.rtsp_url}</div>
                </div>
                <button
                  type="button"
                  onClick={() => void onDelete(camera.name)}
                  disabled={mtxBusy}
                  className="inline-flex h-9 w-9 items-center justify-center rounded-md border border-zinc-700 bg-zinc-950/40 text-zinc-200 transition hover:bg-zinc-900 disabled:opacity-60"
                  title="Remove"
                >
                  <Trash2 className="h-4 w-4" />
                </button>
              </div>
            ))}
            {(mtx?.cameras ?? []).length === 0 ? (
              <div className="rounded-md border border-zinc-800 bg-zinc-950/10 px-3 py-2 text-xs text-zinc-400">
                Chưa có camera.
              </div>
            ) : null}
          </div>

          <form onSubmit={(e) => void onAdd(e)} className="mt-4 space-y-2">
            <div>
              <label className="text-xs text-zinc-400">RTSP URL</label>
              <input
                value={rtspUrl}
                onChange={(e) => setRtspUrl(e.target.value)}
                placeholder="rtsp://user:pass@ip:554/stream"
                className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
              />
            </div>
            <button
              type="submit"
              disabled={!canAdd || isLoading || mtxBusy}
              className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60"
            >
              <Plus className="h-4 w-4" />
              Add Camera
            </button>
          </form>
        </div>

        <div className="rounded-lg border border-zinc-800 bg-zinc-900/20 p-4">
          <div className="text-xs font-semibold text-zinc-200">Recording & Scheduler</div>
          <div className="mt-1 text-xs text-zinc-400">Camera lấy từ `mediamtx.yml`, các URL/credentials lấy từ `config.json`</div>

          <div className="mt-4 space-y-3">
            <div className="grid gap-2">
              <div>
                <label className="text-xs text-zinc-400">MediaMTX API URL</label>
                <input
                  value={mediamtxApiUrl}
                  onChange={(e) => setMediamtxApiUrl(e.target.value)}
                  placeholder="http://127.0.0.1:9997"
                  className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                />
              </div>
              <div>
                <label className="text-xs text-zinc-400">MediaMTX WebRTC URL</label>
                <input
                  value={mediamtxWebrtcUrl}
                  onChange={(e) => setMediamtxWebrtcUrl(e.target.value)}
                  placeholder="http://127.0.0.1:8889"
                  className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                />
              </div>
              <div className="grid gap-2 md:grid-cols-2">
                <div>
                  <label className="text-xs text-zinc-400">MediaMTX API User</label>
                  <input
                    value={mediamtxApiUser}
                    onChange={(e) => setMediamtxApiUser(e.target.value)}
                    placeholder="dashboard"
                    className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                  />
                </div>
                <div>
                  <label className="text-xs text-zinc-400">MediaMTX API Pass</label>
                  <input
                    type="password"
                    value={mediamtxApiPass}
                    onChange={(e) => setMediamtxApiPass(e.target.value)}
                    placeholder="password"
                    className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                  />
                </div>
              </div>
              <div className="grid gap-2 md:grid-cols-2">
                <div>
                  <label className="text-xs text-zinc-400">Recordings Dir</label>
                  <input
                    value={recordingsDir}
                    onChange={(e) => setRecordingsDir(e.target.value)}
                    placeholder="/mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings"
                    className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                  />
                </div>
                <div>
                  <label className="text-xs text-zinc-400">API Port</label>
                  <input
                    type="number"
                    min={1}
                    max={65535}
                    value={apiPort}
                    onChange={(e) => setApiPort(e.target.value)}
                    className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                  />
                </div>
              </div>
              <button
                type="button"
                onClick={() => void onSaveAll()}
                disabled={mtxBusy}
                className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60"
              >
                Save All
              </button>
            </div>

            <label className="flex items-center gap-2 text-sm text-zinc-200">
              <input
                type="checkbox"
                checked={recordEnabled}
                onChange={(e) => setRecordEnabled(e.target.checked)}
                className="h-4 w-4 rounded border-zinc-700 bg-zinc-950"
              />
              MediaMTX record (pathDefaults.record)
            </label>

            <div>
              <label className="text-xs text-zinc-400">recordDeleteAfter</label>
              <select
                value={recordDeleteAfterDays}
                onChange={(e) => setRecordDeleteAfterDays(e.target.value)}
                disabled={mtxBusy}
                className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100 disabled:opacity-60"
              >
                <option value="1">1 ngày</option>
                <option value="3">3 ngày</option>
                <option value="7">7 ngày</option>
              </select>
            </div>

            <label className="flex items-center gap-2 text-sm text-zinc-200">
              <input
                type="checkbox"
                checked={schedulerEnabled}
                onChange={(e) => setSchedulerEnabledState(e.target.checked)}
                className="h-4 w-4 rounded border-zinc-700 bg-zinc-950"
              />
              Enable scheduler
            </label>

            <div className="grid gap-2 md:grid-cols-2">
              <div>
                <label className="text-xs text-zinc-400">Weekdays from</label>
                <input
                  type="time"
                  value={weekdaysFrom}
                  onChange={(e) => setWeekdaysFrom(e.target.value)}
                  className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                />
              </div>
              <div>
                <label className="text-xs text-zinc-400">Weekdays to</label>
                <input
                  type="time"
                  value={weekdaysTo}
                  onChange={(e) => setWeekdaysTo(e.target.value)}
                  className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100"
                />
              </div>
            </div>

            <label className="flex items-center gap-2 text-sm text-zinc-200">
              <input
                type="checkbox"
                checked={weekendAllDay}
                onChange={(e) => setWeekendAllDay(e.target.checked)}
                className="h-4 w-4 rounded border-zinc-700 bg-zinc-950"
              />
              Weekend: record all day
            </label>

            <button
              type="button"
              onClick={() => void onRestartDocker()}
              disabled={mtxBusy}
              className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60"
            >
              Restart MediaMTX Docker
            </button>

            <div className="rounded-md border border-zinc-800 bg-zinc-950/10 px-3 py-2 text-xs text-zinc-400">
              MediaMTX API: <span className="text-zinc-200">{config?.mediamtx_api_url ?? "-"}</span>
              <br />
              WebRTC: <span className="text-zinc-200">{config?.mediamtx_webrtc_url ?? "-"}</span>
              <br />
              Recordings dir: <span className="text-zinc-200">{config?.recordings_dir ?? "-"}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

