import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import random
import io

# 1. Copy of your exported bibliometric data
data = """document id	keyword id	frequency
1	975	1
3	72	1
3	1135	1
4	1115	1
5	1216	1
6	1135	1
7	1128	1
8	193	1
9	1128	1
11	1135	1
12	193	1
14	200	1
14	1128	1
15	72	1
16	72	1
18	200	1
19	1131	1
20	975	1
21	1131	1
21	1216	1
23	1115	1
26	1135	1
28	193	1
28	232	1
28	1252	1
29	1128	1
29	1228	1
31	72	1
32	193	1
33	1115	1
34	1115	1
34	1136	1
34	1216	1
35	1108	1
35	1135	1
36	1128	1
36	1135	1
37	72	1
37	1115	1
37	1131	1
39	250	1
39	939	1
41	72	1
42	232	1
42	1135	1
43	531	1
43	1115	1
43	1216	1
44	200	1
45	200	1
46	200	1
48	94	1
48	1128	1
49	638	1
49	1115	1
51	391	1
54	1136	1
56	200	1
56	1115	1
61	197	1
61	200	1
61	526	1
61	1135	1
62	72	1
63	534	1
63	1135	1
65	638	1
65	1128	1
66	232	1
69	72	1
70	1115	1
71	72	1
71	391	1
71	1115	1
72	72	1
73	374	1
73	1228	1
74	72	1
74	197	1
74	946	1
74	1115	1
74	1228	1
75	94	1
75	946	1
76	1128	1
77	1135	1
77	1136	1
78	232	1
82	250	1
82	534	1
82	638	1
84	1128	1
86	72	1
86	197	1
86	1115	1
90	72	1
91	939	1
92	526	1
92	1131	1
92	1135	1
93	193	1
94	1131	1
95	1115	1
96	250	1
96	531	1
96	1228	1
97	193	1
97	840	1
98	72	1
98	1135	1
100	197	1
101	72	1
103	232	1
104	458	1
104	1115	1
104	1135	1
105	193	1
105	1216	1
106	200	1
106	526	1
110	1108	1
111	1135	1
113	171	1
115	840	1
115	1115	1
116	1135	1
117	193	1
117	638	1
119	94	1
120	374	1
121	171	1
123	232	1
124	1216	1
125	1115	1
126	975	1
126	1115	1
129	1128	1
134	1115	1
134	1216	1
136	1115	1
137	939	1
139	1115	1
139	1216	1
142	939	1
142	975	1
142	1131	1
143	458	1
143	1066	1
143	1135	1
144	391	1
145	72	1
145	250	1
145	526	1
145	939	1
146	232	1
146	1108	1
146	1115	1
147	72	1
147	526	1
148	171	1
148	1115	1
149	171	1
149	1115	1
152	1115	1
152	1135	1
153	232	1
153	939	1
153	1115	1
154	232	1
155	72	1
155	1135	1
156	395	1
157	72	1
157	193	1
157	395	1
157	638	1
158	946	1
158	1115	1
161	1115	1
162	232	1
162	1128	1
163	193	1
163	374	1
165	1128	1
165	1135	1
167	1135	1
168	232	1
168	1252	1
169	1128	1
170	72	1
170	1115	1
173	232	1
174	1135	1
175	171	1
176	193	1
176	1128	1
177	200	1
178	193	1
178	638	1
178	1115	1
178	1136	1
179	72	1
179	200	1
179	232	1
179	1252	1
180	1228	1
182	1108	1
182	1115	1
183	72	1
183	200	1
183	1115	1
183	1131	1
184	1128	1
186	374	1
187	928	1
188	72	1
188	197	1
189	526	1
189	975	1
190	395	1
191	928	1
192	72	1
192	193	1
193	250	1
194	1131	1
197	232	1
198	526	1
198	1115	1
199	232	1
199	1108	1
200	638	1
202	1066	1
203	458	1
203	1135	1
204	200	1
204	1128	1
205	1131	1
206	374	1
207	975	1
208	374	1
209	72	1
211	840	1
212	395	1
212	1115	1
214	72	1
214	1131	1
215	200	1
217	72	1
217	200	1
217	534	1
219	1115	1
220	94	1
221	200	1
222	1216	1
223	72	1
224	232	1
226	232	1
226	1115	1
227	72	1
227	250	1
227	1115	1
228	200	1
228	975	1
229	200	1
229	1115	1
230	458	1
230	1252	1
231	1135	1
232	232	1
232	1115	1
233	1216	1
234	975	1
236	232	1
237	939	1
237	1135	1
238	94	1
238	1115	1
239	975	1
239	1115	1
241	391	1
241	458	1
245	72	1
245	531	1
246	1115	1
246	1252	1
247	1128	1
249	531	1
249	638	1
250	250	1
250	1216	1
251	928	1
251	1131	1
253	939	1
256	458	1
257	1115	1
258	232	1
259	232	1
259	1128	1
261	193	1
261	232	1
261	250	1
261	1108	1
263	72	1
263	1115	1
264	200	1
264	1115	1
265	638	1
266	939	1
266	975	1
266	1128	1
267	928	1
267	1131	1
268	534	1
268	1115	1
275	391	1
275	1135	1
276	1128	1
278	1066	1
279	232	1
280	72	1
280	193	1
281	193	1
281	1135	1
282	200	1
282	638	1
282	928	1
282	1066	1
282	1115	1
283	250	1
283	531	1
284	534	1
284	1216	1
285	395	1
285	526	1
287	72	1
287	1115	1
288	193	1
288	1115	1
289	1216	1
290	193	1
290	197	1
292	72	1
292	200	1
294	193	1
294	840	1
294	946	1
294	1115	1
295	526	1
298	193	1
301	193	1
301	374	1
302	200	1
302	1216	1
305	232	1
305	395	1
305	1115	1
306	1128	1
308	1115	1
310	638	1
311	72	1
311	946	1
311	1115	1
312	232	1
313	193	1
313	232	1
314	840	1
315	1136	1
319	1115	1
323	193	1
323	1066	1
324	197	1
324	374	1
325	391	1"""

df = pd.read_csv(io.StringIO(data), sep="\t")

# 2. Group keywords by document to map co-occurrences
doc_to_kw = df.groupby('document id')['keyword id'].apply(list).to_dict()

# 3. Building the Co-occurrence Graph
G = nx.Graph()
for doc_id, kws in doc_to_kw.items():
    for i in range(len(kws)):
        G.add_node(kws[i])
        for j in range(i + 1, len(kws)):
            if G.has_edge(kws[i], kws[j]):
                G[kws[i]][kws[j]]['weight'] += 1
            else:
                G.add_edge(kws[i], kws[j], weight=1)

# 4. Stability Simulation Function
def simular_robustez(grafo, estrategia="aleatoria"):
    G_temp = grafo.copy()
    num_inicial = G_temp.number_of_nodes()
    
    eje_x = [0.0]
    eje_y = [1.0]
    
    while G_temp.number_of_nodes() > 1:
        if estrategia == "ataque":
            # Remove the word with the highest current degree (Concept Hub)
            nodo_a_eliminar = max(G_temp.degree, key=lambda x: x[1])[0]
        else:
            # Remove a random keyword (normal obsolescence)
            nodo_a_eliminar = random.choice(list(G_temp.nodes()))
            
        G_temp.remove_node(nodo_a_eliminar)
        
        porcentaje_eliminado = ((num_inicial - G_temp.number_of_nodes()) / num_inicial) * 100
        componentes = sorted(nx.connected_components(G_temp), key=len, reverse=True)
        tamano_lcc = len(componentes[0]) / num_inicial if componentes else 0
        
        eje_x.append(porcentaje_eliminado)
        eje_y.append(tamano_lcc)
        
    return eje_x, eje_y

# 5. Run scenarios
x_rand, y_rand = simular_robustez(G, estrategia="aleatoria")
x_ataq, y_ataq = simular_robustez(G, estrategia="ataque")

# 6. Plot the conceptual resilience curve
plt.figure(figsize=(8, 5))
plt.plot(x_rand, y_rand, label="Random Obsolescence (Random Disuse)", color="#1f77b4", linewidth=2.5)
plt.plot(x_ataq, y_ataq, label="Targeted Attack (Fall of Paradigms)", color="#d62728", linewidth=2.5)
plt.xlabel("% of Keywords Removed from the Network", fontsize=11)
plt.ylabel("Integrity of the Largest Connected Component (LCC %)", fontsize=11)
# 7. Customize the title: "Keywords Plus©" OR "Author Keywords"
plt.title("Analysis of the Epistemological Resilience of Author Keywords", fontsize=12, fontweight='bold')
plt.legend()
plt.grid(True, linestyle=":", alpha=0.6)
plt.tight_layout()
plt.show()