import type { ModelConfig, ModelConfigMap, ModelRole } from "@infiplot/types";
import { SymbolView } from "expo-symbols";
import type { ComponentProps } from "react";
import { useEffect, useMemo, useState } from "react";
import {
  Pressable,
  ScrollView,
  Switch,
  Text,
  TextInput,
  View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";

import { BottomTabInset } from "@/constants/theme";
import {
  clearModelConfig,
  defaultModelConfig,
  readModelConfig,
  writeModelConfig,
} from "@/lib/model-config";

type SymbolName = ComponentProps<typeof SymbolView>["name"];

const modelGroups: {
  id: ModelRole;
  title: string;
  hint: string;
  accent: string;
}[] = [
  {
    id: "text",
    title: "文本模型",
    hint: "剧情、分镜、选择分支",
    accent: "#ff4d6d",
  },
  {
    id: "image",
    title: "图像模型",
    hint: "角色、场景、封面生成",
    accent: "#b8ff5d",
  },
  {
    id: "vision",
    title: "视觉理解",
    hint: "风格图解析、画面标注",
    accent: "#78d7ff",
  },
  { id: "tts", title: "语音模型", hint: "对白配音、旁白", accent: "#ffd166" },
];

const roleLabels: Record<ModelRole, string> = {
  text: "文本",
  image: "图像",
  vision: "视觉",
  tts: "语音",
};

export default function ProfileScreen() {
  const [syncEnabled, setSyncEnabled] = useState(true);
  const [showKeys, setShowKeys] = useState(false);
  const [signedIn, setSignedIn] = useState(false);
  const [email, setEmail] = useState("");
  const [selectedRole, setSelectedRole] = useState<ModelRole>("text");
  const [configs, setConfigs] = useState<ModelConfigMap>(defaultModelConfig);
  const [savedConfigs, setSavedConfigs] =
    useState<ModelConfigMap>(defaultModelConfig);
  const [status, setStatus] = useState<"loading" | "saved" | "dirty">(
    "loading",
  );

  useEffect(() => {
    let mounted = true;

    readModelConfig().then((stored) => {
      if (!mounted) return;
      setConfigs(stored);
      setSavedConfigs(stored);
      setStatus("saved");
    });

    return () => {
      mounted = false;
    };
  }, []);

  const selectedGroup =
    modelGroups.find((group) => group.id === selectedRole) ?? modelGroups[0];
  const selectedConfig = configs[selectedRole];

  const configuredCount = useMemo(
    () =>
      Object.values(configs).filter((config) => config.apiKey.trim().length > 0)
        .length,
    [configs],
  );

  const dirty = useMemo(
    () => JSON.stringify(configs) !== JSON.stringify(savedConfigs),
    [configs, savedConfigs],
  );

  function updateConfig(field: keyof ModelConfig, value: string) {
    setConfigs((current) => ({
      ...current,
      [selectedRole]: {
        ...current[selectedRole],
        [field]: value,
      },
    }));
    setStatus("dirty");
  }

  async function handleSave() {
    const saved = await writeModelConfig(configs);
    setConfigs(saved);
    setSavedConfigs(saved);
    setStatus("saved");
  }

  async function handleReset() {
    const reset = await clearModelConfig();
    setConfigs(reset);
    setSavedConfigs(reset);
    setSelectedRole("text");
    setStatus("saved");
  }

  function handleAuthAction() {
    if (signedIn) {
      setSignedIn(false);
      setEmail("");
      return;
    }

    if (email.trim().length > 3) {
      setSignedIn(true);
    }
  }

  return (
    <SafeAreaView className="flex-1 bg-[#09090b]">
      <ScrollView
        contentContainerStyle={{ paddingBottom: BottomTabInset + 34 }}
        keyboardShouldPersistTaps="handled"
      >
        <View className="gap-[18px] p-[18px]">
          <View className="flex-row items-center gap-3 rounded-lg bg-white/10 p-3.5">
            <View className="h-[54px] w-[54px] items-center justify-center rounded-full bg-[#ff4d6d]">
              <Text className="text-lg font-black text-white">IP</Text>
            </View>
            <View className="flex-1 gap-[3px]">
              <Text className="text-lg font-black text-white">
                {signedIn ? "InfiPlot 创作者" : "未登录创作者"}
              </Text>
              <Text className="text-xs font-bold leading-[17px] text-white/60">
                {signedIn
                  ? email.trim()
                  : "登录后同步我的剧情、草稿和模型配置。"}
              </Text>
            </View>
            <Pressable
              onPress={handleAuthAction}
              className="h-9 justify-center rounded-full bg-white px-4"
              style={({ pressed }) => ({ opacity: pressed ? 0.76 : undefined })}
            >
              <Text className="text-[13px] font-black text-[#09090b]">
                {signedIn ? "退出" : "登录"}
              </Text>
            </Pressable>
          </View>

          {!signedIn && (
            <View className="flex-row gap-2.5 rounded-lg bg-white/[0.06] p-3">
              <TextInput
                value={email}
                onChangeText={setEmail}
                autoCapitalize="none"
                autoCorrect={false}
                keyboardType="email-address"
                placeholder="creator@infiplot.app"
                placeholderTextColor="rgba(255,255,255,0.35)"
                className="min-h-[42px] flex-1 rounded-lg border border-white/10 bg-black/20 px-3 text-[13px] font-bold text-white"
              />
              <Pressable
                onPress={handleAuthAction}
                disabled={email.trim().length <= 3}
                className={`h-[42px] min-w-[70px] items-center justify-center rounded-full bg-white ${
                  email.trim().length <= 3 ? "opacity-40" : ""
                }`}
                style={({ pressed }) => ({
                  opacity:
                    pressed && email.trim().length > 3 ? 0.76 : undefined,
                })}
              >
                <Text className="text-[13px] font-black text-[#09090b]">
                  继续
                </Text>
              </Pressable>
            </View>
          )}

          <View className="flex-row rounded-lg bg-white/[0.06] py-3.5">
            <Stat value="12" label="草稿" />
            <Stat value="4" label="已发布" />
            <Stat value={`${configuredCount}/4`} label="API" />
          </View>

          <View className="flex-row items-center justify-between gap-4">
            <View>
              <Text className="text-[23px] font-black text-white">
                模型 API
              </Text>
              <Text className="mt-1 text-xs font-bold leading-[18px] text-white/60">
                对应 web 端文字、图片、视觉和 TTS 配置。
              </Text>
            </View>
            <Pressable
              onPress={() => setShowKeys((value) => !value)}
              className="h-[42px] w-[42px] items-center justify-center rounded-full bg-white/10"
              style={({ pressed }) => ({ opacity: pressed ? 0.76 : undefined })}
            >
              <SymbolView
                name={{
                  ios: showKeys ? "eye.slash.fill" : "eye.fill",
                  android: showKeys ? "visibility_off" : "visibility",
                  web: showKeys ? "visibility_off" : "visibility",
                }}
                size={18}
                tintColor="#fff"
              />
            </Pressable>
          </View>

          <View className="flex-row gap-2">
            {modelGroups.map((group) => {
              const selected = group.id === selectedRole;
              const configured = configs[group.id].apiKey.trim().length > 0;

              return (
                <Pressable
                  key={group.id}
                  onPress={() => setSelectedRole(group.id)}
                  className={`min-h-[42px] flex-1 flex-row items-center justify-center gap-1.5 rounded-lg border ${
                    selected
                      ? "border-white/20 bg-white/[0.14]"
                      : "border-white/10 bg-white/[0.07]"
                  }`}
                  style={({ pressed }) => ({
                    opacity: pressed ? 0.76 : undefined,
                  })}
                >
                  <View
                    className="h-[7px] w-[7px] rounded-full"
                    style={{
                      backgroundColor: configured ? group.accent : "#4a4a52",
                    }}
                  />
                  <Text
                    className={`text-xs font-black ${selected ? "text-white" : "text-white/60"}`}
                  >
                    {roleLabels[group.id]}
                  </Text>
                </Pressable>
              );
            })}
          </View>

          <View className="gap-3 rounded-lg border border-white/10 bg-white/[0.075] p-3.5">
            <View className="flex-row justify-between gap-3">
              <View>
                <Text className="text-[17px] font-black text-white">
                  {selectedGroup.title}
                </Text>
                <Text className="mt-[3px] text-xs font-bold text-white/50">
                  {selectedGroup.hint}
                </Text>
              </View>
              <View
                className={`h-[26px] justify-center rounded-full px-2.5 ${dirty ? "bg-[#ffd166]/15" : "bg-[#b8ff5d]/15"}`}
              >
                <Text
                  className={`text-[11px] font-black ${dirty ? "text-[#ffd166]" : "text-[#b8ff5d]"}`}
                >
                  {status === "loading"
                    ? "读取中"
                    : dirty
                      ? "未保存"
                      : "已保存"}
                </Text>
              </View>
            </View>

            <InputLine
              label="Provider"
              value={selectedConfig.provider}
              onChangeText={(value) => updateConfig("provider", value)}
              placeholder="openai / claude / gemini / stepfun"
            />
            <InputLine
              label="Base URL"
              value={selectedConfig.baseUrl}
              onChangeText={(value) => updateConfig("baseUrl", value)}
              placeholder="https://api.example.com/v1"
            />
            <InputLine
              label="API Key"
              value={selectedConfig.apiKey}
              onChangeText={(value) => updateConfig("apiKey", value)}
              secureTextEntry={!showKeys}
              placeholder="sk-..."
            />
            <InputLine
              label="Model"
              value={selectedConfig.model}
              onChangeText={(value) => updateConfig("model", value)}
              placeholder="model name"
            />

            <View className="mt-0.5 flex-row gap-2.5">
              <Pressable
                onPress={handleReset}
                className="h-11 justify-center rounded-full bg-white/10 px-[18px]"
                style={({ pressed }) => ({
                  opacity: pressed ? 0.76 : undefined,
                })}
              >
                <Text className="text-sm font-black text-white">重置</Text>
              </Pressable>
              <Pressable
                onPress={handleSave}
                disabled={!dirty}
                className={`h-11 flex-1 flex-row items-center justify-center gap-[7px] rounded-full bg-white ${
                  !dirty ? "opacity-40" : ""
                }`}
                style={({ pressed }) => ({
                  opacity: pressed && dirty ? 0.76 : undefined,
                })}
              >
                <SymbolView
                  name={{
                    ios: "checkmark.circle.fill",
                    android: "check_circle",
                    web: "check_circle",
                  }}
                  size={18}
                  tintColor="#09090b"
                />
                <Text className="text-sm font-black text-[#09090b]">
                  保存配置
                </Text>
              </Pressable>
            </View>
          </View>

          <View className="flex-row items-center justify-between gap-[18px] rounded-lg bg-white/[0.07] p-3.5">
            <View className="flex-1 gap-[3px]">
              <Text className="text-[15px] font-black text-white">
                云端同步
              </Text>
              <Text className="text-xs font-bold text-white/50">
                登录后自动同步我的剧情和配置。
              </Text>
            </View>
            <Switch
              value={syncEnabled}
              onValueChange={setSyncEnabled}
              trackColor={{ false: "#303036", true: "#ff4d6d" }}
              thumbColor="#fff"
            />
          </View>

          <View className="overflow-hidden rounded-lg bg-white/[0.07]">
            <MenuItem
              name={{
                ios: "tray.and.arrow.down.fill",
                android: "download",
                web: "download",
              }}
              label="导入 .infiplot 剧情"
            />
            <MenuItem
              name={{
                ios: "lock.shield.fill",
                android: "shield",
                web: "shield",
              }}
              label="隐私与本地密钥"
            />
            <MenuItem
              name={{
                ios: "questionmark.circle.fill",
                android: "help",
                web: "help",
              }}
              label="帮助与反馈"
            />
          </View>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

function Stat({ value, label }: { value: string; label: string }) {
  return (
    <View className="flex-1 items-center gap-1">
      <Text className="text-xl font-black text-white">{value}</Text>
      <Text className="text-xs font-extrabold text-white/50">{label}</Text>
    </View>
  );
}

function InputLine({
  label,
  value,
  onChangeText,
  secureTextEntry,
  placeholder,
}: {
  label: string;
  value: string;
  onChangeText: (value: string) => void;
  secureTextEntry?: boolean;
  placeholder: string;
}) {
  return (
    <View className="gap-1.5">
      <Text className="text-[11px] font-black text-white/50">{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChangeText}
        secureTextEntry={secureTextEntry}
        autoCapitalize="none"
        autoCorrect={false}
        className="min-h-[42px] rounded-lg border border-white/10 bg-black/20 px-3 text-[13px] font-bold text-white"
        placeholder={placeholder}
        placeholderTextColor="rgba(255,255,255,0.35)"
      />
    </View>
  );
}

function MenuItem({ name, label }: { name: SymbolName; label: string }) {
  return (
    <Pressable
      className="min-h-14 flex-row items-center gap-3 border-b border-white/10 px-3.5"
      style={({ pressed }) => ({ opacity: pressed ? 0.76 : undefined })}
    >
      <View className="h-[34px] w-[34px] items-center justify-center rounded-full bg-white/10">
        <SymbolView name={name} size={18} tintColor="#fff" />
      </View>
      <Text className="flex-1 text-sm font-extrabold text-white">{label}</Text>
      <SymbolView
        name={{
          ios: "chevron.right",
          android: "chevron_right",
          web: "chevron_right",
        }}
        size={14}
        tintColor="rgba(255,255,255,0.4)"
      />
    </Pressable>
  );
}
