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,
  StyleSheet,
  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 style={styles.safe}>
      <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
        <View style={styles.profileCard}>
          <View style={styles.avatar}>
            <Text style={styles.avatarText}>IP</Text>
          </View>
          <View style={styles.profileCopy}>
            <Text style={styles.name}>{signedIn ? 'InfiPlot 创作者' : '未登录创作者'}</Text>
            <Text style={styles.subline}>
              {signedIn ? email.trim() : '登录后同步我的剧情、草稿和模型配置。'}
            </Text>
          </View>
          <Pressable
            onPress={handleAuthAction}
            style={({ pressed }) => [styles.loginButton, pressed && styles.pressed]}>
            <Text style={styles.loginText}>{signedIn ? '退出' : '登录'}</Text>
          </Pressable>
        </View>

        {!signedIn && (
          <View style={styles.loginPanel}>
            <TextInput
              value={email}
              onChangeText={setEmail}
              autoCapitalize="none"
              autoCorrect={false}
              keyboardType="email-address"
              placeholder="creator@infiplot.app"
              placeholderTextColor="rgba(255,255,255,0.35)"
              style={styles.loginInput}
            />
            <Pressable
              onPress={handleAuthAction}
              disabled={email.trim().length <= 3}
              style={({ pressed }) => [
                styles.loginSubmit,
                email.trim().length <= 3 && styles.disabledButton,
                pressed && email.trim().length > 3 && styles.pressed,
              ]}>
              <Text style={styles.loginSubmitText}>继续</Text>
            </Pressable>
          </View>
        )}

        <View style={styles.stats}>
          <Stat value="12" label="草稿" />
          <Stat value="4" label="已发布" />
          <Stat value={`${configuredCount}/4`} label="API" />
        </View>

        <View style={styles.sectionHeader}>
          <View>
            <Text style={styles.sectionTitle}>模型 API</Text>
            <Text style={styles.sectionHint}>对应 web 端文字、图片、视觉和 TTS 配置。</Text>
          </View>
          <Pressable
            onPress={() => setShowKeys((value) => !value)}
            style={({ pressed }) => [styles.iconButton, pressed && styles.pressed]}>
            <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 style={styles.roleTabs}>
          {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)}
                style={({ pressed }) => [
                  styles.roleTab,
                  selected && styles.selectedRoleTab,
                  pressed && styles.pressed,
                ]}>
                <View style={[styles.roleDot, { backgroundColor: configured ? group.accent : '#4a4a52' }]} />
                <Text style={[styles.roleText, selected && styles.selectedRoleText]}>
                  {roleLabels[group.id]}
                </Text>
              </Pressable>
            );
          })}
        </View>

        <View style={styles.modelEditor}>
          <View style={styles.modelTop}>
            <View>
              <Text style={styles.modelTitle}>{selectedGroup.title}</Text>
              <Text style={styles.modelHint}>{selectedGroup.hint}</Text>
            </View>
            <View style={[styles.statusPill, dirty && styles.dirtyPill]}>
              <Text style={[styles.statusText, dirty && styles.dirtyText]}>
                {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 style={styles.actionRow}>
            <Pressable
              onPress={handleReset}
              style={({ pressed }) => [styles.secondaryButton, pressed && styles.pressed]}>
              <Text style={styles.secondaryText}>重置</Text>
            </Pressable>
            <Pressable
              onPress={handleSave}
              disabled={!dirty}
              style={({ pressed }) => [
                styles.saveButton,
                !dirty && styles.disabledButton,
                pressed && dirty && styles.pressed,
              ]}>
              <SymbolView
                name={{ ios: 'checkmark.circle.fill', android: 'check_circle', web: 'check_circle' }}
                size={18}
                tintColor="#09090b"
              />
              <Text style={styles.saveText}>保存配置</Text>
            </Pressable>
          </View>
        </View>

        <View style={styles.settingRow}>
          <View style={styles.settingTextBlock}>
            <Text style={styles.settingTitle}>云端同步</Text>
            <Text style={styles.settingHint}>登录后自动同步我的剧情和配置。</Text>
          </View>
          <Switch
            value={syncEnabled}
            onValueChange={setSyncEnabled}
            trackColor={{ false: '#303036', true: '#ff4d6d' }}
            thumbColor="#fff"
          />
        </View>

        <View style={styles.menuList}>
          <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>
      </ScrollView>
    </SafeAreaView>
  );
}

function Stat({ value, label }: { value: string; label: string }) {
  return (
    <View style={styles.stat}>
      <Text style={styles.statValue}>{value}</Text>
      <Text style={styles.statLabel}>{label}</Text>
    </View>
  );
}

function InputLine({
  label,
  value,
  onChangeText,
  secureTextEntry,
  placeholder,
}: {
  label: string;
  value: string;
  onChangeText: (value: string) => void;
  secureTextEntry?: boolean;
  placeholder: string;
}) {
  return (
    <View style={styles.inputLine}>
      <Text style={styles.inputLabel}>{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChangeText}
        secureTextEntry={secureTextEntry}
        autoCapitalize="none"
        autoCorrect={false}
        style={styles.input}
        placeholder={placeholder}
        placeholderTextColor="rgba(255,255,255,0.35)"
      />
    </View>
  );
}

function MenuItem({ name, label }: { name: SymbolName; label: string }) {
  return (
    <Pressable style={({ pressed }) => [styles.menuItem, pressed && styles.pressed]}>
      <View style={styles.menuIcon}>
        <SymbolView name={name} size={18} tintColor="#fff" />
      </View>
      <Text style={styles.menuLabel}>{label}</Text>
      <SymbolView
        name={{ ios: 'chevron.right', android: 'chevron_right', web: 'chevron_right' }}
        size={14}
        tintColor="rgba(255,255,255,0.4)"
      />
    </Pressable>
  );
}

const styles = StyleSheet.create({
  safe: {
    flex: 1,
    backgroundColor: '#09090b',
  },
  content: {
    padding: 18,
    paddingBottom: BottomTabInset + 34,
    gap: 18,
  },
  profileCard: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
    borderRadius: 8,
    padding: 14,
    backgroundColor: 'rgba(255,255,255,0.08)',
  },
  avatar: {
    width: 54,
    height: 54,
    borderRadius: 27,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#ff4d6d',
  },
  avatarText: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '900',
  },
  profileCopy: {
    flex: 1,
    gap: 3,
  },
  name: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '900',
  },
  subline: {
    color: 'rgba(255,255,255,0.58)',
    fontSize: 12,
    lineHeight: 17,
    fontWeight: '700',
  },
  loginButton: {
    height: 36,
    paddingHorizontal: 16,
    borderRadius: 18,
    justifyContent: 'center',
    backgroundColor: '#fff',
  },
  loginText: {
    color: '#09090b',
    fontSize: 13,
    fontWeight: '900',
  },
  loginPanel: {
    flexDirection: 'row',
    gap: 10,
    borderRadius: 8,
    padding: 12,
    backgroundColor: 'rgba(255,255,255,0.06)',
  },
  loginInput: {
    flex: 1,
    minHeight: 42,
    borderRadius: 8,
    paddingHorizontal: 12,
    color: '#fff',
    fontSize: 13,
    fontWeight: '700',
    backgroundColor: 'rgba(0,0,0,0.22)',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
  },
  loginSubmit: {
    minWidth: 70,
    height: 42,
    borderRadius: 21,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#fff',
  },
  loginSubmitText: {
    color: '#09090b',
    fontSize: 13,
    fontWeight: '900',
  },
  stats: {
    flexDirection: 'row',
    borderRadius: 8,
    paddingVertical: 14,
    backgroundColor: 'rgba(255,255,255,0.06)',
  },
  stat: {
    flex: 1,
    alignItems: 'center',
    gap: 4,
  },
  statValue: {
    color: '#fff',
    fontSize: 20,
    fontWeight: '900',
  },
  statLabel: {
    color: 'rgba(255,255,255,0.54)',
    fontSize: 12,
    fontWeight: '800',
  },
  sectionHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 16,
  },
  sectionTitle: {
    color: '#fff',
    fontSize: 23,
    fontWeight: '900',
  },
  sectionHint: {
    color: 'rgba(255,255,255,0.56)',
    fontSize: 12,
    lineHeight: 18,
    fontWeight: '700',
    marginTop: 4,
  },
  iconButton: {
    width: 42,
    height: 42,
    borderRadius: 21,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(255,255,255,0.1)',
  },
  roleTabs: {
    flexDirection: 'row',
    gap: 8,
  },
  roleTab: {
    flex: 1,
    minHeight: 42,
    borderRadius: 8,
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
    gap: 6,
    backgroundColor: 'rgba(255,255,255,0.07)',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
  },
  selectedRoleTab: {
    backgroundColor: 'rgba(255,255,255,0.14)',
    borderColor: 'rgba(255,255,255,0.2)',
  },
  roleDot: {
    width: 7,
    height: 7,
    borderRadius: 7,
  },
  roleText: {
    color: 'rgba(255,255,255,0.58)',
    fontSize: 12,
    fontWeight: '900',
  },
  selectedRoleText: {
    color: '#fff',
  },
  modelEditor: {
    gap: 12,
    borderRadius: 8,
    padding: 14,
    backgroundColor: 'rgba(255,255,255,0.075)',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
  },
  modelTop: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    gap: 12,
  },
  modelTitle: {
    color: '#fff',
    fontSize: 17,
    fontWeight: '900',
  },
  modelHint: {
    color: 'rgba(255,255,255,0.52)',
    fontSize: 12,
    fontWeight: '700',
    marginTop: 3,
  },
  statusPill: {
    height: 26,
    justifyContent: 'center',
    borderRadius: 13,
    paddingHorizontal: 10,
    backgroundColor: 'rgba(184,255,93,0.16)',
  },
  dirtyPill: {
    backgroundColor: 'rgba(255,209,102,0.16)',
  },
  statusText: {
    color: '#b8ff5d',
    fontSize: 11,
    fontWeight: '900',
  },
  dirtyText: {
    color: '#ffd166',
  },
  inputLine: {
    gap: 6,
  },
  inputLabel: {
    color: 'rgba(255,255,255,0.5)',
    fontSize: 11,
    fontWeight: '900',
  },
  input: {
    minHeight: 42,
    borderRadius: 8,
    paddingHorizontal: 12,
    color: '#fff',
    fontSize: 13,
    fontWeight: '700',
    backgroundColor: 'rgba(0,0,0,0.22)',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
  },
  actionRow: {
    flexDirection: 'row',
    gap: 10,
    marginTop: 2,
  },
  secondaryButton: {
    height: 44,
    borderRadius: 22,
    paddingHorizontal: 18,
    justifyContent: 'center',
    backgroundColor: 'rgba(255,255,255,0.1)',
  },
  secondaryText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '900',
  },
  saveButton: {
    flex: 1,
    height: 44,
    borderRadius: 22,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 7,
    backgroundColor: '#fff',
  },
  disabledButton: {
    opacity: 0.42,
  },
  saveText: {
    color: '#09090b',
    fontSize: 14,
    fontWeight: '900',
  },
  settingRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 18,
    borderRadius: 8,
    padding: 14,
    backgroundColor: 'rgba(255,255,255,0.07)',
  },
  settingTextBlock: {
    flex: 1,
    gap: 3,
  },
  settingTitle: {
    color: '#fff',
    fontSize: 15,
    fontWeight: '900',
  },
  settingHint: {
    color: 'rgba(255,255,255,0.52)',
    fontSize: 12,
    fontWeight: '700',
  },
  menuList: {
    borderRadius: 8,
    overflow: 'hidden',
    backgroundColor: 'rgba(255,255,255,0.07)',
  },
  menuItem: {
    minHeight: 56,
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
    paddingHorizontal: 14,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: 'rgba(255,255,255,0.08)',
  },
  menuIcon: {
    width: 34,
    height: 34,
    borderRadius: 17,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(255,255,255,0.1)',
  },
  menuLabel: {
    flex: 1,
    color: '#fff',
    fontSize: 14,
    fontWeight: '800',
  },
  pressed: {
    opacity: 0.76,
  },
});
