import { useState, useEffect } from "react";
import {
  View,
  Text,
  TextInput,
  ScrollView,
  Switch,
  Pressable,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import * as SecureStore from "expo-secure-store";
import { Colors } from "@/constants/theme";
import { DEFAULT_TEMPLATE } from "@/lib/markdown";
import type { GitProvider } from "@/lib/git";
import type { AIProvider } from "@/lib/ai";
import { AI_PROVIDER_BASE_URLS, AI_PROVIDER_MODEL_PLACEHOLDERS } from "@/lib/ai";

const KEYS = {
  INPUT_MODE: "pref_input_mode",
  HOME_VIEW: "pref_home_view",
  AI_ENABLED: "pref_ai_enabled",
  AI_PROVIDER: "pref_ai_provider",
  AI_KEY: "pref_ai_key",
  AI_BASE_URL: "pref_ai_base_url",
  AI_MODEL: "pref_ai_model",
  TITLE_TEMPLATE: "pref_title_template",
  MD_TEMPLATE: "md_template",
  GIT_PROVIDER: "git_provider",
  GITEA_URL: "gitea_url",
  GITEA_TOKEN: "gitea_token",
  GITEA_OWNER: "gitea_owner",
  GITEA_REPO: "gitea_repo",
  GITHUB_TOKEN: "github_token",
  GITHUB_OWNER: "github_owner",
  GITHUB_REPO: "github_repo",
  GITLAB_URL: "gitlab_url",
  GITLAB_TOKEN: "gitlab_token",
  GITLAB_OWNER: "gitlab_owner",
  GITLAB_REPO: "gitlab_repo",
} as const;

const LABEL = {
  color: Colors.text2,
  fontSize: 11,
  fontWeight: "700" as const,
  textTransform: "uppercase" as const,
  letterSpacing: 0.6,
  marginBottom: 6,
} as const;

const SECTION_TITLE = {
  color: Colors.text1,
  fontSize: 16,
  fontWeight: "700" as const,
  marginTop: 28,
  marginBottom: 12,
} as const;

const INPUT = {
  backgroundColor: Colors.surface,
  borderColor: Colors.border,
  borderWidth: 1,
  borderRadius: 8,
  color: Colors.text1,
  padding: 12,
  fontSize: 14,
  marginBottom: 14,
  fontFamily: "monospace",
} as const;

const PROVIDER_LABELS: Record<GitProvider, string> = {
  gitea: "Gitea",
  github: "GitHub",
  gitlab: "GitLab",
};

function parseRepoUrl(raw: string, provider: GitProvider): { instanceUrl?: string; owner?: string; repo?: string } {
  try {
    const cleaned = raw.trim().replace(/\.git$/, "");
    const u = new URL(cleaned);
    const parts = u.pathname.split("/").filter(Boolean);
    if (parts.length < 2) return {};
    const repo = parts[parts.length - 1];
    const owner = parts[parts.length - 2];
    const instanceUrl = provider !== "github" ? `${u.protocol}//${u.host}` : undefined;
    return { instanceUrl, owner, repo };
  } catch {
    return {};
  }
}

function buildRepoUrl(instanceUrl: string | null, owner: string | null, repo: string | null, provider: GitProvider): string {
  if (!owner || !repo) return "";
  const base = provider === "github" ? "https://github.com" : (instanceUrl ?? "");
  if (!base) return "";
  return `${base}/${owner}/${repo}.git`;
}

// Defined outside SettingsScreen — prevents remount on every rerender, which
// would cause TextInput to lose focus after each keystroke.

function ToggleRow({
  label,
  value,
  onValueChange,
}: {
  label: string;
  value: boolean;
  onValueChange: (v: boolean) => void;
}) {
  return (
    <View
      style={{
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        backgroundColor: Colors.surface,
        borderRadius: 8,
        padding: 14,
        marginBottom: 10,
      }}
    >
      <Text style={{ color: Colors.text1, fontSize: 15 }}>{label}</Text>
      <Switch
        value={value}
        onValueChange={onValueChange}
        trackColor={{ true: Colors.primary, false: Colors.border }}
        thumbColor="#fff"
      />
    </View>
  );
}

function SegmentRow({
  label,
  options,
  value,
  onChange,
  wrap,
}: {
  label: string;
  options: { key: string; label: string }[];
  value: string;
  onChange: (v: string) => void;
  wrap?: boolean;
}) {
  return (
    <View style={{ marginBottom: 16 }}>
      <Text style={LABEL}>{label}</Text>
      <View style={{ flexDirection: "row", gap: 8, flexWrap: wrap ? "wrap" : "nowrap" }}>
        {options.map((opt) => (
          <Pressable
            key={opt.key}
            onPress={() => onChange(opt.key)}
            style={{
              ...(wrap ? { width: "31%" } : { flex: 1 }),
              backgroundColor:
                value === opt.key ? Colors.primary : Colors.surface,
              borderRadius: 8,
              padding: 12,
              alignItems: "center",
              borderWidth: 1,
              borderColor:
                value === opt.key ? Colors.primary : Colors.border,
            }}
          >
            <Text
              style={{
                color: value === opt.key ? Colors.bg : Colors.text2,
                fontWeight: "700",
                fontSize: 13,
              }}
            >
              {opt.label}
            </Text>
          </Pressable>
        ))}
      </View>
    </View>
  );
}

function Field({
  label,
  value,
  onChange,
  placeholder,
  secure,
  url,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  secure?: boolean;
  url?: boolean;
}) {
  return (
    <>
      <Text style={LABEL}>{label}</Text>
      <TextInput
        style={INPUT}
        value={value}
        onChangeText={onChange}
        placeholder={placeholder}
        placeholderTextColor={Colors.textDim}
        secureTextEntry={secure}
        autoCapitalize="none"
        autoCorrect={false}
        keyboardType={url ? "url" : "default"}
      />
    </>
  );
}

export default function SettingsScreen() {
  const insets = useSafeAreaInsets();
  const [inputMode, setInputMode] = useState<"voice" | "form">("form");
  const [homeView, setHomeView] = useState<"dashboard" | "capture">("dashboard");
  const [aiEnabled, setAiEnabled] = useState(false);
  const [aiProvider, setAiProvider] = useState<AIProvider>("openai");
  const [aiKey, setAiKey] = useState("");
  const [aiBaseUrl, setAiBaseUrl] = useState("");
  const [aiModel, setAiModel] = useState("");
  const [titleTemplate, setTitleTemplate] = useState("");
  const [mdTemplate, setMdTemplate] = useState(DEFAULT_TEMPLATE);
  const [saved, setSaved] = useState(false);

  const [gitProvider, setGitProvider] = useState<GitProvider>("gitea");
  const [giteaRepoUrl, setGiteaRepoUrl] = useState("");
  const [giteaToken, setGiteaToken] = useState("");
  const [githubRepoUrl, setGithubRepoUrl] = useState("");
  const [githubToken, setGithubToken] = useState("");
  const [gitlabRepoUrl, setGitlabRepoUrl] = useState("");
  const [gitlabToken, setGitlabToken] = useState("");

  useEffect(() => {
    (async () => {
      const [
        im, hv, ai, aip, key, aiUrl, aiMdl, titleTpl, tpl,
        gp, gu, gt, go, gr,
        ghu, ghown, ghrepo,
        glu, glt, glo, glr,
      ] = await Promise.all([
        SecureStore.getItemAsync(KEYS.INPUT_MODE),
        SecureStore.getItemAsync(KEYS.HOME_VIEW),
        SecureStore.getItemAsync(KEYS.AI_ENABLED),
        SecureStore.getItemAsync(KEYS.AI_PROVIDER),
        SecureStore.getItemAsync(KEYS.AI_KEY),
        SecureStore.getItemAsync(KEYS.AI_BASE_URL),
        SecureStore.getItemAsync(KEYS.AI_MODEL),
        SecureStore.getItemAsync(KEYS.TITLE_TEMPLATE),
        SecureStore.getItemAsync(KEYS.MD_TEMPLATE),
        SecureStore.getItemAsync(KEYS.GIT_PROVIDER),
        SecureStore.getItemAsync(KEYS.GITEA_URL),
        SecureStore.getItemAsync(KEYS.GITEA_TOKEN),
        SecureStore.getItemAsync(KEYS.GITEA_OWNER),
        SecureStore.getItemAsync(KEYS.GITEA_REPO),
        SecureStore.getItemAsync(KEYS.GITHUB_TOKEN),
        SecureStore.getItemAsync(KEYS.GITHUB_OWNER),
        SecureStore.getItemAsync(KEYS.GITHUB_REPO),
        SecureStore.getItemAsync(KEYS.GITLAB_URL),
        SecureStore.getItemAsync(KEYS.GITLAB_TOKEN),
        SecureStore.getItemAsync(KEYS.GITLAB_OWNER),
        SecureStore.getItemAsync(KEYS.GITLAB_REPO),
      ]);
      if (im) setInputMode(im as "voice" | "form");
      if (hv) setHomeView(hv as "dashboard" | "capture");
      if (ai) setAiEnabled(ai === "true");
      if (aip) setAiProvider(aip as AIProvider);
      if (key) setAiKey(key);
      if (aiUrl) setAiBaseUrl(aiUrl);
      if (aiMdl) setAiModel(aiMdl);
      if (titleTpl) setTitleTemplate(titleTpl);
      if (tpl) setMdTemplate(tpl);
      if (gp) setGitProvider(gp as GitProvider);
      if (gt) setGiteaToken(gt);
      setGiteaRepoUrl(buildRepoUrl(gu, go, gr, "gitea"));
      if (ghu) setGithubToken(ghu);
      setGithubRepoUrl(buildRepoUrl(null, ghown, ghrepo, "github"));
      if (glt) setGitlabToken(glt);
      setGitlabRepoUrl(buildRepoUrl(glu, glo, glr, "gitlab"));
    })();
  }, []);

  async function handleSave() {
    const gitea = parseRepoUrl(giteaRepoUrl, "gitea");
    const github = parseRepoUrl(githubRepoUrl, "github");
    const gitlab = parseRepoUrl(gitlabRepoUrl, "gitlab");
    await Promise.all([
      SecureStore.setItemAsync(KEYS.INPUT_MODE, inputMode),
      SecureStore.setItemAsync(KEYS.HOME_VIEW, homeView),
      SecureStore.setItemAsync(KEYS.AI_ENABLED, String(aiEnabled)),
      SecureStore.setItemAsync(KEYS.AI_PROVIDER, aiProvider),
      SecureStore.setItemAsync(KEYS.AI_KEY, aiKey),
      SecureStore.setItemAsync(KEYS.AI_BASE_URL, aiBaseUrl),
      SecureStore.setItemAsync(KEYS.AI_MODEL, aiModel),
      SecureStore.setItemAsync(KEYS.TITLE_TEMPLATE, titleTemplate),
      SecureStore.setItemAsync(KEYS.MD_TEMPLATE, mdTemplate),
      SecureStore.setItemAsync(KEYS.GIT_PROVIDER, gitProvider),
      SecureStore.setItemAsync(KEYS.GITEA_URL, gitea.instanceUrl ?? ""),
      SecureStore.setItemAsync(KEYS.GITEA_TOKEN, giteaToken),
      SecureStore.setItemAsync(KEYS.GITEA_OWNER, gitea.owner ?? ""),
      SecureStore.setItemAsync(KEYS.GITEA_REPO, gitea.repo ?? ""),
      SecureStore.setItemAsync(KEYS.GITHUB_TOKEN, githubToken),
      SecureStore.setItemAsync(KEYS.GITHUB_OWNER, github.owner ?? ""),
      SecureStore.setItemAsync(KEYS.GITHUB_REPO, github.repo ?? ""),
      SecureStore.setItemAsync(KEYS.GITLAB_URL, gitlab.instanceUrl ?? ""),
      SecureStore.setItemAsync(KEYS.GITLAB_TOKEN, gitlabToken),
      SecureStore.setItemAsync(KEYS.GITLAB_OWNER, gitlab.owner ?? ""),
      SecureStore.setItemAsync(KEYS.GITLAB_REPO, gitlab.repo ?? ""),
    ]);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  return (
    <ScrollView
      style={{ flex: 1, backgroundColor: Colors.bg }}
      contentContainerStyle={{ padding: 16, paddingBottom: 48 + insets.bottom }}
      keyboardShouldPersistTaps="handled"
    >
      <Text style={SECTION_TITLE}>Preferences</Text>

      <SegmentRow
        label="Default Input"
        value={inputMode}
        onChange={(v) => setInputMode(v as "voice" | "form")}
        options={[
          { key: "form", label: "Form" },
          { key: "voice", label: "Voice" },
        ]}
      />

      <SegmentRow
        label="Home View"
        value={homeView}
        onChange={(v) => setHomeView(v as "dashboard" | "capture")}
        options={[
          { key: "dashboard", label: "Dashboard" },
          { key: "capture", label: "Quick Capture" },
        ]}
      />

      <Field
        label="Title Template"
        value={titleTemplate}
        onChange={setTitleTemplate}
        placeholder="INC-001  (leave empty to disable)"
      />
      <View
        style={{
          backgroundColor: Colors.surface,
          borderRadius: 8,
          padding: 10,
          marginTop: -8,
          marginBottom: 14,
          borderLeftWidth: 3,
          borderLeftColor: Colors.text2,
        }}
      >
        <Text style={{ color: Colors.text2, fontSize: 12, lineHeight: 18 }}>
          Pre-fills the Title field on new incidents. If the value ends with
          digits, the number is auto-incremented after each save.{"\n"}
          e.g. INC-001 → INC-002 → INC-003
        </Text>
      </View>

      <Text style={SECTION_TITLE}>AI — Root Cause Assistant</Text>
      <View
        style={{
          backgroundColor: Colors.surface,
          borderRadius: 8,
          padding: 12,
          marginBottom: 14,
          borderLeftWidth: 3,
          borderLeftColor: Colors.text2,
        }}
      >
        <Text style={{ color: Colors.text2, fontSize: 13, lineHeight: 20 }}>
          When enabled, a Suggest button appears between Symptom and Root Cause.
          It sends the title and symptom to your AI provider and pre-fills the
          analysis fields. Supports Anthropic natively; all others use the
          OpenAI-compatible API.
        </Text>
      </View>
      <ToggleRow
        label="Enable AI assistance"
        value={aiEnabled}
        onValueChange={setAiEnabled}
      />
      {aiEnabled && (
        <>
          <SegmentRow
            label="Provider"
            value={aiProvider}
            wrap
            onChange={(v) => {
              const p = v as AIProvider;
              setAiProvider(p);
              setAiBaseUrl(AI_PROVIDER_BASE_URLS[p]);
            }}
            options={[
              { key: "anthropic", label: "Anthropic" },
              { key: "openai", label: "OpenAI" },
              { key: "mistral", label: "Mistral" },
              { key: "perplexity", label: "Perplexity" },
              { key: "ollama", label: "Ollama" },
              { key: "openrouter", label: "OpenRouter" },
              { key: "custom", label: "Custom" },
            ]}
          />
          {aiProvider !== "anthropic" && (
            <Field
              label="Base URL"
              value={aiBaseUrl}
              onChange={setAiBaseUrl}
              placeholder={AI_PROVIDER_BASE_URLS[aiProvider] || "https://your-api.example.com/v1"}
              url
            />
          )}
          <Field
            label="Model"
            value={aiModel}
            onChange={setAiModel}
            placeholder={AI_PROVIDER_MODEL_PLACEHOLDERS[aiProvider]}
          />
          <Field
            label="API Key"
            value={aiKey}
            onChange={setAiKey}
            placeholder={aiProvider === "ollama" ? "no key required" : "paste your API key"}
            secure
          />
        </>
      )}

      <Text style={SECTION_TITLE}>Git Repository</Text>

      <SegmentRow
        label="Provider"
        value={gitProvider}
        onChange={(v) => setGitProvider(v as GitProvider)}
        options={(["gitea", "github", "gitlab"] as GitProvider[]).map((p) => ({
          key: p,
          label: PROVIDER_LABELS[p],
        }))}
      />

      {gitProvider === "gitea" && (
        <>
          <Field
            label="Repo URL"
            value={giteaRepoUrl}
            onChange={setGiteaRepoUrl}
            placeholder="https://homegit.example.com/username/incidents.git"
            url
          />
          <Field
            label="Token (PAT, write:repository)"
            value={giteaToken}
            onChange={setGiteaToken}
            placeholder="paste token value — no Bearer prefix"
            secure
          />
          <View
            style={{
              backgroundColor: Colors.surface,
              borderRadius: 8,
              padding: 10,
              marginTop: -8,
              marginBottom: 14,
              borderLeftWidth: 3,
              borderLeftColor: Colors.text2,
            }}
          >
            <Text style={{ color: Colors.text2, fontSize: 12, lineHeight: 18 }}>
              The repo must have at least one commit — initialize it with a README if empty.
            </Text>
          </View>
        </>
      )}

      {gitProvider === "github" && (
        <>
          <Field
            label="Repo URL"
            value={githubRepoUrl}
            onChange={setGithubRepoUrl}
            placeholder="https://github.com/username/incidents.git"
            url
          />
          <Field
            label="Personal Access Token"
            value={githubToken}
            onChange={setGithubToken}
            placeholder="ghp_..."
            secure
          />
        </>
      )}

      {gitProvider === "gitlab" && (
        <>
          <Field
            label="Repo URL"
            value={gitlabRepoUrl}
            onChange={setGitlabRepoUrl}
            placeholder="https://gitlab.com/username/incidents.git"
            url
          />
          <Field
            label="Personal Access Token"
            value={gitlabToken}
            onChange={setGitlabToken}
            placeholder="glpat-..."
            secure
          />
        </>
      )}

      <Text style={SECTION_TITLE}>Markdown Template</Text>
      <TextInput
        style={{ ...INPUT, minHeight: 200, textAlignVertical: "top" }}
        value={mdTemplate}
        onChangeText={setMdTemplate}
        multiline
        placeholder={DEFAULT_TEMPLATE}
        placeholderTextColor={Colors.textDim}
      />

      <Pressable
        onPress={handleSave}
        style={{
          backgroundColor: saved ? Colors.success : Colors.primary,
          borderRadius: 10,
          padding: 16,
          alignItems: "center",
          marginTop: 8,
        }}
      >
        <Text style={{ color: Colors.bg, fontSize: 16, fontWeight: "700" }}>
          {saved ? "Saved ✓" : "Save Settings"}
        </Text>
      </Pressable>
    </ScrollView>
  );
}
