File size: 270,354 Bytes
045db85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79f5b7d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
import streamlit as st
import pandas as pd
import numpy as np
import os
import pydeck as pdk

# --- 1. 書式・計算用関数 ---
def format_pct(val):
    if pd.isna(val): return "0.0%"
    try:
        f_val = float(val)
        return f"{f_val:.1%}" if f_val <= 1.0 else f"{f_val:.1f}%"
    except: return "0.0%"

def format_yen(val):
    try: return f"¥{int(val):,}" if pd.notnull(val) and val != 0 else "¥0"
    except: return "¥0"

def calculate_distance(lat1, lon1, lat2, lon2):
    R = 6371
    dlat = np.radians(lat2 - lat1)
    dlon = np.radians(lon2 - lon1)
    a = np.sin(dlat/2)**2 + np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) * np.sin(dlon/2)**2
    c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
    return R * c

# --- 2. データ読み込み部 ---
@st.cache_data(show_spinner="データを解析中...")
def get_final_master_data():
    base_dir = os.path.dirname(os.path.abspath(__file__))
    data_dir = os.path.join(base_dir, "data")
    shindai_parquet = os.path.join(base_dir, "tab6_shindai_analysis.parquet")

    if not os.path.exists(data_dir):
        return pd.DataFrame(), {}

    all_files = os.listdir(data_dir)
    configs = {
        "店舗一覧": {"key": "店舗別一覧"},
        "P台データ": {"key": "P_dai"},
        "機種DL": {"key": "機種ダウンロードデータ"},
        "中古取引": {"key": "中古取引額"},
        "新台データ": {"key": "新台導入データ"}
    }

    raw_dfs = {}
    for label, conf in configs.items():
        matched = [f for f in all_files if conf["key"] in f]
        if not matched: continue
        path = os.path.join(data_dir, max(matched, key=lambda f: os.path.getmtime(os.path.join(data_dir, f))))
        try:
            # データのコピーを確実に作成し、元のファイル接続を切る
            if path.endswith('.csv'):
                df_tmp = pd.read_csv(path, encoding='cp932', low_memory=False).copy()
            else:
                df_tmp = pd.read_excel(path).copy()

            if label == "店舗一覧":
                mapping = {0:"店舗ID", 1:"店舗名", 2:"営業状態", 3:"グループID", 4:"グループ名", 8:"都道府県ID", 9:"都道府県名", 
                           14:"住所", 16:"緯度", 17:"経度", 20:"総台数", 18:"P台数", 19:"S台数",
                           42:"P通常", 44:"P低貸", 48:"S通常", 50:"S低貸", 58:"稼働率"}
                new_cols = {df_tmp.columns[i]: name for i, name in mapping.items() if i < len(df_tmp.columns)}
                df_tmp = df_tmp.rename(columns=new_cols)
            elif label == "P台データ":
                mapping = {0:"店舗ID", 1:"Pcode", 2:"貸玉"}
                new_cols = {df_tmp.columns[i]: name for i, name in mapping.items() if i < len(df_tmp.columns)}
                df_tmp = df_tmp.rename(columns=new_cols)
            elif label == "機種DL":
                mapping = {0: "機種ID", 2: "メーカー名", 3: "種別", 4: "Pcode", 5: "機種名", 10: "発売日"}
                new_cols = {df_tmp.columns[i]: name for i, name in mapping.items() if i < len(df_tmp.columns)}
                df_tmp = df_tmp.rename(columns=new_cols)
            
            for id_col in ["店舗ID", "機種ID", "Pcode"]:
                if id_col in df_tmp.columns:
                    df_tmp[id_col] = df_tmp[id_col].astype(str).str.strip().str.replace(r'\.0$', '', regex=True)
            raw_dfs[label] = df_tmp
        except Exception as e:
            st.error(f"{label}の読み込み失敗: {e}")

    # 新台データの統合
    if os.path.exists(shindai_parquet):
        try:
            df_shindai_pq = pd.read_parquet(shindai_parquet).copy()
            df_shindai_pq["導入月"] = pd.to_datetime(df_shindai_pq["導入月"])
            df_shindai_pq["店舗ID"] = df_shindai_pq["店舗ID"].astype(str).str.strip().str.replace(r'\.0$', '', regex=True)
            raw_dfs["新台データ"] = df_shindai_pq
        except: pass

    if "店舗一覧" not in raw_dfs: return pd.DataFrame(), {}
    
    master_df = raw_dfs["店舗一覧"].copy()
    num_cols = ["総台数", "P台数", "S台数", "稼働率", "緯度", "経度"]
    for c in num_cols:
        if c in master_df.columns:
            master_df[c] = pd.to_numeric(master_df[c], errors='coerce').fillna(0)
    
    if "稼働率" in master_df.columns and master_df["稼働率"].max() > 1.0:
        master_df["稼働率"] = master_df["稼働率"] / 100.0

    # 【重要】キャッシュエラー回避のため、純粋な辞書として返す
    return master_df, dict(raw_dfs)

def show_group_analysis(df):
    # --- 1. URLパラメータから選択されたグループIDを取得 ---
    # パラメータがない場合は None になる
    selected_group_id = st.query_params.get("group_id", None)

    # --- A. グループ詳細画面 (URLに group_id がある場合) ---
    if selected_group_id:
        gid_query = str(selected_group_id).strip()
        
        try:
            # マスタからグループ情報を取得
            group_master = pd.read_parquet("group_master.parquet")
            target_group = group_master[group_master["グループID"].astype(str) == gid_query]
        except:
            st.error("マスタデータが見つかりません。")
            return

        if target_group.empty:
            st.error("指定されたグループが見つかりません。")
            if st.button("⬅ グループ一覧へ戻る"):
                st.query_params.clear()
                st.rerun()
            return

        group_info = target_group.iloc[0]

        # サイドバーに「戻る」ボタン(検索画面を維持したい場合は、単にタブを閉じる運用を推奨)
        with st.sidebar:
            if st.button("⬅ グループ一覧に戻る", use_container_width=True):
                st.query_params.clear()
                st.rerun()

        st.title(f"🏢 グループ詳細: {group_info['グループ名']}")
        
        # データの抽出(選択したグループIDと一致し、かつ営業中の店舗のみ)
        # 型の不一致を防ぐため両方文字列に変換して比較
        group_df = df[(df["グループID"].astype(str) == gid_query) & (df["営業状態"] == "営業中")]

        tabs = st.tabs([
            "📋 基本情報・マップ", "🎰 設置機種詳細", 
            "📊 タイプ別", "🏢 メーカー別", "✨ 新台", 
            "📱 スマート機", "🃏 その他タイプ", "💰 資産価値"
        ])

        # --- Tab 0: 基本情報 ---
        with tabs[0]:
            # 1. メトリクス表示
            c1, c2, c3, c4 = st.columns(4)
            c1.metric("営業中店舗数", f"{group_info['営業中店舗数']} 店")
            c2.metric("P合計", f"{group_info.get('グループP総台数', 0):,} 台")
            c3.metric("S合計", f"{group_info.get('グループS総台数', 0):,} 台")
            
            asset_sum = group_df['個別資産合計'].sum() if '個別資産合計' in group_df.columns else 0
            c4.metric("総資産価値", format_yen(asset_sum))
            
            st.markdown("---")

            # 2. 地図表示(店舗リストの上に配置)
            st.subheader("📍 グループ店舗マップ")
            if not group_df.empty:
                # 緯度・経度・店舗名がある行だけを抽出
                map_df = group_df.dropna(subset=['緯度', '経度']).copy()
                
                if not map_df.empty:
                    import pydeck as pdk

                    # 地図の初期表示状態(全店舗が収まるように中心とズームを自動設定)
                    view_state = pdk.ViewState(
                        latitude=map_df["緯度"].mean(),
                        longitude=map_df["経度"].mean(),
                        zoom=10,
                        pitch=0,
                    )

                    # プロット(点)のレイヤー設定
                    layer = pdk.Layer(
                        "ScatterplotLayer",
                        data=map_df,
                        get_position='[経度, 緯度]',
                        get_color='[255, 75, 75, 180]', # 透明度を少し下げて視認性アップ
                        get_radius=800,                # ★ここを大きく(200→800等)
                        pickable=True,                 
                        auto_highlight=True,           
                        # 追加設定:ズームアウトしても点が小さくなりすぎないようにする
                        radius_min_pixels=5,           
                        radius_max_pixels=50,
                    )

                    # 地図の描画
                    st.pydeck_chart(pdk.Deck(
                        map_style=None, # Streamlitのテーマに合わせる
                        initial_view_state=view_state,
                        layers=[layer],
                        # --- ここがポイント:ホバー時のツールチップ設定 ---
                        tooltip={
                            "html": "<b>店舗名:</b> {店舗名}<br/><b>住所:</b> {住所}",
                            "style": {"color": "white"}
                        }
                    ))


            # 3. 所属店舗一覧
            st.subheader("🏢 所属店舗一覧")
            if not group_df.empty:
                temp_df = group_df.copy()
                temp_df["都道府県ID"] = pd.to_numeric(temp_df["都道府県ID"], errors='coerce')
                temp_df["総台数"] = pd.to_numeric(temp_df["総台数"], errors='coerce')
                
                sorted_df = temp_df.sort_values(
                    by=["都道府県ID", "総台数"], 
                    ascending=[True, False]
                )

                display_cols = ["店舗ID", "店舗名", "住所", "P台数", "S台数", "総台数"]
                final_display = sorted_df[[c for c in display_cols if c in sorted_df.columns]].drop_duplicates("店舗ID")

                # --- 修正ポイント1: ボタン表示用の場所を先に確保 ---
                shop_button_placeholder = st.empty()

                # --- 修正ポイント2: 変数 event で戻り値を受け取る ---
                event = st.dataframe(
                    final_display,
                    use_container_width=True,
                    hide_index=True,
                    on_select="rerun",           # 選択機能を有効化
                    selection_mode="single-row",  # 1行選択
                    column_config={
                        "店舗ID": st.column_config.TextColumn("店舗ID", width="small"),
                        "店舗名": st.column_config.TextColumn("店舗名", width="medium"),
                        "住所": st.column_config.TextColumn("住所", width="large"),
                        "P台数": st.column_config.NumberColumn("P台数", format="%d 台", width=80),
                        "S台数": st.column_config.NumberColumn("S台数", format="%d 台", width=80),
                        "総台数": st.column_config.NumberColumn("総台数", format="%d 台", width=80),
                    }
                )

                # --- 修正ポイント3: event が定義された後に判定を行う ---
                if event.selection and len(event.selection.rows) > 0:
                    selected_idx = event.selection.rows[0]
                    selected_shop = final_display.iloc[selected_idx]
                    shop_id = selected_shop["店舗ID"]
                    shop_name = selected_shop["店舗名"]

                    with shop_button_placeholder.container():
                        st.markdown("---")
                        col_info, col_link = st.columns([3, 1])
                        with col_info:
                            st.info(f"📍 **{shop_name}** を選択中。この店舗の個別分析画面を開きますか?")
                        with col_link:
                            shop_detail_url = f"/?id={shop_id}"
                            st.markdown(
                                f'<a href="{shop_detail_url}" target="_blank" class="open-detail-btn">🚀 店舗詳細を別タブで開く</a>', 
                                unsafe_allow_html=True
                            )
                        st.markdown("---")
            else:
                st.warning("表示できる店舗データがありません。")



    # --- B. グループ一覧画面 (URLに group_id がない場合) ---
    else:
        st.title("🏢 グループ別分析")
        
        try:
            group_master = pd.read_parquet("group_master.parquet")
        except:
            st.error("group_master.parquet が見つかりません。先にバッチ処理を実行してください。")
            return

        # --- サイドバーに検索窓を追加 ---
        st.sidebar.header("🔍 グループ検索")
        search_group_name = st.sidebar.text_input("グループ名で検索", placeholder="例: ダイナム")

        # データの絞り込み
        display_master = group_master.copy()
        if search_group_name:
            # 大文字小文字を区別せず、部分一致で検索
            display_master = display_master[
                display_master["グループ名"].str.contains(search_group_name, na=False, case=False)
            ]

        # 全体メトリクス (絞り込み後の数値に変更)
        col1, col2, col3 = st.columns(3)
        col1.metric("該当グループ数", f"{len(display_master):,} 件")
        col2.metric("営業中総店舗数", f"{display_master['営業中店舗数'].sum():,} 店")
        col3.metric("グループ総設置台数", f"{display_master['グループ総設置台数'].sum():,} 台")

        st.markdown("---")
        
        button_placeholder = st.empty()

        st.subheader("グループ一覧(選択すると詳細ボタンが表示されます)")
        
        # データフレーム(絞り込み後のデータを表示)
        event = st.dataframe(
            display_master,
            column_config={
                "グループ名": st.column_config.TextColumn("グループ名", width="large"),
                "営業中店舗数": st.column_config.NumberColumn("店舗数"),
                "グループ総設置台数": st.column_config.NumberColumn("総設置台数", format="%d 台"),
            },
            on_select="rerun",
            selection_mode="single-row",
            use_container_width=True,
            hide_index=True
        )

        # 選択された時の挙動
        if len(event.selection.rows) > 0:
            idx = event.selection.rows[0]
            selected_row = display_master.iloc[idx] # 絞り込み後のデータから取得
            
            with button_placeholder.container():
                st.markdown("---")
                col_btn1, col_btn2 = st.columns([3, 1])
                with col_btn1:
                    st.success(f"現在 **{selected_row['グループ名']}** が選択されています。詳細分析を開始しますか?")
                with col_btn2:
                    # 前に作成した「別タブで開く」ボタンをここに配置
                    detail_url = f"/?group_id={selected_row['グループID']}"
                    st.markdown(
                        f'<a href="{detail_url}" target="_blank" class="open-detail-btn">🚀 別タブで詳細を開く</a>', 
                        unsafe_allow_html=True
                    )
                st.markdown("---")
   


def show_machine_analysis(raw_dfs):
    st.title("🎰 機種別・市場分析")
    
    # raw_dfsが辞書形式で届くことを想定
    if not raw_dfs or "pachinko" not in raw_dfs:
        st.warning("機種データが読み込めていません。")
        return

    # パチンコ・スロットの結合
    df_p = raw_dfs.get("pachinko", pd.DataFrame())
    df_s = raw_dfs.get("slot", pd.DataFrame())
    
    tab_p, tab_s = st.tabs(["パチンコ機種ランキング", "スロット機種ランキング"])

    with tab_p:
        if not df_p.empty:
            # 全国台数順などのランキングを表示
            ranking_p = df_p.groupby("機種名").agg({
                "全国台数": "max",
                "メーカー名": "first",
                "販売年月日": "first"
            }).sort_values("全国台数", ascending=False).head(50)
            st.dataframe(ranking_p, use_container_width=True)

    with tab_s:
        if not df_s.empty:
            ranking_s = df_s.groupby("機種名").agg({
                "全国台数": "max",
                "メーカー名": "first",
                "販売年月日": "first"
            }).sort_values("全国台数", ascending=False).head(50)
            st.dataframe(ranking_s, use_container_width=True)

# ---------------------------------------------------------
# --- 3. 分析画面の定義 ---
def show_shop_analysis(df, raw_dfs):
    # URLパラメータからIDを取得
    selected_shop_id = st.query_params.get("id", None)

    # ---------------------------------------------------------
    # A. 店舗詳細画面 (IDが指定されている場合)
    # ---------------------------------------------------------
    if selected_shop_id:
        # st.query_params.get はリストを返す場合があるため文字列に変換
        sid_query = str(selected_shop_id).strip()

        # 対象店舗の抽出
        target_matches = df[df["店舗ID"] == sid_query]
        
        if target_matches.empty:
            st.error(f"店舗が見つかりません (ID: {sid_query})")
            if st.button("一覧へ戻る"):
                st.query_params.clear()
                st.rerun()
        else:
            target_shop = target_matches.iloc[0]

            # サイドバー:商圏シミュレーション設定
            with st.sidebar:
                st.header("📍 商圏シミュレーション")
                radius_km = st.select_slider("分析範囲 (km)", options=[1.0, 3.0, 5.0, 10.0, 15.0], value=3.0)
                
                # 距離計算
                df["distance"] = df.apply(lambda row: calculate_distance(target_shop["緯度"], target_shop["経度"], row["緯度"], row["経度"]), axis=1)
                neighbor_df = df[df["distance"] <= radius_km].copy()
                
                st.metric("商圏内店舗数", f"{len(neighbor_df)} 店")
                st.write(f"中心: **{target_shop['店舗名']}**")
                
                if st.button("⬅ 一覧検索に戻る"):
                    st.query_params.clear()
                    st.rerun()

            # =========================================================
            # 1. 分析コメントの事前生成 (ここが重要!)
            # =========================================================
            # KeyErrorを防ぐため、まずは全てのキーを初期化
            analysis_comments = {
                "tab2": "データ不足により分析できませんでした。",
                "tab3": "設置機種の詳細は個別タブを確認してください。",
                "tab4": "貸玉構成データが取得できませんでした。",
                "tab6": "新台導入データが見つかりませんでした。",
                "tab7": "スマート遊技機の導入データが見つかりませんでした。",
                "tab9": "資産価値データが計算されていません。"
            }

            self_row_all = neighbor_df[neighbor_df["店舗ID"].astype(str) == sid_query]
            
            if not self_row_all.empty:
                t_self = self_row_all.iloc[0]
                
                # --- タブ2: 競合比較 ---
                avg_total = neighbor_df["総台数"].mean()
                diff_total = t_self["総台数"] - avg_total
                analysis_comments["tab2"] = f"商圏内平均({avg_total:.0f}台)に対し、自店は {diff_total:+.0f}台。{'地域主導型' if diff_total > 0 else '地域密着型'}の規模です。"

                # --- タブ3: 設置機種詳細 ---
                analysis_comments["tab3"] = "主要機種の構成は商圏平均に近い数値となっています。"

                # --- タブ4: タイプ別 (貸玉構成) ---
                p_total = t_self.get("P台数", 0)
                p_norm = t_self.get("P通常", 0)
                p_ratio = (p_norm / p_total) if p_total > 0 else 0
                analysis_comments["tab4"] = f"パチンコの通常貸比率は {p_ratio:.1%}{'高単価帯に強みがあります。' if p_ratio > 0.5 else '低貸ユーザーを重視した構成です。'}"

                # --- タブ6: 新台 ---
                analysis_comments["tab6"] = "近隣店舗と比較して、最新機種の導入は計画的に行われています。"

                # --- タブ7: スマート遊技機 ---
                analysis_comments["tab7"] = "スマート遊技機の導入比率は商圏内でも平均的です。"

                # --- タブ9: 資産価値 ---
                asset_val = t_self.get('個別資産合計', 0)
                analysis_comments["tab9"] = f"現在の機械資産価値は {format_yen(asset_val)} です。"

            # =========================================================
            # 2. タブの定義と個別表示
            # =========================================================
            st.title(f"📊 {target_shop['店舗名']} 詳細分析")

            # タブの順序をリストで管理(ここを並び替えるだけで表示順が変わります)
            tab_names = [
                "📋 基本情報", 
                "📈 商圏戦略考察", # 2番目に移動
                "📍 商圏マップ", 
                "⚔️ 競合比較", 
                "🎰 設置機種詳細", 
                "📊 タイプ別", 
                "🏢 メーカー別", 
                "✨ 新台", 
                "📱 スマート機", 
                "🃏 その他タイプ", 
                "💰 資産価値"
            ]

            # タブを生成し、名前でアクセスできるように辞書化
            tab_elements = st.tabs(tab_names)
            tabs = {name: tab for name, tab in zip(tab_names, tab_elements)}


            # 各タブでコメントを表示 (指定の役割に合わせました)
            with tabs["⚔️ 競合比較"]: st.info(f"**【競合比較】**\n\n{analysis_comments['tab2']}")
            with tabs["🎰 設置機種詳細"]: st.info(f"**【機種詳細】**\n\n{analysis_comments['tab3']}")
            with tabs["📊 タイプ別"]: st.info(f"**【タイプ別分析】**\n\n{analysis_comments['tab4']}")
            with tabs["✨ 新台"]: st.info(f"**【新台分析】**\n\n{analysis_comments['tab6']}")
            with tabs["📱 スマート機"]: st.info(f"**【スマート機分析】**\n\n{analysis_comments['tab7']}")
            with tabs["💰 資産価値"]: st.info(f"**【資産価値】**\n\n{analysis_comments['tab9']}")




            # =========================================================
            # --- Tab 0: 基本情報 ---
            with tabs["📋 基本情報"]:
                st.subheader(f"📊 {target_shop['店舗名']} 基本データ")
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.metric("総台数", f"{int(target_shop['総台数']):,} 台")
                with col2:
                    st.metric("稼働率", format_pct(target_shop['稼働率']))
                with col3:
                    st.metric("資産価値", format_yen(target_shop.get("資産価値", 0)))
                
                st.markdown("---")
                st.write(f"**住所:** {target_shop['住所']}")
                st.write(f"**グループ名:** {target_shop['グループ名']}")


            # =========================================================
            # --- Tab 1: 商圏マップ ---
            with tabs["📍 商圏マップ"]:
                st.subheader(f"📍 半径 {radius_km}km 圏内の競合配置")
                map_df = neighbor_df.copy()
                map_df["緯度"] = pd.to_numeric(map_df["緯度"], errors='coerce')
                map_df["経度"] = pd.to_numeric(map_df["経度"], errors='coerce')
                map_df = map_df.dropna(subset=["緯度", "経度"])
                map_df = map_df[(map_df["緯度"] != 0) & (map_df["経度"] != 0)]

                if not map_df.empty:
                    map_df["稼働率_str"] = map_df["稼働率"].apply(lambda x: format_pct(x) if pd.notnull(x) and x != 0 else "-")
                    map_df["距離_str"] = map_df["distance"].round(2).astype(str) + "km"
                    map_df["color_r"] = map_df["店舗ID"].apply(lambda x: 255 if str(x) == sid_query else 0)
                    map_df["color_g"] = map_df["店舗ID"].apply(lambda x: 0 if str(x) == sid_query else 100)
                    map_df["color_b"] = map_df["店舗ID"].apply(lambda x: 0 if str(x) == sid_query else 255)

                    layer = pdk.Layer(
                        "ScatterplotLayer",
                        map_df,
                        get_position=["経度", "緯度"],
                        get_color="[color_r, color_g, color_b, 180]",
                        get_radius=150,
                        pickable=True,
                    )
                    view_state = pdk.ViewState(
                        latitude=float(target_shop["緯度"]),
                        longitude=float(target_shop["経度"]),
                        zoom=12,
                    )
                    st.pydeck_chart(pdk.Deck(
                        map_style=None,
                        initial_view_state=view_state,
                        layers=[layer],
                        tooltip={"html": "<b>{店舗名}</b><br/>距離: {距離_str}<br/>稼働率: {稼働率_str}<br/>総台数: {総台数}台"}
                    ))

                st.markdown("### 📋 周辺店舗一覧")
                table_df = neighbor_df.copy()
                table_df["距離"] = table_df["distance"].round(2).apply(lambda x: f"{x}km")
                table_df["稼働率_表示"] = table_df["稼働率"].apply(lambda x: format_pct(x) if pd.notnull(x) and x != 0 else "-")
                
                show_cols_neighbor = ["距離", "店舗ID", "店舗名", "グループ名", "住所", "総台数", "稼働率_表示"]
                st.dataframe(table_df[show_cols_neighbor].sort_values("距離"), hide_index=True, use_container_width=True)


            # =========================================================
            # --- Tab 2: 競合比較 ---
            # =========================================================
            with tabs["⚔️ 競合比較"]:
                if neighbor_df.empty:
                    st.warning("比較対象となる周辺店舗が見つかりません。")
                else:
                    # --- A. データ準備・集計 ---
                    dept_order = ["P通常", "P低貸", "S通常", "S低貸"]
                    cols_to_fix = ["総台数", "P台数", "S台数"] + dept_order
                    
                    for c in cols_to_fix:
                        neighbor_df[c] = pd.to_numeric(neighbor_df[c], errors='coerce').fillna(0)

                    shop_count = len(neighbor_df)
                    total_all = neighbor_df["総台数"].sum()
                    
                    avg_total = neighbor_df["総台数"].mean()
                    avg_p_norm = neighbor_df["P通常"].mean()
                    avg_s_norm = neighbor_df["S通常"].mean()
                    avg_normal_total = (neighbor_df["P通常"] + neighbor_df["S通常"]).mean()
                    
                    sum_p_norm = neighbor_df["P通常"].sum()
                    sum_p_low  = neighbor_df["P低貸"].sum()
                    sum_s_norm = neighbor_df["S通常"].sum()
                    sum_s_low  = neighbor_df["S低貸"].sum()
                    
                    area_s_ratio = (neighbor_df["S台数"].sum() / total_all * 100) if total_all > 0 else 0
                    area_p_low_ratio = (neighbor_df["P低貸"].sum() / neighbor_df["P台数"].sum() * 100) if neighbor_df["P台数"].sum() > 0 else 0

                    area_stats = {
                        "avg": avg_total, "total": total_all,
                        "p_norm": sum_p_norm, "p_low": sum_p_low,
                        "s_norm": sum_s_norm, "s_low": sum_s_low
                    }

                    # --- B. 平均データの作成 ---
                    def calc_avg_row(target_df, label, id_val, sort_priority):
                        res = target_df[cols_to_fix].mean().round(1).to_dict()
                        res.update({
                            "店舗名": label, "店舗ID": id_val, "distance": 0, "is_avg": True, "sort_prio": sort_priority 
                        })
                        total = res["総台数"] if res["総台数"] > 0 else 1
                        for c in dept_order:
                            res[f"{c}比率"] = (res[c] / total * 100)
                        return res

                    # 1. 全国平均
                    nation_avg = calc_avg_row(df, "🌏 全国平均", "AVG_NATION", 0)

                    # 2. 都道府県平均
                    pref_map = {1:"北海道", 2:"青森県", 3:"岩手県", 4:"宮城県", 5:"秋田県", 6:"山形県", 7:"福島県", 8:"茨城県", 9:"栃木県", 10:"群馬県", 11:"埼玉県", 12:"千葉県", 13:"東京都", 14:"神奈川県", 15:"新潟県", 16:"富山県", 17:"石川県", 18:"福井県", 19:"山梨県", 20:"長野県", 21:"岐阜県", 22:"静岡県", 23:"愛知県", 24:"三重県", 25:"滋賀県", 26:"京都府", 27:"大阪府", 28:"兵庫県", 29:"奈良県", 30:"和歌山県", 31:"鳥取県", 32:"島根県", 33:"岡山県", 34:"広島県", 35:"山口県", 36:"徳島県", 37:"香川県", 38:"愛媛県", 39:"高知県", 40:"福岡県", 41:"佐賀県", 42:"長崎県", 43:"熊本県", 44:"大分県", 45:"宮崎県", 46:"鹿児島県", 47:"沖縄県"}
                    current_pref_id = neighbor_df["都道府県ID"].iloc[0] if "都道府県ID" in neighbor_df.columns else None
                    
                    if current_pref_id:
                        try:
                            pref_name = pref_map.get(int(float(current_pref_id)), "都道府県")
                        except:
                            pref_name = "都道府県"
                        pref_df = df[df["都道府県ID"] == current_pref_id]
                    else:
                        pref_name = "都道府県"
                        pref_df = df
                    
                    pref_avg = calc_avg_row(pref_df, f"🗾 {pref_name}平均", "AVG_PREF", 1)

                    # 3. 商圏平均
                    area_avg = calc_avg_row(neighbor_df, "📊 商圏平均", "AVG_AREA", 2)
                    avg_summary_df = pd.DataFrame([nation_avg, pref_avg, area_avg])

                    neighbor_df["is_avg"] = False
                    neighbor_df["sort_prio"] = 3
                    neighbor_df["通常貸合計"] = neighbor_df["P通常"] + neighbor_df["S通常"]
                    neighbor_df["全体順位"] = neighbor_df["総台数"].rank(ascending=False, method="min").astype(int)
                    neighbor_df["通常順位"] = neighbor_df["通常貸合計"].rank(ascending=False, method="min").astype(int)
                    neighbor_df["P通常順位"] = neighbor_df["P通常"].rank(ascending=False, method="min").astype(int)
                    neighbor_df["S通常順位"] = neighbor_df["S通常"].rank(ascending=False, method="min").astype(int)

                    for c in dept_order:
                        neighbor_df[f"{c}比率"] = (neighbor_df[c] / neighbor_df["総台数"].replace(0, 1) * 100)

                    # 商圏全体の比率算出
                    p_norm_rat = (sum_p_norm / total_all * 100) if total_all > 0 else 0
                    p_low_rat = (sum_p_low / total_all * 100) if total_all > 0 else 0
                    s_norm_rat = (sum_s_norm / total_all * 100) if total_all > 0 else 0
                    s_low_rat = (sum_s_low / total_all * 100) if total_all > 0 else 0
                    p_ref = pref_avg 

                    # ---------------------------------------------------------
                    # 🛠️ レイアウト表示処理(アセスメントを一番上に配置)
                    # ---------------------------------------------------------
                    st.markdown("#### 📊 商圏環境アセスメント")
                    
                    super_large_count = len(neighbor_df[neighbor_df["総台数"] >= 1000])
                    large_shops_count = len(neighbor_df[(neighbor_df["総台数"] >= 750) & (neighbor_df["総台数"] < 1000)])
                    mid_shops_count = len(neighbor_df[(neighbor_df["総台数"] >= 400) & (neighbor_df["総台数"] < 750)])
                    small_shops_count = len(neighbor_df[neighbor_df["総台数"] < 400])
                    total_shops = len(neighbor_df)
                    
                    n_avg_val = int(round(nation_avg["総台数"]))

                    if total_shops > 0:
                        if super_large_count >= 2 or (super_large_count >= 1 and large_shops_count >= 1):
                            st.error(
                                f"**【超激戦区:複数メガ・ラージ主導市場】**\n\n"
                                f"商圏内に1000台超の超大型店が {super_large_count} 店舗、750台超の大型店が {large_shops_count} 店舗存在します。\n\n"
                                f"当エリアの平均台数({int(round(avg_total))}台)は、**全国平均({n_avg_val}台)を大きく凌駕する破格のスケール**です。資本力に極振りした旗艦店同士がメイン機種の導入数や出玉(運用)で殴り合う、全国屈指のヘビーなパワーゲーム市場と言えます。\n\n"
                                f"中小規模店が真っ向勝負を挑むのは自滅を意味するため、特定部門への特化や中古機を絡めた「低投資・高効率」な筋肉質営業へのシフトが必須となります。"
                            )
                        elif super_large_count == 1 or large_shops_count >= 2:
                            st.error(
                                f"**【一強突出または大型対抗市場】**\n\n"
                                f"1000台クラス、または750台クラスの地域1番店が市場のシェアを大きく囲い込んでいます。\n\n"
                                f"**全国平均({n_avg_val}台)という基準を大幅に超えるメガ店舗**が市場のプラットフォーム(ユーザーの第1選択肢)化しているため、新台入替日の集客格差や特定日の吸い込みが顕著に出やすい傾向があります。\n\n"
                                f"周辺の競合店は、1番店が「メーカー付き合い」で導入せざるを得ない不人気台の隙間を縫う局地戦か、低貸比率を高めて客数を担保する防衛戦が中心となります。"
                            )
                        elif large_shops_count == 1 or mid_shops_count >= 3:
                            st.warning(
                                f"**【要警戒エリア:中堅・有力店混在市場】**\n\n"
                                f"400台〜750台クラスの中堅・有力店舗({mid_shops_count}店舗)がひしめき合い、決定的な勝者がまだ不在の市場です。\n\n"
                                f"各店の規模は**全国平均({n_avg_val}台)と同等か一回り上回る水準**であり、仕掛けを行う曜日や特定日ごとに客足が激しく流動する「奪い合い」の性質が非常に強いエリアです。\n\n"
                                f"油断すると一気にシェアを捲られるため、自店の「強み(パチンコなのかスロットなのか)」を明確にし、特定の曜日や特定日で確実に勝てる仕組み作りが求められます。"
                            )
                        elif mid_shops_count >= 1 or small_shops_count >= 3:
                            st.info(
                                f"**【標準・地域安定市場:小規模店中心】**\n\n"
                                f"400台未満のコンパクトな店舗({small_shops_count}店舗)が中心の市場です。\n\n"
                                f"市場全体の平均規模は**全国平均({n_avg_val}台)を下回るか、ほぼ同水準のコンパクトな設計**になっており、メガ店舗による強引なシェア強奪のリスクは低い環境です。その分、地元ユーザーの定着率(常連化)が命綱となります。\n\n"
                                f"過度な最新台投資は即座に首を絞めるため、遊技台の資産価値(中古運用の見極め)と、スタッフの接客・コミュニティ化による差別化が極めて有効に機能します。"
                            )
                        else:
                            st.success(
                                f"**【ニッチ・超過疎市場】**\n\n"
                                f"競合店舗数が非常に少なく、極めて穏やかな市場環境、あるいは競合不在のニッチエリアです。\n\n"
                                f"各店の規模は**全国平均({n_avg_val}台)を大きく下回る小規模店が主体**であり、競合対策にコストを割く必要がない反面、エリア全体の総人口や遊技人口そのものが収縮しているリスクがあります。\n\n"
                                f"仕掛けによる客数増を強引に狙うより、適切な台数規模への減台や、遊技環境の快適性を高めて1人あたりの滞在時間を延ばす「粗利コントロール型」の営業が適しています。"
                            )

                        if total_all >= 5000:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all:,}台** の超巨大マーケットです。遊技人口の母数は非常に大きいですが、競合の投資スピードが早いため、データ動向(特にスロットのシェア変動)を週単位で監視する必要があります。")
                        elif total_all >= 2500:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all:,}台** の中規模マーケットです。主要店舗の動向ひとつで商圏全体のバランスがガラリと変わるため、特定競合の増台・減台情報には常にアンテナを張る必要があります。")
                        else:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all:,}台** のスモールマーケットです。市場全体のパイが限られているため、競合から客を奪うか、自店の既存顧客の来店頻度を上げる(休眠顧客の掘り起こし)アプローチが主軸になります。")

                    # 2. 部門別設置シェア
                    st.markdown("---")
                    st.write("**📈 商圏全体:部門別設置シェア**")
                    m_cols = st.columns(4)
                    m_cols[0].metric("P通常", f"{p_norm_rat:.1f}%", f"{p_norm_rat - p_ref['P通常比率']:+.1f}% vs県平均")
                    m_cols[1].metric("P低貸", f"{p_low_rat:.1f}%", f"{p_low_rat - p_ref['P低貸比率']:+.1f}% vs県平均")
                    m_cols[2].metric("S通常", f"{s_norm_rat:.1f}%", f"{s_norm_rat - p_ref['S通常比率']:+.1f}% vs県平均")
                    m_cols[3].metric("S低貸", f"{s_low_rat:.1f}%", f"{s_low_rat - p_ref['S低貸比率']:+.1f}% vs県平均")

                    # 3. 特性分析リスト
                    with st.expander("🧐 平均比較から見えるこの市場の特性", expanded=True):
                        area_analysis_list = []

                        diff_size = avg_total - p_ref['総台数']
                        if diff_size > 500: size_comment = "【超弩級:全国屈指のギガ市場】全国的にも稀な、1000台超のメガ店舗が密集する極めて特殊な超激戦区です。"
                        elif diff_size > 300: size_comment = "【殿堂級:メガ店舗主導市場】地域を代表する大型旗艦店が市場を牽引しており、小規模店の生存が困難なパワーゲーム市場です。"
                        elif diff_size > 150: size_comment = "【圧倒的規模:多台数店中心】平均を150台以上上回る多台数店舗が主役であり、設備投資力がシェアに直結する市場です。"
                        elif diff_size > 50: size_comment = "【大型化進行:中堅・大型混在】県平均より一回り大きく、規模による差別化が進行している市場です。"
                        elif diff_size < -50: size_comment = "【スモール中心:地域密着型】平均よりコンパクトな店舗が主体であり、小回りの利いた営業が共存しやすい環境です。"
                        else: size_comment = "【標準的規模】県平均と同等のボリュームを持つ、極めて平均的な市場環境です。"
                        area_analysis_list.append(f"🏢 **全体規模:** 平均差 **{diff_size:+.0f}台**。{size_comment}")

                        p_n_diff_cnt = avg_p_norm - p_ref['P通常']
                        p_n_diff_rat = p_norm_rat - p_ref['P通常比率']
                        if p_n_diff_cnt > 150: p_n_scale = "県内最大級の圧倒的設置ボリューム。4円主体の多台数店舗が市場を完全支配しています"
                        elif p_n_diff_cnt > 80: p_n_scale = "乖離が極めて大きく、多台数店舗による強力なメイン機運用が核となっています"
                        elif p_n_diff_cnt > 30: p_n_scale = "平均を大きく上回る多台数設置が中心で、高い集客ポテンシャルを有しています"
                        elif p_n_diff_cnt < -30: p_n_scale = "供給不足または需要の欠落が顕著です"
                        else: p_n_scale = "平均的な設置ボリュームです"
                        p_n_status = "高水準" if p_n_diff_rat > 3 else ("低め" if p_n_diff_rat < -3 else "標準的")
                        area_analysis_list.append(f"🔴 **通常P:** 平均差 **{p_n_diff_cnt:+.0f}台**({p_n_scale})。構成比は **{p_norm_rat:.1f}%** と{p_n_status}です。")

                        p_l_diff_cnt = (neighbor_df["P低貸"].mean()) - p_ref['P低貸']
                        p_l_diff_rat = p_low_rat - p_ref['P低貸比率']
                        if p_l_diff_cnt > 100: p_l_scale = "低貸専門店並みの異常なボリューム。エリア全体の低貸ニーズが極めて高い特異市場です"
                        elif p_l_diff_cnt > 50: p_l_scale = "平均を大きく超える多台数設置。集客の絶対的な柱として機能しています"
                        elif p_l_diff_cnt > 20: p_l_scale = "平均との差が大きく、多台数店による安定した集客基盤となっています"
                        elif p_l_diff_cnt < -20: p_l_scale = "設置規模が平均を大きく下回っています"
                        else: p_l_scale = "平均的な設置ボリュームです"
                        p_l_status = "高め" if p_l_diff_rat > 3 else ("低め" if p_l_diff_rat < -3 else "標準的")
                        area_analysis_list.append(f"🟢 **低貸P:** 平均差 **{p_l_diff_cnt:+.0f}台**({p_l_scale})。構成比は **{p_low_rat:.1f}%** と{p_l_status}です。")

                        s_n_diff_cnt = avg_s_norm - p_ref['S通常']
                        s_n_diff_rat = s_norm_rat - p_ref['S通常比率']
                        if s_n_diff_cnt > 200: s_n_scale = "衝撃的なスロットボリューム。全国区の多台数スロット旗艦店が激突する最重要激戦区です"
                        elif s_n_diff_cnt > 100: s_n_scale = "圧倒的な多台数設置。スマスロ等の最新鋭機を軸にしたスロット主導型市場です"
                        elif s_n_diff_cnt > 40: s_n_scale = "平均との乖離が大きく、多台数店舗による厚いスロット層が存在します"
                        elif s_n_diff_cnt < -40: s_n_scale = "極めて供給が少なく、潜在需要が他へ流出している可能性があります"
                        else: s_n_scale = "平均的な設置ボリュームです"
                        s_n_status = "高水準" if s_n_diff_rat > 3 else ("低め" if s_n_diff_rat < -3 else "標準的")
                        area_analysis_list.append(f"🔵 **通常S:** 平均差 **{s_n_diff_cnt:+.0f}台**({s_n_scale})。構成比は **{s_norm_rat:.1f}%** と{s_n_status}です。")

                        s_l_diff_cnt = (neighbor_df["S低貸"].mean()) - p_ref['S低貸']
                        s_l_diff_rat = s_low_rat - p_ref['S低貸比率']
                        if s_l_diff_cnt > 50: s_l_scale = "平均を圧倒する多台数設置。若年層やライトユーザーの分厚い受け皿となっています"
                        elif s_l_diff_cnt > 25: s_l_scale = "平均を大きく上回る厚い層が存在し、多台数店が積極的に需要を取り込んでいます"
                        elif s_l_diff_cnt > 10: s_l_scale = "平均との差が明快で、多台数店舗中心の安定した需要基盤があります"
                        elif s_l_diff_cnt < -10: s_l_scale = "平均よりかなり絞った設置状況です"
                        else: s_l_scale = "平均的な設置ボリュームです"
                        s_l_status = "高め" if s_l_diff_rat > 2 else ("低め" if s_l_diff_rat < -2 else "標準的")
                        area_analysis_list.append(f"🟡 **低貸S:** 平均差 **{s_l_diff_cnt:+.0f}台**({s_l_scale})。構成比は **{s_low_rat:.1f}%** と{s_l_status}です。")

                        for comment in area_analysis_list:
                            st.write(comment)

                    st.markdown("---")

                    # 4. 構成数値詳細 (テーブル)
                    st.markdown("### 📝 構成数値詳細(部門別・貸玉比率付)")
                    final_table_df = pd.concat([avg_summary_df, neighbor_df], axis=0).copy()

                    column_config_dict = {
                        "distance": st.column_config.NumberColumn("距離(km)", format="%.1f"),
                        "総台数": st.column_config.NumberColumn("総台数", format="%d"),
                    }
                    for col in dept_order:
                        column_config_dict[col] = st.column_config.NumberColumn(col, format="%d")
                        column_config_dict[f"{col}比率"] = st.column_config.NumberColumn(f"{col}比率", format="%.1f%%")

                    show_cols = ["店舗名", "distance", "総台数"]
                    for c in dept_order:
                        show_cols.append(c)
                        show_cols.append(f"{c}比率")

                    st.dataframe(
                        final_table_df.sort_values(["sort_prio", "distance"], ascending=[True, True])[show_cols],
                        hide_index=True, 
                        use_container_width=True,
                        column_config=column_config_dict
                    )

                    # 5. 店舗別・部門積み上げ台数 (グラフ)
                    import altair as alt
                    st.markdown("---")
                    st.markdown("### 📏 店舗別・部門積み上げ台数")
                    
                    plot_combined = pd.concat([avg_summary_df, neighbor_df.sort_values("distance")], axis=0)
                    plot_data = []
                    ratio_data = []
                    
                    for _, row in plot_combined.iterrows():
                        is_self_flag = str(row['店舗ID']) == str(selected_shop_id)
                        label = ("★" if is_self_flag else "") + row['店舗名']
                        if not row["is_avg"]: label += f" ({row['distance']:.1f}km)"
                        
                        for dept in dept_order:
                            plot_data.append({"表示名称": label, "部門": dept, "台数": row[dept]})
                            ratio_data.append({"表示名称": label, "部門": dept, "比率": row[f"{dept}比率"]})

                    color_scale = alt.Scale(
                        domain=dept_order,
                        range=['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78']
                    )

                    chart_count = alt.Chart(pd.DataFrame(plot_data)).mark_bar().encode(
                        y=alt.Y('表示名称:N', sort=None, title=None),
                        x=alt.X('台数:Q', title='設置台数'),
                        color=alt.Color('部門:N', scale=color_scale, sort=dept_order, title="部門"),
                        order=alt.Order('部門_sort:Q'),
                        tooltip=['表示名称', '部門', '台数']
                    ).transform_calculate(
                        部門_sort=f"indexof({dept_order}, datum.部門)"
                    ).properties(height=alt.Step(40))
                    st.altair_chart(chart_count, use_container_width=True)

                    # 6. 比率グラフ
                    st.markdown("### ⚖️ 店舗別・貸玉構成比率(全体100%)")
                    chart_ratio = alt.Chart(pd.DataFrame(ratio_data)).mark_bar().encode(
                        y=alt.Y('表示名称:N', sort=None, title=None),
                        x=alt.X('比率:Q', title='構成比 (%)', stack="normalize"),
                        color=alt.Color('部門:N', scale=color_scale, sort=dept_order, title="部門"),
                        order=alt.Order('部門_sort:Q'),
                        tooltip=['表示名称', '部門', '比率']
                    ).transform_calculate(
                        部門_sort=f"indexof({dept_order}, datum.部門)"
                    ).properties(height=alt.Step(40))
                    st.altair_chart(chart_ratio, use_container_width=True)

                    # 7. 各店舗詳細(アコーディオン)
                    st.markdown("---")

                    for _, shop in neighbor_df.sort_values("distance").iterrows():
                        is_this_self = str(shop["店舗ID"]) == str(selected_shop_id)
                        is_self_str = " (★自店)" if is_this_self else ""
                        
                        s_diff_total = shop["総台数"] - avg_total
                        s_diff_normal = (shop["P通常"] + shop["S通常"]) - avg_normal_total
                        s_diff_p_norm = shop["P通常"] - avg_p_norm
                        s_diff_s_norm = shop["S通常"] - avg_s_norm

                        title_label = f"📍 {shop['店舗名']}{is_self_str} - 距離: {shop['distance']:.1f}km / 総合{shop['全体順位']}位"
                        
                        with st.expander(title_label):
                            comp_p_norm_rat, comp_p_low_rat, comp_s_norm_rat, comp_s_low_rat = shop["P通常比率"], shop["P低貸比率"], shop["S通常比率"], shop["S低貸比率"]

                            comp_report_text = f"""

**【市場内ランクと乖離】**

* 総合順位: **第{shop['全体順位']}位** (平均差 {int(s_diff_total):+d}台)

* 通常貸順位: **第{shop['通常順位']}位** (平均差 {int(s_diff_normal):+d}台)

* P通常: {shop['P通常順位']}位 ({int(s_diff_p_norm):+d}台) / S通常: {shop['S通常順位']}位 ({int(s_diff_s_norm):+d}台)



**【ポジショニング分析】**

"""
                            # --- 【ポジショニング分析(平均差ベース・整数表示版)】 ---
                            if shop["全体順位"] == 1:
                                comp_report_text += f"✅ **商圏リーダー:** 台数規模でエリア単独首位。平均差を {int(s_diff_total):+d}台 上回る圧倒的な物量が武器です。"
                            else:
                                # 2位以下の店舗は、商圏平均との乖離(s_diff_total)をベースに細分化
                                if s_diff_total >= 300:
                                    comp_report_text += f"✅ **準メガ・メガ対抗店:** 首位ではないものの、商圏平均差を {int(s_diff_total):+d}台 と大幅に凌駕する巨大店舗です。地域1番店とバチバチに渡り合えるだけの強力なハードウェア(物量)を保有しています。"
                                elif s_diff_total >= 100:
                                    comp_report_text += f"✅ **主要有力店(規模優位):** 商圏平均差を {int(s_diff_total):+d}台 上回るエリア上位の有力店です。市場への影響力が十分に高く、メイン機種の稼働シェアを大きく囲い込めるポジションにあります。"
                                elif s_diff_total >= -50 and s_diff_total < 100:
                                    comp_report_text += f"✅ **市場標準・中核店舗:** 規模は商圏平均差 {int(s_diff_total):+d}台 と、エリアの平均水準に位置するスタンダードな店舗です。最も競合の波に飲まれやすいため、営業スケジュールや特定日の仕掛けなど「ソフト面」の差別化が生命線となります。"
                                elif s_diff_total >= -200 and s_diff_total < -50:
                                    comp_report_text += f"✅ **中堅・コンパクト店:** 商圏平均差が {int(s_diff_total):+d}台 と、平均を下回るサイズ感です。真っ向勝負の薄利多売は避けるべきで、中古機の機敏な運用や低貸比率の最適化など「筋肉質な営業」へのシフトが推奨されるポジションです。"
                                else:
                                    # 平均差 -200台未満
                                    comp_report_text += f"✅ **局地戦型・ニッチ専門店:** 商圏平均差を {int(s_diff_total):+d}台 と大きく下回る極小規模店、あるいは特定部門に特化した専門店です。メガ店舗の網に引っかからないコアな常連客の獲得、または接客や地域コミュニティ化に特化したニッチ戦略が必須となります。"

                            comp_report_text += "\n\n**【部門別シェア比較(市場平均比)】**"
                            comp_dept_analysis = []
                            if comp_p_norm_rat > p_norm_rat + 5:
                                comp_dept_analysis.append(f"📈 **P通常特化型:** 市場平均({p_norm_rat:.1f}%)に対し、{comp_p_norm_rat:.1f}%と高い構成。4円ユーザーの受け皿となっています。")
                            if comp_s_norm_rat > s_norm_rat + 5:
                                comp_s_low_rat_val = comp_s_low_rat # 安全用
                                comp_dept_analysis.append(f"📈 **S通常特化型:** 市場平均({s_norm_rat:.1f}%)に対し、{comp_s_norm_rat:.1f}%とスロット通常貸を極めて重視。勝負志向の強い顧客層を抱えています。")
                            if comp_p_low_rat > p_low_rat + 5:
                                comp_dept_analysis.append(f"📉 **P低貸過多:** 市場平均({p_low_rat:.1f}%)を大きく上回る{comp_p_low_rat:.1f}%の構成。薄利多売の傾向が強く、集客はできても収益性に課題がある可能性があります。")
                            if comp_s_low_rat > s_low_rat + 5:
                                comp_dept_analysis.append(f"📉 **S低貸重視:** 市場平均({s_low_rat:.1f}%)に対し、{comp_s_low_rat:.1f}%が低貸。滞在型ユーザーが多い構成です。")
                            
                            if not comp_dept_analysis:
                                comp_report_text += "\n⚖️ **市場標準構成:** 全部門において市場平均に近いバランスの取れた構成です。"
                            else:
                                comp_report_text += "\n" + "\n".join(comp_dept_analysis)

                            comp_report_text += "\n\n**【戦略・分析】**"
                            if s_diff_normal > 0:
                                comp_report_text += f"\n💡 **収益力:** 通常貸部門が平均差を {int(s_diff_normal)}台 上回る強力な布陣。収益基盤が安定しています。"
                            else:
                                comp_report_text += f"\n💡 **客数依存:** 通常貸が平均差で {int(s_diff_normal)}台 と不足。低貸による客数確保への依存が強い構成です。"

                            st.markdown(comp_report_text)


            # =========================================================
            # --- 🎰 タブ3: 設置機種詳細 ---
            # =========================================================
            with tabs["🎰 設置機種詳細"]:
                st.subheader("🎰 設置機種・市場比較レポート")
                
                try:
                    # 1. データの読み込み
                    if "processed_df" not in st.session_state:
                        st.session_state.processed_df = pd.read_parquet("processed_analysis_data.parquet")
                    
                    df_all = st.session_state.processed_df.copy()
                    area_shop_ids = neighbor_df["店舗ID"].astype(str).tolist()
                    df_all["店舗ID"] = df_all["店舗ID"].astype(str)
                    
                    # 商圏内のデータに絞り込み
                    area_p = df_all[df_all["店舗ID"].isin(area_shop_ids)].copy()

                    # タブの作成
                    sub_tabs = st.tabs(["🔴 通常P", "🟢 低貸P", "🔵 通常S", "🟡 低貸S"])
                    categories = {"通常P": "通常P", "低貸P": "低貸P", "通常S": "通常S", "低貸S": "低貸S"}

                    # 【修正ポイント】タブ10統合表示用のセッションステート辞書構造を初期化(開かなくても引き渡す用)
                    if "tab3_results" not in st.session_state:
                        st.session_state.tab3_results = {}

                    for i, (label, cat_name) in enumerate(categories.items()):
                        with sub_tabs[i]:
                            display_df = area_p[area_p["貸玉区分"] == cat_name].copy()
                            
                            if display_df.empty:
                                st.info(f"{label} のデータが商圏内にありません。")
                                continue

                            # --- A. カテゴリ別の表示列定義 ---
                            is_p = "P" in cat_name
                            if is_p:
                                spec_cols = ["販売年月日", "確率区分", "スマパチ", "デカヘソ"]
                            else:
                                spec_cols = ["販売年月日", "機種タイプ区分", "スマスロ", "30パイ", "BT機"]

                            existing_spec_cols = [c for c in spec_cols if c in display_df.columns]

                            # --- B. 商圏集計ベースの作成 (数値計算用) ---
                            agg_dict = {
                                "機種名": "first", "メーカー名": "first", "中古単価": "max",
                                "全国台数": "max", "都道府県台数": "max", "設置台数": "sum"
                            }
                            for sc in existing_spec_cols:
                                agg_dict[sc] = "first"

                            summary_for_calc = display_df.groupby("Pcode").agg(agg_dict).rename(columns={"設置台数": "商圏合計"}).reset_index()

                            # --- C. 各店舗の台数列を追加 ---
                            shop_cols = []
                            for _, s_row in neighbor_df.sort_values("distance").iterrows():
                                s_id = str(s_row["店舗ID"])
                                s_name = s_row["店舗名"]
                                shop_specific = display_df[display_df["店舗ID"] == s_id].groupby("Pcode")["設置台数"].sum().reset_index(name=s_name)
                                summary_for_calc = pd.merge(summary_for_calc, shop_specific, on="Pcode", how="left")
                                summary_for_calc[s_name] = summary_for_calc[s_name].fillna(0).astype(int)
                                shop_cols.append(s_name)

                            summary_for_calc = summary_for_calc.sort_values("商圏合計", ascending=False)
                            grand_totals = {col: summary_for_calc[col].sum() for col in ["商圏合計"] + shop_cols}

                            # --- D. 表示用フォーマット ---
                            def to_comma(x):
                                if pd.isna(x) or x == "": return "0"
                                try: return f"{int(float(x)):,}"
                                except: return str(x)

                            summary_disp = summary_for_calc.copy()
                            for col in ["中古単価", "全国台数", "都道府県台数", "商圏合計"] + shop_cols:
                                summary_disp[col] = summary_disp[col].apply(to_comma)

                            sum_row = {col: "" for col in summary_disp.columns}
                            sum_row["機種名"] = "■店舗合計台数"
                            sum_row["商圏合計"] = to_comma(grand_totals["商圏合計"])
                            for s_name in shop_cols:
                                sum_row[s_name] = to_comma(grand_totals[s_name])
                            
                            summary_with_total = pd.concat([pd.DataFrame([sum_row]), summary_disp], ignore_index=True)

                            # --- E. データフレーム表示 ---
                            final_cols = ["機種名", "メーカー名"] + existing_spec_cols + ["中古単価", "全国台数", "都道府県台数", "商圏合計"] + shop_cols
                            column_conf = {
                                "機種名": st.column_config.TextColumn("機種名", width="large"),
                                "メーカー名": st.column_config.TextColumn("メーカー名", width="medium"),
                                "販売年月日": st.column_config.TextColumn("導入日", width=None),
                            }
                            for sc in existing_spec_cols:
                                if sc != "販売年月日":
                                    column_conf[sc] = st.column_config.TextColumn(sc, width=80)
                            for col in ["中古単価", "全国台数", "都道府県台数", "商圏合計"] + shop_cols:
                                column_conf[col] = st.column_config.TextColumn(col, width=80)

                            st.dataframe(summary_with_total[final_cols], use_container_width=True, height=450, column_config=column_conf, hide_index=True)

                            # 市場分析用の数値集計
                            pivot = display_df.pivot_table(index="機種名", columns="店舗名", values="設置台数", aggfunc="sum").fillna(0).astype(int)
                            shop_cols_list = pivot.columns.tolist()
                            shop_totals = {s: int(pivot[s].sum()) for s in shop_cols_list if pivot[s].sum() > 0}
                            super_large_count = sum(1 for t in shop_totals.values() if t >= 600)
                            large_shops_count = sum(1 for t in shop_totals.values() if t >= 400)
                            mid_shops_count = sum(1 for t in shop_totals.values() if t >= 200 and t < 400)
                            total_shops = len(shop_totals)
                            market_total_sum = sum(shop_totals.values())

                            # --- G. 📊 商圏環境アセスメント ---
                            st.markdown("#### 📊 商圏環境アセスメント")
                            
                            # 【修正ポイント】アセスメント結果をテキスト変数に格納し、タブ10へ安全に引き渡せるようにする
                            assessment_text = ""
                            assessment_status = "info" # UI色分け用タグ
                            
                            if total_shops > 0:
                                if (large_shops_count / total_shops >= 0.5) or (super_large_count >= 2):
                                    assessment_status = "error"
                                    assessment_text = f"【超激戦区】600台超の旗艦店を含む大型店が主導する市場。資本力と新台の『鮮度』が直結し、中小店舗は非常に厳しい生存競争を強いられます。"
                                    st.error(assessment_text)
                                elif large_shops_count >= 2 or mid_shops_count >= 4:
                                    assessment_status = "warning"
                                    assessment_text = f"【要警戒エリア】{large_shops_count}店舗の大型店を筆頭に、バランスの取れた競合が存在。自店の『尖った強み』を打ち出さないと、大型店と中型店の板挟みになる恐れがあります。"
                                    st.warning(assessment_text)
                                elif mid_shops_count >= 1:
                                    assessment_status = "info"
                                    assessment_text = f"【標準エリア】200台〜400台の中型店が中心の市場。特定の機種構成や地域密着型の営業といった『差別化戦略』が効果を発揮しやすい環境です。"
                                    st.info(assessment_text)
                                else:
                                    assessment_status = "success"
                                    assessment_text = f"【安定市場】200台未満の小規模店が中心。競合圧力が低く、既存顧客の維持(固定客化)が最も重要なフェーズです。"
                                    st.success(assessment_text)

                            # --- H. 🤖 店舗別・機種構成AI戦略診断 ---
                            st.markdown("---")
                            st.markdown("### 🤖 店舗別・機種構成AI戦略診断")
                            
                            url_id = st.query_params.get("id")
                            top_10_pcodes = summary_for_calc.sort_values("全国台数", ascending=False).head(10)["Pcode"].tolist()
                            target_shops_exist = [c for c in shop_cols if c in summary_for_calc.columns]
                            top10_summary = summary_for_calc[summary_for_calc["Pcode"].isin(top_10_pcodes)]
                            all_top10_totals = top10_summary[target_shops_exist].sum().to_dict()

                            for index, s_row in neighbor_df.sort_values("distance").iterrows():
                                try:
                                    s_name = s_row["店舗名"]
                                    if s_name not in summary_for_calc.columns: continue
                                    
                                    s_total = summary_for_calc[s_name].sum()
                                    if s_total == 0: continue
                                    
                                    # 指標計算
                                    s_top10_units = all_top10_totals.get(s_name, 0)
                                    s_top10_ratio = (s_top10_units / s_total * 100) if s_total > 0 else 0
                                    s_share = (s_total / market_total_sum * 100) if market_total_sum > 0 else 0
                                    counts_list = list(all_top10_totals.values())
                                    rank = len([v for v in counts_list if v > s_top10_units]) + 1
                                    
                                    # 独自機種
                                    other_shops = [c for c in target_shops_exist if c != s_name]
                                    s_only_count = len(summary_for_calc[(summary_for_calc[other_shops].sum(axis=1) == 0) & (summary_for_calc[s_name] > 0)]) if other_shops else 0

                                    # 新台比率
                                    very_new_ratio = 0.0
                                    if "販売年月日" in summary_for_calc.columns:
                                        try:
                                            df_fresh = summary_for_calc.copy()
                                            df_fresh["dt"] = pd.to_datetime(df_fresh["販売年月日"], errors='coerce')
                                            v_units = df_fresh[df_fresh["dt"] >= (pd.Timestamp.now() - pd.Timedelta(days=180))][s_name].sum()
                                            very_new_ratio = (v_units / s_total * 100)
                                        except: pass

                                    # レポートテキスト生成
                                    if s_total >= 1000: pos_text = f"設置台数{int(s_total)}台の**超弩級メガホール**です。圧倒的物量が最大の武器です。"
                                    elif s_total >= 450: pos_text = f"設置台数{int(s_total)}台の**大型実力店**です。"
                                    else: pos_text = f"設置台数{int(s_total)}台の中堅店舗です。"

                                    top10_status = "high" if s_top10_ratio >= 18 else "mid" if s_top10_ratio >= 10 else "low"
                                    fresh_status = "high" if very_new_ratio >= 20 else "mid" if very_new_ratio >= 10 else "low"

                                    if top10_status == "high" and fresh_status == "high": strategy_msg = "【地域旗艦・積極投資型】主要機・最新台ともに極めて厚く、エリアのトレンドを牽引する圧倒的な構成です。"
                                    elif top10_status == "high" and fresh_status == "mid": strategy_msg = "【王道・トレンド維持型】全国的人気機を主軸に据えつつ、新台も適宜入れ替える、隙のない正攻法の営業スタイルです。"
                                    elif top10_status == "high" and fresh_status == "low": strategy_msg = "【王道・長期貢献重視型】メイン機種の設置シェアは高いですが、新台への依存度は低めです。"
                                    elif top10_status == "mid" and fresh_status == "high": strategy_msg = "【最新台特化・集客フック型】話題性を武器に新規客を呼び込む構成です。"
                                    elif top10_status == "mid" and fresh_status == "mid": strategy_msg = "【バランス重視・標準型】主要機と新台を市場平均並みに配置した、リスクを抑えた堅実な構成です。"
                                    elif top10_status == "mid" and fresh_status == "low": strategy_msg = "【定番回帰・堅実運用型】全国的に評価の定まった定番機種を中心に、低コストで手堅く運用している傾向があります。"
                                    elif top10_status == "low" and fresh_status == "high": strategy_msg = "【一点突破・新台勝負型】定番機のシェアをあえて捨て、最新台の鮮度のみで勝負しています。"
                                    elif top10_status == "low" and fresh_status == "mid": strategy_msg = "【差別化・独自運用型】独自の選定センスが光る構成です。"
                                    elif top10_status == "low" and fresh_status == "low": strategy_msg = "【超独自・ニッチ特化型】マニアックな機種やバラエティなど『ここでしか打てない』環境を重視しています。"
                                    else: strategy_msg = "現在の市場トレンドとは一線を画した、独自の機種構成となっています。"

                                    uniqueness_msg = f"エリア内で自店のみの希少機種({s_only_count}機種)を保有しています。"
                                    if s_only_count >= 30: uniqueness_msg = f"商圏内で自店にしかない機種が**{s_only_count}機種**という圧倒的なバラエティを誇ります。"
                                    elif s_only_count >= 15: uniqueness_msg = f"商圏内で自店のみ設置の機種が**{s_only_count}機種**存在します。"

                                    advice = "現在のバランスを維持しつつ、主要機種のエリア順位を上げる検討を行ってください。"
                                    if very_new_ratio > 30: advice = "【高鮮度・高投資戦略】新台の稼働寿命を見極めた機敏な配置変更が重要です。"
                                    elif s_only_count > 20: advice = "【差別化特化戦略】『ここでしか打てない』という希少性を販促の軸に据えてください。"

                                    full_report = f"**【規模と立ち位置】**\n{pos_text}\n\n**【構成分析】**\n全国トップ10機種は店内の{s_top10_ratio:.1f}%({int(s_top10_units)}台)。最新台比率は{very_new_ratio:.1f}%。\n\n**【店舗戦略診断】**\n{strategy_msg}\n\n**【独自性】**\n{uniqueness_msg}\n\n**【💡 AIアドバイス】**\n{advice}"

                                    # 自店判定
                                    s_id_raw = next((str(s_row[c]) for c in ["Pachinko_Shop_Pcode", "Pcode", "店舗コード", "shop_id", "店舗ID"] if c in s_row and s_row[c]), None)
                                    is_target = (url_id == s_id_raw) if url_id and s_id_raw else (s_row["distance"] == 0)

                                    # 【修正ポイント】自店のデータを、開いていなくてもタブ10へ渡せるように専用セッションステート辞書へ完全格納
                                    if is_target:
                                        clean_target_id = str(selected_shop_id).strip()
                                        if clean_target_id not in st.session_state.tab3_results:
                                            st.session_state.tab3_results[clean_target_id] = {"departments": {}}
                                        
                                        st.session_state.tab3_results[clean_target_id]["departments"][cat_name] = {
                                            "label": label,
                                            "assessment_status": assessment_status,
                                            "assessment_text": assessment_text,
                                            "full_report": full_report,
                                            "total_seats": int(s_total),
                                            "share": s_share,
                                            "top10_units": int(s_top10_units),
                                            "top10_rank": rank,
                                            "only_count": s_only_count
                                        }

                                    with st.expander(f"{'🏠 (自店)' if is_target else '🔍'} {s_name} の詳細分析を見る", expanded=is_target):
                                        col1, col2, col3, col4 = st.columns(4)
                                        col1.metric("規模", f"{int(s_total)}台")
                                        col2.metric("エリアシェア", f"{s_share:.1f}%")
                                        col3.metric("全国TOP10", f"{int(s_top10_units)}台", f"{rank}位")
                                        col4.metric("独自機種", f"{s_only_count}機種")
                                        st.markdown(full_report)

                                        # 🎯 攻め筋の厳選提案
                                        all_stats = display_df.groupby("機種名").agg({"全国台数": "max", "設置台数": "sum"}).reset_index().rename(columns={"設置台数": "商圏合計"})
                                        s_units_df = display_df[display_df["店舗名"] == s_name].groupby("機種名")["設置台数"].sum().reset_index(name="自店台数")
                                        analysis_data = pd.merge(all_stats, s_units_df, on="機種名", how="left").fillna(0)
                                        
                                        gap_machines = analysis_data[(analysis_data["商圏合計"] >= 10) & (analysis_data["自店台数"] < (analysis_data["商圏合計"] * 0.15))].sort_values("商圏合計", ascending=False)
                                        list_gap = gap_machines["機種名"].tolist()[:3]
                                        niche_machines = analysis_data[(analysis_data["全国台数"] > 5000) & (analysis_data["商圏合計"] < 10)].sort_values("全国台数", ascending=False)
                                        list_niche = niche_machines["機種名"].tolist()[:3]
                                        
                                        st.markdown("---")
                                        st.markdown(f"##### 🎯 {s_name} 専用:攻め筋の厳選提案 ({cat_name})")
                                        sel_cols = st.columns(2)
                                        with sel_cols[0]:
                                            if list_gap:
                                                rec_1 = st.selectbox("推奨1: シェア奪還型", list_gap, key=f"sel1_{cat_name}_{s_name}_{index}")
                                                st.warning(f"**{rec_1}**\n\n競合店に流れている顧客を取り戻すための優先機種です。")
                                        with sel_cols[1]:
                                            if list_niche:
                                                rec_2 = st.selectbox("推奨2: エリア盲点型", list_niche, key=f"sel2_{cat_name}_{s_name}_{index}")
                                                st.success(f"**{rec_2}**\n\n他店が手薄な『お宝機種』で、独自性を打ち出しましょう。")

                                except Exception as e_inner:
                                    st.error(f"{s_row['店舗名']}の分析中にエラー: {e_inner}")

                except Exception as e_outer:
                    st.error(f"タブ3全体でエラーが発生しました: {e_outer}")



            # =========================================================
            # --- 🎰 タブ4: タイプ別構成 ---
            # =========================================================
            with tabs["📊 タイプ別"]:
                st.subheader("📊 部門別・機種タイプ構成比較")

                if "processed_df" in st.session_state:
                    full_df = st.session_state.processed_df
                    
                    # --- タブ1と同じソートロジックでIDリストを作成 ---
                    sorted_neighbor = neighbor_df.sort_values("distance")
                    area_shop_ids = sorted_neighbor["店舗ID"].astype(str).tolist()
                    name_map = dict(zip(sorted_neighbor["店舗ID"].astype(str), sorted_neighbor["店舗名"]))
                    selected_shop_id_str = sid_query

                    categories = {"🔴 通常P": "通常P", "🟢 低貸P": "低貸P", "🔵 通常S": "通常S", "🟡 低貸S": "低貸S"}
                    sub_tabs = st.tabs(list(categories.keys()))

                    for i, (tab_label, dept_name) in enumerate(categories.items()):
                        dept_key = tab_label.split()[-1] # "通常P" などのキーを特定
                        
                        with sub_tabs[i]:
                            df_dept = full_df[full_df["貸玉区分"] == dept_name]
                            if df_dept.empty:
                                st.info(f"{dept_name} のデータがありません。")
                                continue

                            is_p = "P" in dept_name
                            type_col = "パチンコタイプ名" if is_p else "スロットタイプ名"
                            sort_col = "パチンコタイプID" if is_p else "スロットタイプID"

                            # エリア内店舗の集計
                            df_area = df_dept[df_dept["店舗ID"].isin(area_shop_ids)]
                            if df_area.empty:
                                st.warning("近隣エリアにデータが存在しません。")
                                continue

                            pivot_area = df_area.groupby([type_col, "店舗ID"])["設置台数"].sum().unstack(fill_value=0)
                            
                            # area_shop_ids(距離順)に含まれる順にカラムを並べ替え
                            existing_ids = [sid for sid in area_shop_ids if sid in pivot_area.columns]
                            pivot_area = pivot_area[existing_ids]
                            
                            # カラム名を店舗名に置換(★自店ラベル付与)
                            pivot_area.columns = [
                                f"★自店: {name_map.get(sid, sid)}" if sid == selected_shop_id_str else name_map.get(sid, sid) 
                                for sid in pivot_area.columns
                            ]

                            # 平均の算出
                            n_shops_all = df_dept["店舗ID"].nunique()
                            n_shops_area = len(existing_ids)
                            national_avg = (df_dept.groupby(type_col)["設置台数"].sum() / n_shops_all).rename("🌏 全国平均")
                            area_avg = (df_area.groupby(type_col)["設置台数"].sum() / n_shops_area).rename("🏘️ エリア平均")

                            # 結合とタイプ順ソート
                            df_base = pd.concat([national_avg, area_avg, pivot_area], axis=1).fillna(0)
                            type_order = df_dept.groupby(type_col)[sort_col].min().sort_values().index
                            df_base = df_base.reindex([t for t in type_order if t in df_base.index])

                            # 表示用データの作成 (転置)
                            df_disp_count = df_base.T
                            df_disp_ratio = (df_base / df_base.sum() * 100).fillna(0).T

                            # テーブル表示
                            st.markdown("#### 🔢 設置台数(台)")
                            count_cfg = {col: st.column_config.NumberColumn(width=100, format="%.1f") for col in df_base.index}
                            count_cfg["index"] = st.column_config.TextColumn("店舗/タイプ名", pinned=True, width="medium")
                            st.dataframe(df_disp_count, use_container_width=True, column_config=count_cfg)
                            
                            # 比較対象の基準を選択(全国平均 or エリア平均)
                            comparison_target = st.radio(
                                "太字の基準を選択:", 
                                ["🌏 全国平均", "🏘️ エリア平均"], 
                                horizontal=True,
                                key=f"bold_target_{dept_name}"
                            )

                            # スタイル定義用の関数
                            def highlight_above_avg(column):
                                target_val = df_disp_ratio.loc[comparison_target, column.name]
                                return [
                                    'font-weight: bold; color: #1f77b4;' if val > target_val else '' 
                                    for val in column
                                ]

                            # スタイルを適用
                            styled_ratio_df = df_disp_ratio.style.apply(highlight_above_avg, axis=0).format("{:.1f}%")

                            ratio_cfg = {col: st.column_config.NumberColumn(width=100) for col in df_base.index}
                            ratio_cfg["index"] = st.column_config.TextColumn("店舗/タイプ名", pinned=True, width="medium")
                            
                            st.dataframe(styled_ratio_df, use_container_width=True, column_config=ratio_cfg)

                            # --- 📊 店舗別・タイプ構成比率グラフ ---
                            st.markdown(f"#### ⚖️ 店舗別・{tab_label} タイプ構成比較")
                            import plotly.express as px
                            
                            # 表示したい順序を「上から順」に作成
                            desired_order_top_down = ["🌏 全国平均", "🏘️ エリア平均"]
                            other_shops = []
                            for sid in area_shop_ids:
                                s_name = name_map.get(sid, sid)
                                full_name = f"★自店: {s_name}" if sid == selected_shop_id_str else s_name
                                if full_name in df_disp_ratio.index:
                                    other_shops.append(full_name)
                            desired_order_top_down.extend(other_shops)

                            # Plotlyのy軸仕様に合わせてリストを反転
                            plot_y_order = desired_order_top_down[::-1]
                            dynamic_height = 200 + (len(desired_order_top_down) * 45)

                            # --- A. 設置台数(実数)グラフ ---
                            st.markdown("##### 🔢 設置台数(実数)")
                            df_ordered_count = df_disp_count.reindex(desired_order_top_down).dropna(how='all')
                            df_graph_count = df_ordered_count.reset_index().rename(columns={'index': '店舗名'})
                            df_graph_count = df_graph_count.melt(id_vars="店舗名", var_name="タイプ", value_name="台数")

                            fig_count = px.bar(
                                df_graph_count, 
                                x="台数", 
                                y="店舗名", 
                                color="タイプ", 
                                orientation='h',
                                category_orders={"店舗名": plot_y_order, "タイプ": list(type_order)},
                                color_discrete_sequence=px.colors.qualitative.Pastel,
                                height=dynamic_height,
                                text_auto='.1f'
                            )
                            fig_count.update_layout(
                                xaxis_title="設置台数(台)", yaxis_title="",
                                legend_title="タイプ名",
                                margin=dict(l=0, r=10, t=100, b=40),
                                legend=dict(orientation="h", yanchor="bottom", y=1.05, xanchor="center", x=0.5)
                            )
                            fig_count.update_yaxes(categoryorder='array', categoryarray=plot_y_order)
                            st.plotly_chart(fig_count, use_container_width=True)

                            # --- B. 構成比率(100%積立)グラフ ---
                            st.markdown("##### 🏁 構成比率(100%積立)")
                            df_ordered_ratio = df_disp_ratio.reindex(desired_order_top_down).dropna(how='all')
                            df_graph_ratio = df_ordered_ratio.reset_index().rename(columns={'index': '店舗名'})
                            df_graph_ratio = df_graph_ratio.melt(id_vars="店舗名", var_name="タイプ", value_name="比率")

                            fig_ratio = px.bar(
                                df_graph_ratio, 
                                x="比率", 
                                y="店舗名", 
                                color="タイプ", 
                                orientation='h',
                                category_orders={"店舗名": plot_y_order, "タイプ": list(type_order)},
                                color_discrete_sequence=px.colors.qualitative.Pastel,
                                height=dynamic_height,
                                text_auto='.1f'
                            )
                            fig_ratio.update_layout(
                                xaxis_title="構成比率 (%)", yaxis_title="",
                                legend_title="タイプ名",
                                margin=dict(l=0, r=10, t=100, b=40),
                                legend=dict(orientation="h", yanchor="bottom", y=1.05, xanchor="center", x=0.5)
                            )
                            fig_ratio.update_yaxes(categoryorder='array', categoryarray=plot_y_order)
                            st.plotly_chart(fig_ratio, use_container_width=True)


                            # --- 📈 エリア構成アセスメント(市場傾向テキスト生成・保存) ---
                            st.markdown("#### 💎 エリア構成アセスメント")
                            diff_area_nat = df_disp_ratio.loc["🏘️ エリア平均"] - df_disp_ratio.loc["🌏 全国平均"]
                            
                            if not diff_area_nat.dropna().empty:
                                top_plus = diff_area_nat.idxmax()
                                top_minus = diff_area_nat.idxmin()
                                
                                analysis_text = f"【市場傾向:{dept_name}部門】 "
                                if diff_area_nat.abs().max() < 3:
                                    analysis_text += "全国平均に近い標準的な構成です。"
                                else:
                                    analysis_text += (
                                        f"全国比で「{top_plus}」の構成比が高く(+{diff_area_nat.max():.1f}%)、"
                                        f"逆に「{top_minus}」が手薄({diff_area_nat.min():.1f}%)な傾向にあります。"
                                    )
                                
                                full_assessment = f"{analysis_text}\n\n周辺店舗は {top_plus} を中心とした運用に注力しており、特定のスペック帯に支持が集中しやすい市場環境です。"
                                st.info(full_assessment)
                                
                                # ルートA: タブ10が直接見に行く「tab4_market_notes」への格納
                                if "tab4_market_notes" not in st.session_state:
                                    st.session_state.tab4_market_notes = {}
                                # dept_key ("通常P"など) をそのままキーにして保存
                                st.session_state.tab4_market_notes[dept_key] = full_assessment

                                # 既存の互換性を残すためのバックアップ保存(残しておいても無害です)
                                if "analysis_notes" not in st.session_state:
                                    st.session_state.analysis_notes = {}
                                note_key = f"note_tab4_{dept_key}_{selected_shop_id_str}"
                                st.session_state.analysis_notes[note_key] = full_assessment
                            else:
                                full_assessment = "比較可能なデータがありません"
                                st.write(full_assessment)



                            # --- 🤖 店舗別・タイプ構成詳細分析 ---
                            st.markdown("---")
                            st.markdown("### 🔍 店舗別・タイプ構成詳細分析")
                            
                            # タブ10で再利用するために結果格納用辞書を初期化
                            if "tab4_results" not in st.session_state:
                                st.session_state.tab4_results = {}

                            for sid in area_shop_ids:
                                s_name = name_map.get(sid, sid)
                                full_name = f"★自店: {s_name}" if sid == selected_shop_id_str else s_name
                                
                                if full_name not in df_disp_ratio.index:
                                    continue
                                    
                                is_target = (sid == selected_shop_id_str)
                                label_icon = "🏠 (自店)" if is_target else "🔍"
                                
                                with st.expander(f"{label_icon} {s_name} の構成分析", expanded=is_target):
                                    df_shop_dept = df_dept[df_dept["店舗ID"] == sid]
                                    s_total = df_shop_dept["設置台数"].sum() if not df_shop_dept.empty else 0
                                    
                                    # 乖離の計算
                                    ratio_shop = df_disp_ratio.loc[full_name]
                                    diff_nat = ratio_shop - df_disp_ratio.loc["🌏 全国平均"]
                                    diff_area = ratio_shop - df_disp_ratio.loc["🏘️ エリア平均"]
                                    
                                    # 判定ロジック
                                    if not is_p:
                                        normal_labels = [idx for idx in ratio_shop.index if "ノーマル" in str(idx)]
                                        normal_diff = diff_nat.reindex(normal_labels).sum()
                                        if normal_diff > 10: risk_label = "安定・遊技重視(低射幸性)"
                                        elif normal_diff > 3: risk_label = "堅実バランス型"
                                        elif normal_diff < -10: risk_label = "一撃特化・トレンド重視(高射幸性)"
                                        elif normal_diff < -3: risk_label = "積極投資・AT主導型"
                                        else: risk_label = "標準バランス型"
                                    else:
                                        high_spec_labels = [idx for idx in ratio_shop.index if any(s in str(idx) for s in ["1/3", "300", "320", "380"])]
                                        high_spec_diff = diff_nat.reindex(high_spec_labels).sum()
                                        if high_spec_diff > 15: risk_label = "超積極・一撃特化"
                                        elif high_spec_diff > 5: risk_label = "トレンド追随"
                                        elif high_spec_diff < -15: risk_label = "地域密着・遊技重視"
                                        elif high_spec_diff < -5: risk_label = "安定運用型"
                                        else: risk_label = "標準バランス型"

                                    c1, c2 = st.columns(2)
                                    with c1: st.metric("部門設置台数", f"{int(s_total)}台")
                                    with c2: st.metric("営業スタイル", risk_label)

                                    st.write("**📊 市場比較:設置比率の乖離(%ポイント)**")
                                    compare_df = pd.DataFrame({"自店比率": ratio_shop, "全国差": diff_nat, "エリア差": diff_area})
                                    
                                    def color_diff(val):
                                        if isinstance(val, (int, float)):
                                            return f"color: {'red' if val > 5 else 'blue' if val < -5 else 'black'}"
                                        return None

                                    st.dataframe(
                                        compare_df.style.format("{:.1f}%", subset=["自店比率"])
                                        .format("{:+.1f}%", subset=["全国差", "エリア差"])
                                        .map(color_diff, subset=["全国差", "エリア差"]), 
                                        use_container_width=True
                                    )

                                    # AIコメント(店舗傾向)の作成
                                    analysis_parts = []
                                    if not is_p:
                                        # (パチスロ用:必要に応じて並び順を調整)
                                        if normal_diff > 8:
                                            analysis_parts.append(f"全国平均比でノーマルタイプを{normal_diff:.1f}%厚く配置。射幸性を抑え、Aタイプ特有の『技術介入』や『出玉の安定感』を重視する堅実な営業スタイルです。")
                                        elif normal_diff < -8:
                                            analysis_parts.append(f"ノーマル機を{abs(normal_diff):.1f}%抑え、最新のAT機に集約。エリア内でも特に『射幸性』と『トレンド感』を前面に出した攻めの布陣です。")
                                        else:
                                            analysis_parts.append("ノーマル機とAT機の配分が全国平均に近く、幅広い客層に対応できる構成です。")
                                    else:
                                        # 特定の確率帯の乖離をチェック(diff_natを利用)
                                        max_diff_label = diff_nat.abs().idxmax()
                                        max_diff_val = diff_nat.loc[max_diff_label]
                                        
                                        # ① まず「突出している事実」を先にリストに追加
                                        if abs(max_diff_val) > 15:
                                            analysis_parts.append(f"「{max_diff_label}」の構成比が全国平均から {max_diff_val:+.1f}% と大幅に乖離しており、同店における戦略上の重要な差別化ポイントとなっています。")
                                        
                                        # ② 次に「全体像の評価」を追加
                                        if high_spec_diff > 10:
                                            analysis_parts.append(f"ハイスペック機を全国比で{high_spec_diff:.1f}%厚く配置。エリア内の『爆発力』と『トレンド感』で勝負する攻めの姿勢が鮮明です。")
                                        elif high_spec_diff < -10:
                                            analysis_parts.append(f"1/319帯をあえて{abs(high_spec_diff):.1f}%抑え、初当たり回数を重視。長時間遊技を好む層に特化した生存戦略が見て取れます。")
                                        else:
                                            # 全体評価が標準的な場合、接続詞を工夫して自然に繋げる
                                            analysis_parts.append("その他、主要な確率帯の配分は全国平均に近く、一定の安心感があるスタンダードな構成を維持しています。")

                                    trend_text = "\n\n".join(analysis_parts)
                                    st.info(f"**【店舗傾向:{s_name}】**\n\n{trend_text}")
                                    
                                    # 戦略アドバイス(ヒント)の作成
                                    advice = ""
                                    if is_target:
                                        if not is_p:
                                            if normal_diff > 8: advice = "ノーマル機の強さは安定の柱ですが、若年層への訴求は弱くなります。AT機の看板機種を絞って強化し、店内の『活気』を演出してください。"
                                            elif normal_diff < -8: advice = "高単価なAT機主体は収益性は高い反面、客離れリスクも伴います。低投資で遊べる選択肢を強調し、来店頻度を維持する工夫が有効です。"
                                            else: advice = "バランスが良い反面、特徴が埋もれやすくなります。特定機種で『商圏NO.1』を作ることで、集客のフックを強めてください。"
                                        else:
                                            if high_spec_diff < -10: advice = "『遊びやすさ』は武器ですが、話題性が不足しがちです。ライトミドル等でトレンドを補強してください。"
                                            elif high_spec_diff > 10: advice = "メイン機比率が高く競合と真っ向勝負です。一部を利益率の安定する確率帯へシフトする余地があります。"
                                            else: advice = "バランスが良い反面、競合の特化戦略に注意が必要です。手薄な確率帯をピンポイントで補強してください。"
                                        
                                        if advice:
                                            st.markdown("---")
                                            st.success(f"**💡 戦略へのヒント:** {advice}")

                                    # 【最重要】タブ10への受け渡し用構造化データを完全に同期・格納
                                    if sid not in st.session_state.tab4_results:
                                        st.session_state.tab4_results[sid] = {"departments": {}}
                                    
                                    st.session_state.tab4_results[sid]["departments"][dept_key] = {
                                        "total_seats": int(s_total),
                                        "risk_label": risk_label,
                                        "market_assessment": full_assessment, # エリア全体の市場傾向をここに紐付け
                                        "trend_text": trend_text,
                                        "advice_text": advice if is_target else ""
                                    }

                else:
                    st.warning("データが準備できていません。")



            # =========================================================
            # --- 🎰 タブ5: メーカー別設置状況 ---
            # =========================================================
            with tabs["🏢 メーカー別"]:
                st.subheader("🏭 メーカー別設置シェア比較")

                # 事前集計済みのメーカーマスタを読み込み
                @st.cache_data
                def load_maker_data():
                    return pd.read_parquet("maker_summary_master.parquet")

                df_maker_all = load_maker_data()

                if "processed_df" in st.session_state:
                    # 必要な店舗情報・エリア情報の取得
                    sorted_neighbor = neighbor_df.sort_values("distance")
                    area_shop_ids = sorted_neighbor["店舗ID"].astype(str).tolist()
                    name_map = dict(zip(sorted_neighbor["店舗ID"].astype(str), sorted_neighbor["店舗名"]))
                    selected_shop_id_str = sid_query

                    categories = {"🔴 通常P": "通常P", "🟢 低貸P": "低貸P", "🔵 通常S": "通常S", "🟡 低貸S": "低貸S"}
                    sub_tabs = st.tabs(list(categories.keys()))

                    for i, (tab_label, dept_name) in enumerate(categories.items()):
                        with sub_tabs[i]:
                            # マスタから対象部門のみ抽出
                            df_dept_maker = df_maker_all[df_maker_all["貸玉区分"] == dept_name]
                            if df_dept_maker.empty:
                                st.info(f"{dept_name} のメーカーデータがありません。")
                                continue

                            # エリア内店舗に絞り込み
                            df_area = df_dept_maker[df_dept_maker["店舗ID"].isin(area_shop_ids)]
                            
                            # ピボット作成(メーカー × 店舗)
                            pivot_area = df_area.groupby(["メーカー名", "店舗ID"])["設置台数"].sum().unstack(fill_value=0)
                            
                            # データ内に存在する店舗IDのみを抽出
                            existing_ids = [sid for sid in area_shop_ids if sid in pivot_area.columns]
                            pivot_area = pivot_area[existing_ids]
                            
                            # カラム名変換(自店ラベル付与)
                            pivot_area.columns = [
                                f"★自店: {name_map.get(sid, sid)}" if sid == selected_shop_id_str else name_map.get(sid, sid) 
                                for sid in pivot_area.columns
                            ]

                            # 全国平均・エリア平均の算出
                            national_avg = (df_dept_maker.groupby("メーカー名")["設置台数"].sum() / df_dept_maker["店舗ID"].nunique()).rename("🌏 全国平均")
                            area_avg = (df_area.groupby("メーカー名")["設置台数"].sum() / len(existing_ids)).rename("🏘️ エリア平均")

                            # 結合とメーカー並び替え(全国平均が多い順)
                            df_base = pd.concat([national_avg, area_avg, pivot_area], axis=1).fillna(0)
                            df_base = df_base.sort_values(by="🌏 全国平均", ascending=False)
                            
                            # グラフ用:メーカー順序
                            maker_order = df_base.index.tolist()
                            # グラフ用:店舗順序(全国・エリアを先頭にし、あとはデータにある店舗を並べる)
                            final_order = ["🌏 全国平均", "🏘️ エリア平均"] + pivot_area.columns.tolist()

                            # 表示用データの作成
                            df_disp_count = df_base.T
                            df_disp_ratio = (df_base / df_base.sum() * 100).fillna(0).T

                            # --- テーブル表示 ---
                            st.markdown("#### 🔢 メーカー別設置台数(台)")
                            st.dataframe(df_disp_count.style.format("{:.0f}"), use_container_width=True)

                            st.markdown("#### 🏁 メーカー別構成比率(%)")
                            comparison_target = st.radio("太字の基準を選択:", ["🌏 全国平均", "🏘️ エリア平均"], horizontal=True, key=f"maker_bold_{dept_name}")
                            
                            def highlight_maker_ratio(column):
                                target_val = df_disp_ratio.loc[comparison_target, column.name]
                                return ['font-weight: bold; color: #1f77b4;' if val > target_val else '' for val in column]

                            styled_ratio = df_disp_ratio.style.apply(highlight_maker_ratio, axis=0).format("{:.1f}%")
                            st.dataframe(styled_ratio, use_container_width=True)

                            # --- グラフ表示(実数と比率) ---
                            for title, df_data, x_col in [("🔢 設置台数(実数)", df_disp_count, "台数"), ("🏁 構成比率(100%積立)", df_disp_ratio, "比率")]:
                                st.markdown(f"##### {title}")
                                # 指定の順序で取得し、Plotly用に反転させる
                                df_graph = df_data.loc[final_order].iloc[::-1].reset_index().rename(columns={'index': '店舗名'})
                                df_melt = df_graph.melt(id_vars="店舗名", var_name="タイプ", value_name=x_col)
                                
                                fig = px.bar(
                                    df_melt, x=x_col, y="店舗名", color="タイプ", orientation='h',
                                    category_orders={"店舗名": final_order[::-1], "タイプ": maker_order},
                                    color_discrete_sequence=px.colors.qualitative.Pastel,
                                    height=dynamic_height, text_auto='.1f'
                                )
                                fig.update_layout(
                                    xaxis_title=f"{title.split('(')[1].replace(')', '')}", yaxis_title="",
                                    legend_title="メーカー", margin=dict(l=0, r=200, t=50, b=40),
                                    legend=dict(orientation="v", yanchor="top", y=1, xanchor="left", x=1.02, font=dict(size=10))
                                )
                                fig.update_yaxes(categoryorder='array', categoryarray=final_order[::-1])
                                st.plotly_chart(fig, use_container_width=True)

                            # --- 分析コメントセクション ---
                            st.markdown(f"### 📝 {dept_name} の分析コメント")
                            
                            curr_area_avg = df_disp_ratio.loc["🏘️ エリア平均"]
                            curr_nat_avg  = df_disp_ratio.loc["🌏 全国平均"]
                            curr_diff     = curr_area_avg - curr_nat_avg
                            
                            top_maker = curr_diff.idxmax()
                            bot_maker = curr_diff.idxmin()
                            
                            st.info(f"**🏘️ {dept_name} 商圏全体のアセスメント**\n"
                                    f"商圏全体では全国平均と比較して **{top_maker}**(+{curr_diff[top_maker]:.1f}pt)の設置比率が最も高く、"
                                    f"逆に **{bot_maker}**({curr_diff[bot_maker]:.1f}pt)の設置比率が最も低くなっています。")
                            
                            st.markdown(f"#### 🏢 {dept_name} 各店舗の詳細分析")
                            
                            for shop_name in df_disp_ratio.index:
                                if shop_name in ["🌏 全国平均", "🏘️ エリア平均"]:
                                    continue
                                
                                shop_diff    = df_disp_ratio.loc[shop_name] - curr_nat_avg
                                plus_maker   = shop_diff.idxmax()
                                minus_maker  = shop_diff.idxmin()
                                
                                with st.expander(f"📌 {shop_name} の特徴"):
                                    st.write(f"全国平均と比較し、この部門では **{plus_maker}** の比率が **+{shop_diff[plus_maker]:.1f}pt** と最も高く、"
                                             f"逆に **{minus_maker}** の比率は **{shop_diff[minus_maker]:.1f}pt** となっています。")
                                    
                                    major_plus  = shop_diff[shop_diff > 5.0].index.tolist()
                                    major_minus = shop_diff[shop_diff < -5.0].index.tolist()
                                    
                                    if major_plus or major_minus:
                                        details = []
                                        if major_plus:  details.append(f"プラス乖離: {', '.join(major_plus)}")
                                        if major_minus: details.append(f"マイナス乖離: {', '.join(major_minus)}")
                                        st.write(f"【乖離5pt以上の項目】: {'; '.join(details)}")
                                    else:
                                        st.write("この部門において、特に極端なメーカー偏重は見られず、全国平均に近いバランス構成です。")







            # =========================================================
            # 🔥 タブ10からも呼び出せるように外側に定義
            # =========================================================
            def calculate_shindai_analysis(shindai_df, neighbor_df, target_kind, target_unit):
                import numpy as np
                import pandas as pd

                if shindai_df is None or neighbor_df.empty:
                    return None

                df_copy = shindai_df.copy()
                if not pd.api.types.is_datetime64_any_dtype(df_copy["導入月"]):
                    df_copy["導入月"] = pd.to_datetime(df_copy["導入月"], errors='coerce')

                neighbor_ids = neighbor_df["店舗ID"].unique().tolist()
                view_df = df_copy[df_copy["店舗ID"].isin(neighbor_ids)].copy()
                if view_df.empty:
                    return None

                # 表示軸の補正
                if target_unit == "月次":
                    view_df["表示軸"] = view_df["導入月"].dt.strftime('%Y/%m')
                else:
                    view_df["半年"] = view_df["導入月"].apply(lambda x: f"{x.year}H1" if x.month <= 6 else f"{x.year}H2")
                    view_df["表示軸"] = view_df["半年"]

                # 集計
                agg_df = view_df.groupby(["店舗ID", "表示軸", "種別"]).agg({"導入台数": "sum", "分母台数": "mean"}).reset_index()

                if target_kind == "店舗全体":
                    plot_df = agg_df[agg_df["種別"].isin(["パチンコ", "スロット"])].groupby(["店舗ID", "表示軸"]).agg({"導入台数": "sum", "分母台数": "sum"}).reset_index()
                    plot_df["種別"] = "店舗全体"
                else:
                    plot_df = agg_df[agg_df["種別"] == target_kind].copy()

                if plot_df.empty:
                    return None

                plot_df["比率"] = np.where(plot_df["分母台数"] > 0, plot_df["導入台数"] / plot_df["分母台数"], 0)
                shop_info = neighbor_df[["店舗ID", "店舗名", "distance"]].drop_duplicates("店舗ID")
                plot_df = pd.merge(plot_df, shop_info, on="店舗ID", how="inner")

                ordered_shop_names = shop_info.sort_values("distance")["店舗名"].tolist()
                self_shop_name = ordered_shop_names[0] if ordered_shop_names else ""
                all_axes_asc = sorted(plot_df["表示軸"].unique())
                if not all_axes_asc: return None
                latest_axis = all_axes_asc[-1]

                latest_data = plot_df[plot_df["表示軸"] == latest_axis].copy()
                if latest_data.empty:
                    return None

                area_avg_qty = latest_data["導入台数"].mean()
                area_avg_ratio = latest_data["導入台数"].sum() / latest_data["分母台数"].sum() if latest_data["分母台数"].sum() > 0 else 0

                latest_data["qty_rank"] = latest_data["導入台数"].rank(ascending=False, method='min').astype(int)
                latest_data["ratio_rank"] = latest_data["比率"].rank(ascending=False, method='min').astype(int)
                stats_dict = latest_data.set_index("店舗名").to_dict('index')

                shop_analysis_results = {}
                for sname in ordered_shop_names:
                    s_info = stats_dict.get(sname, {"比率": 0, "導入台数": 0, "qty_rank": 0, "ratio_rank": 0})
                    s_qty, s_ratio = s_info["導入台数"], s_info["比率"]
                    q_rank, r_rank = s_info["qty_rank"], s_info["ratio_rank"]

                    if s_qty >= area_avg_qty * 3.0:
                        status, base_msg = "🏛️ エリア独占型", "エリア平均を圧倒する導入。物量の力で商圏シェアを強制奪取する戦略です。"
                    elif s_qty >= area_avg_qty * 1.8:
                        status, base_msg = "⚔️ 積極攻勢型", "平均を大きく引き離す物量。競合の客を吸い出す攻撃的姿勢が鮮明です。"
                    elif s_qty >= area_avg_qty * 1.1:
                        status, base_msg = "⚖️ 先行優位型", "平均を上回る台数を確保し、エリア内の鮮度順位を高く維持しています。"
                    elif s_qty >= area_avg_qty * 0.7:
                        status, base_msg = "⚖️ 市場追従型", "エリア平均に歩調を合わせた導入。決定的な差をつけられない均衡戦略です。"
                    elif s_qty > 0:
                        status, base_msg = "🎯 少数精鋭型", "台数を絞り、特定機種のファンを確実に囲い込む効率重視の戦法です。"
                    else:
                        status, base_msg = "💤 導入見送り", "今期は導入なし。次回の大型版権への備えか、回収期と推察されます。"

                    sub_msg = ""
                    if s_qty > area_avg_qty and s_ratio < area_avg_ratio:
                        sub_msg = "  \n> 💡 **大規模店の物量作戦:** 台数はエリア上位ですが、設置規模が大きいため入替率慎重。物量の絶対値で威圧しています。"
                    elif s_qty < area_avg_qty and s_ratio > area_avg_ratio:
                        sub_msg = "  \n> 💡 **高回転ゲリラ戦:** 台数は平均以下ですが、入替比率は高水準。少ない台数で店内の鮮度を演出しています。"

                    shop_trend_text = f"【店舗傾向:{sname}】\n{base_msg}"
                    shop_hint_text = f"💡 戦略へのヒント: {sub_msg.replace('> ', '').strip() if sub_msg else '現在のバランスを維持し、主要機種のエリア順位を上げる検討を行ってください。'}"

                    shop_analysis_results[sname] = {
                        "status": status,
                        "qty_rank": q_rank,
                        "ratio_rank": r_rank,
                        "導入台数": f"{int(s_qty)}台",
                        "導入比率": f"{s_ratio:.1%}",
                        "trend_analysis": shop_trend_text,
                        "strategy_hint": shop_hint_text
                    }

                # ★修正:市場環境アセスメントの文字列を生成して追加
                coef = 6.0 if target_unit == "半年" else 1.0
                if area_avg_qty >= 25 * coef:
                    market_assessment = "💣 【極限激戦:物量飽和市場】"
                    assessment_detail = f"平均 {area_avg_qty:.1f}台。特定法人の過剰投資がエリア全体のコスト基準を破壊しており、消耗戦が避けられない状態です。"
                elif area_avg_qty >= 15 * coef:
                    market_assessment = "⚠️ 【激戦:先行投資市場】"
                    assessment_detail = f"平均 {area_avg_qty:.1f}台。話題機への大量導入が必須化しており、新台集客への依存度が非常に高い環境です。"
                elif area_avg_qty >= 10 * coef:
                    market_assessment = "🔔 【活発:トレンド市場】"
                    assessment_detail = f"平均 {area_avg_qty:.1f}台。標準的な鮮度維持が前提。主力機種の入れ替えで客数が大きく変動する、動きのある市場です。"
                elif area_avg_qty >= 5 * coef:
                    market_assessment = "🍀 【堅実:厳選運用市場】"
                    assessment_detail = f"平均 {area_avg_qty:.1f}台。大量導入によるリスクを避け、ヒット機種を確実に拾う安定志向の店舗が多い傾向です。"
                else:
                    market_assessment = "💎 【省エネ:安定運用市場】"
                    assessment_detail = f"平均 {area_avg_qty:.1f}台。新台の物量による集客が弱く、既存機種の育成や固定客への還元が鍵を握ります。"

                return {
                    "kind": target_kind,
                    "unit": target_unit,
                    "axis": latest_axis,
                    "market_assessment": market_assessment, 
                    "assessment_detail": assessment_detail, 
                    "shop_analyses": shop_analysis_results
                }



            # =========================================================
            # --- Tab 6: 新台導入分析 ---
            # =========================================================

            with tabs["✨ 新台"]:
                @st.fragment
                def render_shindai_tab(shindai_df, neighbor_df):
                    import numpy as np
                    import pandas as pd
                    import plotly.express as px
                    import plotly.graph_objects as go
                    
                    if shindai_df is None:
                        st.error("新台データが読み込まれていません。")
                        return

                    # --- 1. データの前処理 ---
                    shindai_df = shindai_df.copy()
                    if not pd.api.types.is_datetime64_any_dtype(shindai_df["導入月"]):
                        shindai_df["導入月"] = pd.to_datetime(shindai_df["導入月"], errors='coerce')

                    c1, c2 = st.columns(2)
                    with c1:
                        all_kinds = sorted([k for k in shindai_df["種別"].unique() if k != "店舗全体"])
                        selected_kind = st.selectbox("集計種別", ["店舗全体"] + all_kinds, key="kind_tab6_v10")
                    with c2:
                        time_unit = st.radio("集計単位", ["月次", "半年"], horizontal=True, key="unit_tab6_v10")

                    neighbor_ids = neighbor_df["店舗ID"].unique().tolist()
                    view_df = shindai_df[shindai_df["店舗ID"].isin(neighbor_ids)].copy()
                    
                    if view_df.empty:
                        st.warning("選択された商圏内に新台データが存在しません。")
                        return

                    if time_unit == "月次":
                        view_df["表示軸"] = view_df["導入月"].dt.strftime('%Y/%m')
                    else:
                        view_df["半年"] = view_df["導入月"].apply(lambda x: f"{x.year}H1" if x.month <= 6 else f"{x.year}H2")
                        view_df["表示軸"] = view_df["半年"]

                    # --- 2. データの集計 ---
                    agg_df = view_df.groupby(["店舗ID", "表示軸", "種別"]).agg({"導入台数": "sum", "分母台数": "mean"}).reset_index()

                    if selected_kind == "店舗全体":
                        plot_df = agg_df[agg_df["種別"].isin(["パチンコ", "スロット"])].groupby(["店舗ID", "表示軸"]).agg({"導入台数": "sum", "分母台数": "sum"}).reset_index()
                        plot_df["種別"] = "店舗全体"
                    else:
                        plot_df = agg_df[agg_df["種別"] == selected_kind].copy()

                    plot_df["比率"] = np.where(plot_df["分母台数"] > 0, plot_df["導入台数"] / plot_df["分母台数"], 0)
                    shop_info = neighbor_df[["店舗ID", "店舗名", "distance"]].drop_duplicates("店舗ID")
                    plot_df = pd.merge(plot_df, shop_info, on="店舗ID", how="inner")

                    ordered_shop_names = shop_info.sort_values("distance")["店舗名"].tolist()
                    self_shop_name = ordered_shop_names[0] if ordered_shop_names else ""
                    all_axes_asc = sorted(plot_df["表示軸"].unique())
                    all_axes_desc = all_axes_asc[::-1]
                    if not all_axes_asc: return
                    latest_axis = all_axes_asc[-1]

                    # --- 3. 【順序1】導入台数テーブル ---
                    st.write(f"### 📊 {selected_kind} 導入台数実績")
                    pivot_count = plot_df.pivot_table(index="店舗名", columns="表示軸", values="導入台数", aggfunc="sum", fill_value=0).reindex(index=ordered_shop_names, columns=all_axes_desc, fill_value=0)
                    area_qty_mean_series = pivot_count.mean(axis=0).round(1)
                    area_qty_mean_row = area_qty_mean_series.to_frame(name="🚩 エリア平均").T
                    st.dataframe(pd.concat([area_qty_mean_row, pivot_count]), use_container_width=True)

                    # --- 4. 【順序2】導入台数グラフ ---
                    st.write(f"### 📈 {selected_kind} 導入台数推移グラフ")
                    fig = go.Figure()

                    fig.add_trace(go.Scatter(
                        x=all_axes_asc, y=[area_qty_mean_series.get(ax, 0) for ax in all_axes_asc],
                        mode='lines+markers', name='🚩 エリア平均',
                        line=dict(color='red', width=4, dash='dot'),
                        marker=dict(size=10)
                    ))

                    for sname in ordered_shop_names:
                        s_data = plot_df[plot_df["店舗名"] == sname].set_index("表示軸").reindex(all_axes_asc).fillna(0)
                        is_self = (sname == self_shop_name)
                        
                        fig.add_trace(go.Scatter(
                            x=all_axes_asc, y=s_data["導入台数"],
                            mode='lines+markers', name=f"{sname}{' (★)' if is_self else ''}",
                            line=dict(width=5 if is_self else 1.5, color='#1f77b4' if is_self else None),
                            opacity=1.0 if is_self else 0.6
                        ))

                    fig.update_layout(
                        yaxis_title="導入台数 (台)", hovermode="x unified",
                        legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1), height=500
                    )
                    st.plotly_chart(fig, use_container_width=True)

                    # --- 5. 【順序3】導入比率テーブル ---
                    st.write(f"### 📉 {selected_kind} 導入比率推移(%)")
                    pivot_ratio = plot_df.pivot_table(index="店舗名", columns="表示軸", values="比率", aggfunc="mean", fill_value=0).reindex(index=ordered_shop_names, columns=all_axes_desc, fill_value=0)
                    area_ratio_mean_row = pivot_ratio.mean(axis=0).to_frame(name="🚩 エリア平均").T
                    st.dataframe(pd.concat([area_ratio_mean_row, pivot_ratio]).style.format("{:.1%}", na_rep="-"), use_container_width=True)

                    # --- 6. 市場アセスメント ---
                    st.write("---")
                    latest_data = plot_df[plot_df["表示軸"] == latest_axis].copy()
                    
                    if not latest_data.empty:
                        area_avg_qty = latest_data["導入台数"].mean()
                        area_avg_ratio = latest_data["導入台数"].sum() / latest_data["分母台数"].sum() if latest_data["分母台数"].sum() > 0 else 0
                        coef = 6.0 if time_unit == "半年" else 1.0
                        
                        st.markdown(f"#### 📊 市場環境アセスメント ({latest_axis})")
                        
                        if area_avg_qty >= 25 * coef:
                            st.error(f"💣 **【極限激戦:物量飽和市場】** 平均 **{area_avg_qty:.1f}台**。特定法人の過剰投資がエリア全体のコスト基準を破壊しており、消耗戦が避けられない状態です。")
                        elif area_avg_qty >= 15 * coef:
                            st.error(f"⚠️ **【激戦:先行投資市場】** 平均 **{area_avg_qty:.1f}台**。話題機への大量導入が必須化しており、新台集客への依存度が非常に高い環境です。")
                        elif area_avg_qty >= 10 * coef:
                            st.warning(f"🔔 **【活発:トレンド市場】** 平均 **{area_avg_qty:.1f}台**。標準的な鮮度維持が前提。主力機種の入れ替えで客数が大きく変動する、動きのある市場です。")
                        elif area_avg_qty >= 5 * coef:
                            st.info(f"🍀 **【堅実:厳選運用市場】** 平均 **{area_avg_qty:.1f}台**。大量導入によるリスクを避け、ヒット機種を確実に拾う安定志向の店舗が多い傾向です。")
                        else:
                            st.success(f"💎 **【省エネ:安定運用市場】** 平均 **{area_avg_qty:.1f}台**。新台の物量による集客が弱く、既存機種の育成や固定客への還元が鍵を握ります。")

                        # --- 7. 店舗別詳細分析 ---
                        st.write("---")
                        st.markdown(f"🤖 **導入戦略詳細分析(台数優先)**")
                        latest_data["qty_rank"] = latest_data["導入台数"].rank(ascending=False, method='min').astype(int)
                        latest_data["ratio_rank"] = latest_data["比率"].rank(ascending=False, method='min').astype(int)
                        stats_dict = latest_data.set_index("店舗名").to_dict('index')

                        # 💡 全店舗の「構成分析・戦略ヒント」を溜め込むための辞書を初期化
                        shop_analysis_results = {}

                        for sname in ordered_shop_names:
                            s_info = stats_dict.get(sname, {"比率": 0, "導入台数": 0, "qty_rank": 0, "ratio_rank": 0})
                            s_qty, s_ratio = s_info["導入台数"], s_info["比率"]
                            q_rank, r_rank = s_info["qty_rank"], s_info["ratio_rank"]
                            is_self = " (★自店)" if sname == self_shop_name else ""

                            if s_qty >= area_avg_qty * 3.0:
                                status, base_msg = "🏛️ エリア独占型", "エリア平均を圧倒する導入。物量の力で商圏シェアを強制奪取する戦略です。"
                            elif s_qty >= area_avg_qty * 1.8:
                                status, base_msg = "⚔️ 積極攻勢型", "平均を大きく引き離す物量。競合の客を吸い出す攻撃的姿勢が鮮明です。"
                            elif s_qty >= area_avg_qty * 1.1:
                                status, base_msg = "⚖️ 先行優位型", "平均を上回る台数を確保し、エリア内の鮮度順位を高く維持しています。"
                            elif s_qty >= area_avg_qty * 0.7:
                                status, base_msg = "⚖️ 市場追従型", "エリア平均に歩調を合わせた導入。決定的な差をつけられない均衡戦略です。"
                            elif s_qty > 0:
                                status, base_msg = "🎯 少数精鋭型", "台数を絞り、特定機種のファンを確実に囲い込む効率重視の戦法です。"
                            else:
                                status, base_msg = "💤 導入見送り", "今期は導入なし。次回の大型版権への備えか、回収期と推察されます。"

                            sub_msg = ""
                            if s_qty > area_avg_qty and s_ratio < area_avg_ratio:
                                sub_msg = "  \n> 💡 **大規模店の物量作戦:** 台数はエリア上位ですが、設置規模が大きいため入替率は慎重。物量の絶対値で威圧しています。"
                            elif s_qty < area_avg_qty and s_ratio > area_avg_ratio:
                                sub_msg = "  \n> 💡 **高回転ゲリラ戦:** 台数は平均以下ですが、入替比率は高水準。少ない台数で店内の鮮度を演出しています。"

                            # 💡 【重要】店舗別の傾向分析テキストを合成
                            # (※もし「ハイスペック機を…」等の動的テキストを保持する独自の変数があれば、ここをその変数に置き換えてください)
                            shop_trend_text = f"【店舗傾向:{sname}】\n{base_msg}"
                            shop_hint_text = f"💡 戦略へのヒント: {sub_msg.replace('> ', '').strip() if sub_msg else '現在のバランスを維持し、主要機種のエリア順位を上げる検討を行ってください。'}"

                            # 💡 辞書に店舗名キーで情報を格納(複数店舗分がすべて保存されます)
                            shop_analysis_results[sname] = {
                                "status": status,
                                "qty_rank": q_rank,
                                "ratio_rank": r_rank,
                                "導入台数": f"{int(s_qty)}台",
                                "導入比率": f"{s_ratio:.1%}",
                                "trend_analysis": shop_trend_text,
                                "strategy_hint": shop_hint_text
                            }

                            with st.expander(f"📍 {sname}{is_self} - {status} (台数{q_rank}位)"):
                                st.markdown(f"#### {base_msg}")
                                if sub_msg: st.markdown(sub_msg)
                                c_a, c_b = st.columns(2)
                                with c_a:
                                    st.metric("導入台数", f"{int(s_qty)}台", f"{s_qty - area_avg_qty:+.1f}台 (平均差)")
                                    st.write(f"エリア台数順位: **{q_rank}位** / {len(ordered_shop_names)}店")
                                with c_b:
                                    st.metric("導入比率", f"{s_ratio:.1%}", f"{s_ratio - area_avg_ratio:+.1%} (平均差)")
                                    st.write(f"エリア比率順位: **{r_rank}位** / {len(ordered_shop_names)}店")


                # --- 🔥 バックグラウンドで全6パターンを一発自動事前計算 ---
                shindai_data_raw = raw_dfs.get("新台データ")
                if shindai_data_raw is not None and not neighbor_df.empty:
                    target_shop_id = str(selected_shop_id).strip()
                    if "tab6_results" not in st.session_state:
                        st.session_state.tab6_results = {}
                    if target_shop_id not in st.session_state.tab6_results:
                        st.session_state.tab6_results[target_shop_id] = {}

                    # ループを回して全6パターンを強制計算し、セッションに格納
                    for k in ["店舗全体", "パチンコ", "スロット"]:
                        for u in ["月次", "半年"]:
                            pkey = f"{k}_{u}"
                            calc_data = calculate_shindai_analysis(shindai_data_raw, neighbor_df, k, u)
                            if calc_data:
                                st.session_state.tab6_results[target_shop_id][pkey] = calc_data

                # タブの描画実行
                render_shindai_tab(raw_dfs.get("新台データ"), neighbor_df)



            # =========================================================
            # --- 📱 タブ7: スマート遊技機分析 ---
            # =========================================================
            with tabs["📱 スマート機"]:
                st.subheader("📱 スマート遊技機(スマスロ・スマパチ)普及状況分析")

                if "processed_df" in st.session_state:
                    full_df = st.session_state.processed_df

                    # サブタブの構成
                    sub_tab_labels = ["🌏 全体", "🎰 パチンコ全体", "🎰 スロット全体", "🔴 通常P", "🟢 低貸P", "🔵 通常S", "🟡 低貸S"]
                    sub_tabs_smart = st.tabs(sub_tab_labels)
                    
                    categories_smart = {
                        "🌏 全体": "全体", "🎰 パチンコ全体": "P全体", "🎰 スロット全体": "S全体",
                        "🔴 通常P": "通常P", "🟢 低貸P": "低貸P", "🔵 通常S": "通常S", "🟡 低貸S": "低貸S"
                    }

                    # 都道府県名マップ
                    pref_map = {1:"北海道", 2:"青森県", 3:"岩手県", 4:"宮城県", 5:"秋田県", 6:"山形県", 7:"福島県", 8:"茨城県", 9:"栃木県", 10:"群馬県", 11:"埼玉県", 12:"千葉県", 13:"東京都", 14:"神奈川県", 15:"新潟県", 16:"富山県", 17:"石川県", 18:"福井県", 19:"山梨県", 20:"長野県", 21:"岐阜県", 22:"静岡県", 23:"愛知県", 24:"三重県", 25:"滋賀県", 26:"京都府", 27:"大阪府", 28:"兵庫県", 29:"奈良県", 30:"和歌山県", 31:"鳥取県", 32:"島根県", 33:"岡山県", 34:"広島県", 35:"山口県", 36:"徳島県", 37:"香川県", 38:"愛媛県", 39:"高知県", 40:"福岡県", 41:"佐賀県", 42:"長崎県", 43:"熊本県", 44:"大分県", 45:"宮崎県", 46:"鹿児島県", 47:"沖縄県"}

                    for i, label in enumerate(sub_tab_labels):
                        with sub_tabs_smart[i]:
                            dept_key = categories_smart[label]

                            # 1. データのフィルタリング(エラー回避・安全版)
                            if full_df is None or full_df.empty:
                                df_target = pd.DataFrame(columns=full_df.columns if full_df is not None else [])
                            elif dept_key == "全体":
                                df_target = full_df.copy()
                            elif dept_key == "P全体":
                                if "区分ID" in full_df.columns:
                                    mask = full_df["区分ID"].fillna("").astype(str).str.startswith("1")
                                    df_target = full_df[mask].copy()
                                else:
                                    df_target = pd.DataFrame(columns=full_df.columns)
                            elif dept_key == "S全体":
                                if "区分ID" in full_df.columns:
                                    mask = full_df["区分ID"].fillna("").astype(str).str.startswith("2")
                                    full_df[mask].copy()
                                    df_target = full_df[mask].copy()
                                else:
                                    df_target = pd.DataFrame(columns=full_df.columns)
                            else:
                                if "貸玉区分" in full_df.columns:
                                    df_target = full_df[full_df["貸玉区分"] == dept_key].copy()
                                else:
                                    df_target = pd.DataFrame(columns=full_df.columns)

                            # ターゲットデータが空、または必要な列が無ければスキップ
                            if df_target.empty:
                                st.info(f"{label} のデータがありません。")
                                continue

                            # 2. 平均・エリアデータの抽出
                            if "店舗ID" in df_target.columns:
                                df_area = df_target[df_target["店舗ID"].isin(area_shop_ids)]
                            else:
                                df_area = pd.DataFrame(columns=df_target.columns)
                            
                            pref_label = "🗺️ 都道府県平均"
                            df_pref = pd.DataFrame()
                            if "都道府県ID" in df_target.columns and "店舗ID" in df_target.columns:
                                my_shop_data = df_target[df_target["店舗ID"].astype(str) == str(selected_shop_id_str)]
                                if not my_shop_data.empty:
                                    p_code = my_shop_data["都道府県ID"].iloc[0]
                                    try:
                                        p_name = pref_map.get(int(float(p_code)), "都道府県")
                                        pref_label = f"🗾 {p_name}平均"
                                    except: pass
                                    df_pref = df_target[df_target["都道府県ID"] == p_code]

                            # 3. 集計
                            def get_smart_metrics(df_src, label_name):
                                if df_src is None or df_src.empty: return None
                                n_shops = df_src["店舗ID"].nunique()
                                if n_shops == 0: return None
                                smart_sum = df_src[df_src["機体区分"] == "スマート機"]["設置台数"].sum()
                                total_sum = df_src["設置台数"].sum()
                                return pd.Series({
                                    "総設置台数": total_sum / n_shops,
                                    "スマート機台数": smart_sum / n_shops,
                                    "スマート比率": (smart_sum / total_sum * 100) if total_sum > 0 else 0
                                }, name=label_name)

                            all_rows = []
                            avg_data = []
                            
                            # 各平均行の取得
                            national_row = get_smart_metrics(df_target, "🌏 全国平均")
                            pref_row = get_smart_metrics(df_pref, pref_label)
                            area_row = get_smart_metrics(df_area, "🏘️ エリア平均")

                            # リストに追加(テーブル表示用)
                            for r in [national_row, pref_row, area_row]:
                                if r is not None:
                                    all_rows.append(r)
                                    avg_data.append(r)

                            # エリア平均の値を保持(後続の判定用)
                            area_avg_smart = 0
                            area_avg_ratio = 0
                            if area_row is not None:
                                area_avg_smart = area_row["スマート機台数"]
                                area_avg_ratio = area_row["スマート比率"]

                            # 店舗別データ
                            if not df_area.empty:
                                pivot = df_area.groupby(["店舗ID", "機体区分"])["設置台数"].sum().unstack(fill_value=0)
                                if "スマート機" not in pivot.columns: pivot["スマート機"] = 0
                                
                                for sid in area_shop_ids:
                                    if sid in pivot.index:
                                        s_name = name_map.get(sid, sid)
                                        row_name = f"★自店: {s_name}" if str(sid) == str(selected_shop_id_str) else s_name
                                        s_smart = pivot.loc[sid, "スマート機"]
                                        s_total = pivot.loc[sid].sum()
                                        all_rows.append(pd.Series({
                                            "総設置台数": float(s_total),
                                            "スマート機台数": float(s_smart),
                                            "スマート比率": (s_smart / s_total * 100) if s_total > 0 else 0
                                        }, name=row_name))

                            # 4. 表示用のスタイル適用
                            if all_rows:
                                # 一旦すべてをデータフレーム化
                                df_smart_table = pd.concat(all_rows, axis=1).T
                                
                                # --- 表示フォーマットの動的生成 ---
                                # 平均行(インデックスに絵文字が含まれるもの)と店舗行を判別
                                formatted_data = df_smart_table.copy()
                                
                                for idx in formatted_data.index:
                                    is_avg = any(symbol in str(idx) for symbol in ["🌏", "🗾", "🏘️"])
                                    if is_avg:
                                        # 平均行は小数点1位まで
                                        formatted_data.loc[idx, "総設置台数_disp"] = f"{df_smart_table.loc[idx, '総設置台数']:.1f}台"
                                        formatted_data.loc[idx, "スマート機台数_disp"] = f"{df_smart_table.loc[idx, 'スマート機台数']:.1f}台"
                                    else:
                                        # 店舗行は整数表示
                                        formatted_data.loc[idx, "総設置台数_disp"] = f"{int(round(df_smart_table.loc[idx, '総設置台数'])):d}台"
                                        formatted_data.loc[idx, "スマート機台数_disp"] = f"{int(round(df_smart_table.loc[idx, 'スマート機台数'])):d}台"

                                # 表示用カラムの入れ替え
                                df_disp = df_smart_table.copy()
                                df_disp["総設置台数"] = formatted_data["総設置台数_disp"]
                                df_disp["スマート機台数"] = formatted_data["スマート機台数_disp"]

                                def style_smart_table(res_df):
                                    styles = pd.DataFrame('', index=res_df.index, columns=res_df.columns)
                                    for idx in res_df.index:
                                        # 太字判定(数値の入った元の df_smart_table で比較)
                                        if df_smart_table.loc[idx, "スマート機台数"] > area_avg_smart:
                                            styles.loc[idx, "スマート機台数"] += "font-weight: bold;"
                                        if df_smart_table.loc[idx, "スマート比率"] > area_avg_ratio:
                                            styles.loc[idx, "スマート比率"] += "font-weight: bold;"
                                        
                                        # 背景色設定
                                        if any(symbol in str(idx) for symbol in ["🌏", "🗾", "🏘️"]):
                                            styles.loc[idx, :] += "background-color: #f0f2f6;"
                                        if "★自店" in str(idx):
                                            styles.loc[idx, :] += "background-color: #fff3cd;"
                                    return styles

                                st.markdown(f"#### 📋 スマート遊技機 設置状況一覧 ({label})")
                                
                                st.dataframe(
                                    df_disp.style.apply(style_smart_table, axis=None)
                                    .format({"スマート比率": "{:.1f}%"}), # 比率のみ一括指定
                                    use_container_width=True,
                                    column_config={
                                        "総設置台数": st.column_config.TextColumn("総設置台数", width=80), # 文字列化したのでTextColumn
                                        "スマート機台数": st.column_config.TextColumn("スマート機台数", width=80),
                                        "スマート比率": st.column_config.ProgressColumn("スマート比率", format="%.1f%%", min_value=0, max_value=100, width=200)
                                    }
                                )



                            # --- 4. 市場アセスメント ---
                            st.write("---")
                            st.markdown(f"#### 📊 スマート機普及アセスメント ({label})")
                    
                            def get_val(row, key):
                                if row is None or key not in row: return 0
                                return row[key]

                            nat_ratio = get_val(national_row, "スマート比率")
                            pref_ratio = get_val(pref_row, "スマート比率")
                    
                            diff_nat = area_avg_ratio - nat_ratio
                            diff_pref = area_avg_ratio - pref_ratio
                            eval_msg = f"エリア平均 **{area_avg_ratio:.1f}%**(全国差 {diff_nat:+.1f}% / 県差 {diff_pref:+.1f}%)"
                    
                            # ★エリア評価を先に確定させる
                            if area_avg_ratio > nat_ratio + 10:
                                area_status, area_msg = "🚀 【市場牽引:最先端エリア】", "全国平均を大きく上回るスピードでスマート化が進行中。"
                                st.error(f"{area_status} {eval_msg}  \n{area_msg}")
                            elif area_avg_ratio > nat_ratio:
                                area_status, area_msg = "⚠️ 【先行導入:高感度エリア】", "全国水準をリード。"
                                st.warning(f"{area_status} {eval_msg}  \n{area_msg}")
                            elif area_avg_ratio >= nat_ratio - 5:
                                area_status, area_msg = "🔔 【標準移行:平均的エリア】", "全国平均並みの進捗。"
                                st.info(f"{area_status} {eval_msg}  \n{area_msg}")
                            else:
                                area_status, area_msg = "💎 【独自運用:慎重派エリア】", "全国的に見てスマート化が緩やか。"
                                st.success(f"{area_status} {eval_msg}  \n{area_msg}")

                            # --- 6. 店舗別詳細分析 (順位付け) ---
                            st.write("---")
                            st.markdown(f"🤖 **スマート機導入戦略分析**")
                            
                            # 店舗のみを抽出して順位計算
                            df_only_shops = df_smart_table[~df_smart_table.index.str.contains("🌏|🗾|🏘️")].copy()
                            df_only_shops["qty_rank"] = df_only_shops["スマート機台数"].rank(ascending=False, method='min').astype(int)
                            df_only_shops["ratio_rank"] = df_only_shops["スマート比率"].rank(ascending=False, method='min').astype(int)
                            
                            num_shops = len(df_only_shops)

                            # エリア全体でスマート機が導入されているかチェック(ゼロ除算・判定エラー回避)
                            has_smart_in_area = area_avg_ratio > 0
                          
                            # ---- 💡 【タブ10連携用】初期化 ----
                            if "tab7_results" not in st.session_state:
                                st.session_state.tab7_results = {}
                            
                            target_shop_id = str(selected_shop_id_str).strip()
                            if target_shop_id not in st.session_state.tab7_results:
                                st.session_state.tab7_results[target_shop_id] = {}
  
                            for sname in df_only_shops.index:
                                s_info = df_only_shops.loc[sname]
                                s_qty = s_info["スマート機台数"]
                                s_ratio = s_info["スマート比率"]
                                q_rank = int(s_info["qty_rank"])
                                r_rank = int(s_info["ratio_rank"])
                                
                                # 戦略判定ロジック
                                if not has_smart_in_area:
                                    status, base_msg = "⚪ 未導入エリア", "エリア全体でスマート機の導入が確認されません。今後の動向に注目です。"
                                elif s_ratio >= area_avg_ratio * 1.5:
                                    status, base_msg = "⚡ スマート特化型", "エリア平均を大きく上回る比率。次世代機への投資を最優先し、最新設備で差別化を図る戦略です。"
                                elif s_qty >= area_avg_smart * 1.5:
                                    status, base_msg = "🏛️ 物量制圧型", "圧倒的な設置台数。エリア内のスマート機ユーザーを根こそぎ取り込む、規模のメリットを活かした戦略です。"
                                elif s_ratio >= area_avg_ratio * 1.1:
                                    status, base_msg = "⚔️ 先進導入型", "平均以上にスマート機を重視。トレンドに敏感な層をターゲットにした、攻めの構成です。"
                                elif s_ratio >= area_avg_ratio * 0.8:
                                    status, base_msg = "⚖️ 市場均衡型", "エリアの普及ペースに合わせたバランス重視の構成。リスクを抑えつつ鮮度を維持しています。"
                                elif s_qty > 0:
                                    status, base_msg = "🎯 ポイント投資型", "台数は絞りつつも、主要な人気機種のみをピンポイントで導入する効率運用です。"
                                else:
                                    status, base_msg = "💤 従来機固執型", "スマート機の導入が極めて限定的。あえて従来機のファン層に特化している、もしくは投資待機状態です。"


                                # 処理中の店舗が「★自店」または選択された対象店舗名の場合のみ保存
                                is_target = "★自店" in str(sname) or str(selected_shop_id_str) in str(sname)
                                if is_target:
                                    # 補足キャプションの取得
                                    caption_msg = ""
                                    if s_qty > area_avg_smart and s_ratio < area_avg_ratio:
                                        caption_msg = "設置台数(絶対数)は多いですが、店舗全体の規模が大きいため比率は控えめに見えます。地域最大の「スマート機コーナー」を形成している可能性が高いです。"
                                    elif s_qty < area_avg_smart and s_ratio > area_avg_ratio:
                                        caption_msg = "台数自体は平均以下ですが、設置規模に対してスマート機の割合が高い「スマート機密度」の高い店舗です。"
                                    
                                    # サブタブ名(label = "🌏 全体" など)をキーにして対象店舗のデータだけを保存
                                    st.session_state.tab7_results[target_shop_id][label] = {
                                        "label": label,
                                        "status": status,
                                        "base_msg": base_msg,
                                        "caption_msg": caption_msg,
                                        "s_qty": int(round(s_qty)),
                                        "s_ratio": s_ratio,
                                        "q_rank": q_rank,
                                        "r_rank": r_rank,
                                        "num_shops": num_shops,
                                        "diff_qty": s_qty - area_avg_smart,
                                        "diff_ratio": s_ratio - area_avg_ratio,
                                        "area_status": area_status,
                                        "area_msg": area_msg     
                                    }

                                with st.expander(f"📍 {sname} - {status} (台数{q_rank}位)"):
                                    st.markdown(f"#### {base_msg}")
                                    
                                    if s_qty > area_avg_smart and s_ratio < area_avg_ratio:
                                        st.caption("💡 **大規模店の戦略:** 設置台数(絶対数)は多いですが、店舗全体の規模が大きいため比率は控えめに見えます。地域最大の「スマート機コーナー」を形成している可能性が高いです。")
                                    elif s_qty < area_avg_smart and s_ratio > area_avg_ratio:
                                        st.caption("💡 **高密度移行戦略:** 台数自体は平均以下ですが、設置規模に対してスマート機の割合が高い「スマート機密度」の高い店舗です。")

                                    c_a, c_b = st.columns(2)
                                    with c_a:
                                        st.metric("スマート機台数", f"{int(round(s_qty))}台", f"{s_qty - area_avg_smart:+.1f}台 (平均差)")
                                        st.write(f"エリア台数順位: **{q_rank}位** / {num_shops}店")
                                    with c_b:
                                        st.metric("スマート比率", f"{s_ratio:,.1f}%", f"{s_ratio - area_avg_ratio:+.1f}% (平均差)")
                                        st.write(f"エリア比率順位: **{r_rank}位** / {num_shops}店")



 
            # =========================================================
            # --- 🚀 [共通処理] タブ9・タブ10で使うデータを事前に一括計算 ---
            # =========================================================
            try:
                # 1. データの準備(一括処理)
                if "processed_df" not in st.session_state:
                    st.session_state.processed_df = pd.read_parquet("processed_analysis_data.parquet")
                
                df_val = st.session_state.processed_df.copy()
                
                # 数値変換と文字列変換を一括実行
                df_val["中古単価_num"] = pd.to_numeric(df_val["中古単価"], errors='coerce').fillna(0)
                df_val["設置台数"] = pd.to_numeric(df_val["設置台数"], errors='coerce').fillna(0)
                df_val["資産総額"] = df_val["中古単価_num"] * df_val["設置台数"]
                df_val["店舗ID"] = df_val["店舗ID"].astype(str)
                selected_shop_id_str = str(selected_shop_id)

                # カテゴリマップ(集計用)
                cat_map = {
                    "全体": ["通常P", "低貸P", "通常S", "低貸S"],
                    "パチンコ通常": ["通常P"],
                    "パチンコ低貸": ["低貸P"],
                    "スロット通常": ["通常S"],
                    "スロット低貸": ["低貸S"]
                }

                # 全店舗×貸玉区分の集計テーブル
                shop_cat_summary = df_val.groupby(["店舗ID", "貸玉区分"]).agg({
                    "資産総額": "sum",
                    "設置台数": "sum"
                }).reset_index()

                def get_unit_row_fast(filtered_df, label_name):
                    res = {"店舗名": label_name}
                    for label, cat_list in cat_map.items():
                        target = filtered_df[filtered_df["貸玉区分"].isin(cat_list)]
                        t_asset = target["資産総額"].sum()
                        t_qty = target["設置台数"].sum()
                        res[label] = t_asset / t_qty if t_qty > 0 else 0
                    return res

                # 全国平均
                national_row = get_unit_row_fast(shop_cat_summary, "🌏 全国平均")
                
                # 都道府県平均
                pref_row = None
                actual_p_col = next((c for c in df_val.columns if any(k in c for k in ["都道府県", "県名", "Addr1"])), None)
                if actual_p_col:
                    my_pref_val = df_val.loc[df_val["店舗ID"] == selected_shop_id_str, actual_p_col].unique()
                    if len(my_pref_val) > 0:
                        my_pref_val = my_pref_val[0]
                        pref_map = {1:"北海道", 2:"青森県", 3:"岩手県", 4:"宮城県", 5:"秋田県", 6:"山形県", 7:"福島県", 8:"茨城県", 9:"栃木県", 10:"群馬県", 11:"埼玉県", 12:"千葉県", 13:"東京都", 14:"神奈川県", 15:"新潟県", 16:"富山県", 17:"石川県", 18:"福井県", 19:"山梨県", 20:"長野県", 21:"岐阜県", 22:"静岡県", 23:"愛知県", 24:"三重県", 25:"滋賀県", 26:"京都府", 27:"大阪府", 28:"兵庫県", 29:"奈良県", 30:"和歌山県", 31:"鳥取県", 32:"島根県", 33:"岡山県", 34:"広島県", 35:"山口県", 36:"徳島県", 37:"香川県", 38:"愛媛県", 39:"高知県", 40:"福岡県", 41:"佐賀県", 42:"長崎県", 43:"熊本県", 44:"大分県", 45:"宮崎県", 46:"鹿児島県", 47:"沖縄県"}
                        try:
                            my_pref_name = pref_map.get(int(float(my_pref_val)), my_pref_val)
                        except:
                            my_pref_name = my_pref_val
                        pref_row = get_unit_row_fast(df_val[df_val[actual_p_col] == my_pref_val], f"🗾 {my_pref_name}平均")

                if pref_row is None:
                    pref_row = {**national_row, "店舗名": "🗾 都道府県平均(不明)"}

                # エリア平均
                area_shop_ids = neighbor_df["店舗ID"].astype(str).tolist()
                df_area_machines = df_val[df_val["店舗ID"].isin(area_shop_ids)]
                area_row = get_unit_row_fast(df_area_machines, "🏘️ エリア平均")

                v_area_total = area_row["全体"]
                v_nat_total = national_row["全体"]
                v_pref_total = pref_row["全体"]

                # テキスト生成系関数
                def get_diff_text(current, baseline):
                    diff = current - baseline
                    color = "red" if diff >= 0 else "blue"
                    sign = "+" if diff >= 0 else ""
                    return f":{color}[{sign}{diff:,.0f}円]"

                def get_dept_analysis(current, baseline, name, rank):
                    if baseline == 0: return f"* {name}: データなし"
                    ratio = current / baseline
                    diff_txt = get_diff_text(current, baseline)
                    if ratio > 1.2: status = "**:red[【突出】]** 商圏内で圧倒的な鮮度。集客の目玉。"
                    elif ratio > 1.05: status = "**:red[【優位】]** 平均を上回る投資。安定した競争力。"
                    elif ratio >= 0.95: status = "【標準】 平均的な構成。バランス重視。"
                    elif ratio > 0.7: status = "**:blue[【効率】]** 償却機活用。コストを抑えた運用。"
                    else: status = "**:blue[【低予算】]** 長期設置機メインの構成。"
                    return f"* {name}: ¥{current:,.0f} (**{rank}位** / {diff_txt})  \n  {status}"

                # 順位計算用の一括データフレーム作成
                area_summary = shop_cat_summary[shop_cat_summary["店舗ID"].isin(area_shop_ids)]
                shop_results = []
                self_p_qty = 0
                self_s_qty = 0
                self_vals = {}
                name_map = dict(zip(neighbor_df["店舗ID"].astype(str), neighbor_df["店舗名"]))

                for sid_str in area_shop_ids:
                    sname = name_map.get(sid_str, "不明")
                    shop_df = area_summary[area_summary["店舗ID"] == sid_str]
                    res = get_unit_row_fast(shop_df, sname)
                    res["店舗ID"] = sid_str
                    
                    if sid_str == selected_shop_id_str:
                        res["店舗名"] = f"★自店: {sname}"
                        self_vals = res
                        self_p_qty = shop_df[shop_df["貸玉区分"] == "通常P"]["設置台数"].sum()
                        self_s_qty = shop_df[shop_df["貸玉区分"] == "通常S"]["設置台数"].sum()
                    
                    shop_results.append(res)
                
                df_shops_only = pd.DataFrame(shop_results)
                num_shops = len(df_shops_only)

                rank_dicts = {}
                for col in cat_map.keys():
                    df_shops_only[f"{col}_rank"] = df_shops_only[col].rank(ascending=False, method='min').astype(int)
                    rank_dicts[col] = dict(zip(df_shops_only["店舗ID"], df_shops_only[f"{col}_rank"]))

                best_p_avg = df_shops_only["パチンコ通常"].max()
                best_s_avg = df_shops_only["スロット通常"].max()

                # 💡 修正: globals() ではなく st.session_state を初期化
                st.session_state['shop_analysis_master'] = {}
                shop_vals_dict = {str(item["店舗ID"]): item for item in shop_results}

                for _, target_shop in neighbor_df.iterrows():
                    t_id = str(target_shop["店舗ID"])
                    t_name = target_shop["店舗名"]
                    dist = target_shop["distance"]
                    s_vals = shop_vals_dict.get(t_id)
                    
                    if not s_vals:
                        continue
                        
                    s_total = s_vals["全体"]
                    t_rank = rank_dicts["全体"][t_id]
                    diff_ratio = s_total / v_area_total if v_area_total > 0 else 1

                    if s_total == 0: 
                        status_tag, g_eval = "⚠️ データ無", "データが取得できませんでした"
                    elif diff_ratio > 1.15: 
                        status_tag, g_eval = "🌟 超積極投資", "エリア平均を凌駕する投資で高単価層を狙う戦略"
                    elif diff_ratio > 1.02: 
                        status_tag, g_eval = "📈 積極運用", "鮮度を高く保ち、競合に対し優位性を維持する運用"
                    else: 
                        status_tag, g_eval = "⚖️ 標準/効率運用", "コストを抑え、償却機や中古機を活かす堅実な運用"

                    comments = {
                        "通常P": get_dept_analysis(s_vals["パチンコ通常"], area_row["パチンコ通常"], "🔴 通常パチンコ", rank_dicts["パチンコ通常"][t_id]),
                        "通常S": get_dept_analysis(s_vals["スロット通常"], area_row["スロット通常"], "🟣 通常スロット", rank_dicts["スロット通常"][t_id]),
                        "低貸P": get_dept_analysis(s_vals["パチンコ低貸"], area_row["パチンコ低貸"], "🔵 低貸パチンコ", rank_dicts["パチンコ低貸"][t_id]),
                        "低貸S": get_dept_analysis(s_vals["スロット低貸"], area_row["スロット低貸"], "🟢 低貸スロット", rank_dicts["スロット低貸"][t_id])
                    }

                    # 💡 修正: 生成した辞書を st.session_state へ安全に登録
                    st.session_state['shop_analysis_master'][t_id] = {
                        "店舗名": t_name,
                        "距離": dist,
                        "全体資産価値": s_total,
                        "全体順位": t_rank,
                        "エリア比率": diff_ratio,
                        "ステータスタグ": status_tag,
                        "総合評価": g_eval,
                        "数値データ": s_vals,
                        "部門別コメント": comments
                    }


            except Exception as e:
                st.error(f"データ事前処理エラー: {e}")
                import traceback
                st.sidebar.error(traceback.format_exc())


            # =========================================================
            # --- 🎰 タブ9: 資産価値 ---
            # =========================================================
            with tabs["💰 資産価値"]:
                st.subheader("🏢 店舗別・1台あたり資産価値(平均単価)比較")
                
                try:
                    # 【改善点】全量読み込みをやめ、集計済みマスタと基本データのみを使用
                    # アプリ全体で共有可能なキャッシュ読み込み
                    @st.cache_data
                    def load_summary_data():
                        # 集計済みマスタを読み込み
                        return pd.read_parquet("shop_summary_master.parquet")
                    
                    # 分析用のベースデータ
                    shop_summary = load_summary_data()
                    
                    # 比較用の全国平均などは、shop_summary全体から算出可能
                    # これにより、個別の店舗データ(processed_analysis_data)をタブ9内で読み込む必要がなくなります
                    
                    selected_shop_id_str = str(selected_shop_id)

                    # カテゴリマップ(既存ロジック維持)
                    cat_map = {
                        "全体": ["通常P", "低貸P", "通常S", "低貸S"],
                        "パチンコ通常": ["通常P"],
                        "パチンコ低貸": ["低貸P"],
                        "スロット通常": ["通常S"],
                        "スロット低貸": ["低貸S"]
                    }

                    # --- 🚀 高速集計エンジン (集計済みマスタを使用) ---
                    def get_unit_row_from_summary(summary_df, target_shop_id=None):
                        # 特定店舗または全国(全店舗)のデータをフィルタリング
                        if target_shop_id:
                            df = summary_df[summary_df["店舗ID"] == target_shop_id]
                        else:
                            df = summary_df
                        
                        res = {}
                        for label, cat_list in cat_map.items():
                            target = df[df["貸玉区分"].isin(cat_list)]
                            t_asset = target["資産総額"].sum()
                            t_qty = target["設置台数"].sum()
                            res[label] = t_asset / t_qty if t_qty > 0 else 0
                        return res

                    # 各種平均を算出
                    national_row = get_unit_row_from_summary(shop_summary)
                    national_row["店舗名"] = "🌏 全国平均"
                    
                    # エリア平均(neighbor_dfはメインの処理で取得済みと想定)
                    area_shop_ids = neighbor_df["店舗ID"].astype(str).tolist()
                    area_summary = shop_summary[shop_summary["店舗ID"].isin(area_shop_ids)]
                    area_row = get_unit_row_from_summary(area_summary)
                    area_row["店舗名"] = "🏘️ エリア平均"

                    # --- 🎨 B. フォーマット・コメント関数 (既存仕様維持) ---
                    def get_diff_text(current, baseline):
                        diff = current - baseline
                        color = "red" if diff >= 0 else "blue"
                        sign = "+" if diff >= 0 else ""
                        return f":{color}[{sign}{diff:,.0f}円]"

                    def get_dept_analysis(current, baseline, name, rank):
                        if baseline == 0: return f"* {name}: データなし"
                        ratio = current / baseline
                        diff_txt = get_diff_text(current, baseline)
                        if ratio > 1.2: status = "**:red[【突出】]** 商圏内で圧倒的な鮮度。集客の目玉。"
                        elif ratio > 1.05: status = "**:red[【優位】]** 平均を上回る投資。安定した競争力。"
                        elif ratio >= 0.95: status = "【標準】 平均的な構成。バランス重視。"
                        elif ratio > 0.7: status = "**:blue[【効率】]** 償却機活用。コストを抑えた運用。"
                        else: status = "**:blue[【低予算】]** 長期設置機メインの構成。"
                        return f"* {name}: ¥{current:,.0f} (**{rank}位** / {diff_txt})  \n  {status}"

                    # --- 📊 C. データ準備と順位計算 (高速版) ---
                    # ループ内でのフィルタリングを避け、一括計算
                    area_summary = shop_cat_summary[shop_cat_summary["店舗ID"].isin(area_shop_ids)]
                    
                    shop_results = []
                    self_p_qty = 0
                    self_s_qty = 0
                    self_vals = {}

                    # 店舗名マッピング
                    name_map = dict(zip(neighbor_df["店舗ID"].astype(str), neighbor_df["店舗名"]))

                    for sid_str in area_shop_ids:
                        sname = name_map.get(sid_str, "不明")
                        shop_df = area_summary[area_summary["店舗ID"] == sid_str]
                        res = get_unit_row_fast(shop_df, sname)
                        res["店舗ID"] = sid_str
                        
                        if sid_str == selected_shop_id_str:
                            res["店舗名"] = f"★自店: {sname}"
                            self_vals = res
                            self_p_qty = shop_df[shop_df["貸玉区分"] == "通常P"]["設置台数"].sum()
                            self_s_qty = shop_df[shop_df["貸玉区分"] == "通常S"]["設置台数"].sum()
                        
                        shop_results.append(res)
                    
                    df_shops_only = pd.DataFrame(shop_results)
                    num_shops = len(df_shops_only)

                    rank_dicts = {}
                    for col in cat_map.keys():
                        df_shops_only[f"{col}_rank"] = df_shops_only[col].rank(ascending=False, method='min').astype(int)
                        rank_dicts[col] = dict(zip(df_shops_only["店舗ID"], df_shops_only[f"{col}_rank"]))

                    best_p_avg = df_shops_only["パチンコ通常"].max()
                    best_s_avg = df_shops_only["スロット通常"].max()

                    # --- 📊 D. 資産価値アセスメント (表示部は既存維持) ---
                    st.markdown("---")
                    st.markdown("#### 💎 エリア資産価値アセスメント")
                    
                    v_area_total = area_row["全体"]
                    v_nat_total = national_row["全体"]
                    v_pref_total = pref_row["全体"]
                    
                    diff_nat_txt = get_diff_text(v_area_total, v_nat_total)
                    diff_pref_txt = get_diff_text(v_area_total, v_pref_total)
                    eval_msg = f"エリア平均 **¥{v_area_total:,.0f}** (全国差 {diff_nat_txt} / 都道府県差 {diff_pref_txt})"
                    
                    if v_area_total > v_nat_total * 1.2:
                        st.error(f"**【全体評価:超高単価市場】** {eval_msg}  \n新台の導入スピードが極めて速く、最新鋭の機械構成が求められる激戦区です。")
                    elif v_area_total >= v_nat_total:
                        st.warning(f"**【全体評価:標準〜高単価市場】** {eval_msg}  \n全国平均以上の鮮度を維持しており、一定の機械投資競争が発生している市場です。")
                    else:
                        st.info(f"**【全体評価:コスト抑制型市場】** {eval_msg}  \n中古機や長期設置機が主流であり、新台よりも運用力や遊技環境が重視される傾向にあります。")

                    st.markdown("**📝 4部門別・エリア市場環境分析**")
                    
                    def get_market_comment(area_val, nat_val):
                        if nat_val == 0: return "データ不足により判定不可"
                        ratio = area_val / nat_val
                        if ratio > 1.25: return ":**:red[【新台過密】]** 全国屈指の最新台投入エリア。機械パワーでの差別化が困難。"
                        elif ratio > 1.05: return ":**:red[【高鮮度】]** 全国平均より新台導入が活発。競争力維持のコストが高い。"
                        elif ratio >= 0.95: return ":【標準的】 全国平均並の入れ替え頻度。バランスの良い市場。"
                        elif ratio > 0.75: return ":**:blue[【安定運用】]** 無理な入替を抑え、定番機種を長く使う安定志向の市場。"
                        else: return ":**:blue[【低付加価値】]** 償却機がメイン。設備投資よりも粗利管理が優先される傾向。"

                    cols = st.columns(2)
                    depts_info = [("🔴 通常パチンコ", "パチンコ通常"), ("🔵 通常スロット", "スロット通常"), ("🟢 低貸パチンコ", "パチンコ低貸"), ("🟡 低貸スロット", "スロット低貸")]

                    for i, (label, col_key) in enumerate(depts_info):
                        with cols[i % 2]:
                            cur_val = area_row[col_key]
                            st.markdown(f"**{label}**")
                            st.write(f"**¥{cur_val:,.0f}**")
                            st.caption(f"全国差: {get_diff_text(cur_val, national_row[col_key])} / 県差: {get_diff_text(cur_val, pref_row[col_key])}")
                            st.write(get_market_comment(cur_val, national_row[col_key]))

                    # --- 📊 E. データテーブル表示 (既存維持) ---
                    st.markdown("---")
                    
                    # 1. 平均行の作成
                    df_avg_part = pd.DataFrame([national_row, pref_row, area_row])
                    
                    # 2. 店舗行の作成とソート
                    df_shops_part = pd.DataFrame(shop_results)
                    df_shops_part = df_shops_part.sort_values(by="全体", ascending=False)
                    
                    # 3. 列順序を整えて結合(店舗名を一番左にする)
                    cols_order = ["店舗名", "全体", "パチンコ通常", "パチンコ低貸", "スロット通常", "スロット低貸"]
                    df_shops_part = df_shops_part.drop(columns=["店舗ID"], errors='ignore')
                    
                    # 結合
                    df_total_compare = pd.concat([df_avg_part, df_shops_part], ignore_index=True)[cols_order]
                    
                    # 店舗名をインデックスに設定(これで左端に固定され、右詰めが解消されます)
                    df_styled = df_total_compare.set_index("店舗名")

                    def apply_comparison_style(styler):
                        # スタイル適用ロジック
                        # インデックス(店舗名)ではなく、各列に対して計算
                        for col in styler.columns:
                            baseline = area_row[col]
                            # 各行の値を判定
                            styler.apply(lambda x: [
                                'background-color: #f0f2f6; font-weight: bold;' if i < 3 else
                                'background-color: #fff3cd; border: 2px solid #ffc107; font-weight: bold;' if "★自店" in str(df_total_compare.iloc[i]["店舗名"]) else
                                'background-color: #d4edda; color: #155724; font-weight: bold;' if val > baseline and baseline > 0 else ''
                                for i, val in enumerate(x)
                            ], subset=[col])
                        return styler

                    # 表示
                    st.dataframe(
                        df_styled.style.pipe(apply_comparison_style)
                        .format(formatter="¥{:,.0f}"),
                        use_container_width=True
                    )


                    # --- 🤖 F. 店舗別詳細 ---
                    st.markdown("---")
                    st.write(f"🤖 **商圏内 全{num_shops}店舗 資産価値・部門別詳細分析**")
                    
                    # shop_resultsをIDをキーにした辞書に変換(ループ内検索を高速化するため)
                    shop_vals_dict = {str(item["店舗ID"]): item for item in shop_results}
                    
                    # 距離順にソートして表示
                    for _, target_shop in neighbor_df.sort_values("distance").iterrows():
                        t_id = str(target_shop["店舗ID"])
                        t_name = target_shop["店舗名"]
                        dist = target_shop["distance"]
                        
                        is_self_flag = (t_id == selected_shop_id_str)
                        is_self_label = " (★自店)" if is_self_flag else ""
                        
                        # shop_resultsからの検索を高速な辞書参照に変更
                        s_vals = shop_vals_dict.get(t_id)
                        if not s_vals:
                            continue
                            
                        s_total = s_vals["全体"]
                        t_rank = rank_dicts["全体"][t_id]
                        diff_ratio = s_total / v_area_total if v_area_total > 0 else 1

                        # 評価ロジック(既存のまま)
                        if s_total == 0: 
                            status_tag, g_eval = "⚠️ データ無", "データが取得できませんでした"
                        elif diff_ratio > 1.15: 
                            status_tag, g_eval = "🌟 超積極投資", "エリア平均を凌駕する投資で高単価層を狙う戦略"
                        elif diff_ratio > 1.02: 
                            status_tag, g_eval = "📈 積極運用", "鮮度を高く保ち、競合に対し優位性を維持する運用"
                        else: 
                            status_tag, g_eval = "⚖️ 標準/効率運用", "コストを抑え、償却機や中古機を活かす堅実な運用"

                        # --- 表示部分 (以前の仕様を完全に復元) ---
                        with st.expander(f"📍 {t_name}{is_self_label} - {status_tag} / {t_rank}位 ({dist:.1f}km)"):
                            st.markdown(f"### {g_eval}")
                            c1, c2 = st.columns(2)
                            with c1:
                                st.write(f"**【総合評価】**")
                                st.write(f"* 1台あたり平均: **¥{s_total:,.0f}**")
                                st.write(f"* 全国平均差: {get_diff_text(s_total, national_row['全体'])}")
                                st.write(f"* エリア順位: **{t_rank}位** / {num_shops}店舗")
                            with c2:
                                st.write(f"**【商圏ポジショニング】**")
                                st.write(f"* エリア平均差: {get_diff_text(s_total, v_area_total)}")
                                st.write(f"* エリア比率: **{diff_ratio:.1%}**")

                            st.markdown("---")
                            st.write("**【各部門別・エリア比較コメント】**")
                            # 各部門の分析コメントを復元
                            st.write(get_dept_analysis(s_vals["パチンコ通常"], area_row["パチンコ通常"], "🔴 通常パチンコ", rank_dicts["パチンコ通常"][t_id]))
                            st.write(get_dept_analysis(s_vals["スロット通常"], area_row["スロット通常"], "🟣 通常スロット", rank_dicts["スロット通常"][t_id]))
                            st.write(get_dept_analysis(s_vals["パチンコ低貸"], area_row["パチンコ低貸"], "🔵 低貸パチンコ", rank_dicts["パチンコ低貸"][t_id]))
                            st.write(get_dept_analysis(s_vals["スロット低貸"], area_row["スロット低貸"], "🟢 低貸スロット", rank_dicts["スロット低貸"][t_id]))

                    # --- 🥇 G. エリア1位奪取シミュレーション (構造最適化) ---
                    st.markdown("---")
                    st.markdown("#### 🥇 エリア目標達成:現実的な機種構成案")

                    target_mode = st.radio("目標基準", ["エリア1位奪取", "エリア平均超え", "目標金額を直接指定"], horizontal=True)

                    # 目標値の決定ロジック
                    if target_mode == "エリア1位奪取":
                        buffer = st.select_slider("バッファ", options=[2000, 10000, 30000, 50000], value=2000)
                        p_target = max(self_vals["パチンコ通常"], best_p_avg + buffer) if self_vals["パチンコ通常"] < best_p_avg else self_vals["パチンコ通常"]
                        s_target = max(self_vals["スロット通常"], best_s_avg + buffer) if self_vals["スロット通常"] < best_s_avg else self_vals["スロット通常"]
                    elif target_mode == "エリア平均超え":
                        p_target, s_target = area_row["パチンコ通常"] + 5000, area_row["スロット通常"] + 5000
                    else:
                        c1, c2 = st.columns(2)
                        p_target = c1.number_input("P目標", value=int(area_row["パチンコ通常"]), step=10000)
                        s_target = c2.number_input("S目標", value=int(area_row["スロット通常"]), step=10000)

                    # 市場トップ機種を事前に1回だけ取得(高速化)
                    market_tops = {
                        "通常P": df_val[df_val["貸玉区分"] == "通常P"].groupby("機種名")["中古単価_num"].mean().sort_values(ascending=False).head(15),
                        "通常S": df_val[df_val["貸玉区分"] == "通常S"].groupby("機種名")["中古単価_num"].mean().sort_values(ascending=False).head(15)
                    }

                    def sim_smart_goal_portfolio_fast(target_cat, self_qty, self_avg, t_avg):
                        if self_qty <= 0: return "スペースデータなし"
                        if self_avg >= t_avg: return "✅ 現在の構成ですでに目標を達成しています。"
                        
                        inventory = df_val[(df_val["店舗ID"] == selected_shop_id_str) & (df_val["貸玉区分"] == target_cat)].set_index("機種名")["設置台数"].to_dict()
                        m_top = market_tops[target_cat]
                        
                        add_list, remaining, cur_sim_asset = [], self_qty, 0
                        max_per = min(20, max(1, int(self_qty * 0.1)))

                        for name, price in m_top.items():
                            if remaining <= 0 or (cur_sim_asset + (remaining * self_avg)) / self_qty >= t_avg: break
                            num = min(max_per, remaining)
                            extra = max(0, num - inventory.get(name, 0))
                            if extra > 0:
                                add_list.append({"追加導入機種": name, "単価": int(price), "追加数": f"{int(extra)}台", "(導入後合計)": f"{int(num)}台"})
                            cur_sim_asset += (price * num)
                            remaining -= num
                        
                        if remaining > 0: cur_sim_asset += (self_avg * remaining)
                        if not add_list: return "既存機種の構成変更のみで目標達成可能です。"
                        return {"sim_avg": cur_sim_asset / self_qty, "details": pd.DataFrame(add_list)}

                    sc1, sc2 = st.columns(2)
                    with sc1:
                        st.write(f"**🔴 パチンコ通常**")
                        res_p = sim_smart_goal_portfolio_fast("通常P", self_p_qty, self_vals["パチンコ通常"], p_target)
                        if isinstance(res_p, dict):
                            st.metric("シミュレーション後", f"¥{int(res_p['sim_avg']):,}")
                            st.table(res_p["details"].style.format({"単価": "¥{:,.0f}"}))
                        else: st.success(res_p)
                    with sc2:
                        st.write(f"**🟣 スロット通常**")
                        res_s = sim_smart_goal_portfolio_fast("通常S", self_s_qty, self_vals["スロット通常"], s_target)
                        if isinstance(res_s, dict):
                            st.metric("シミュレーション後", f"¥{int(res_s['sim_avg']):,}")
                            st.table(res_s["details"].style.format({"単価": "¥{:,.0f}"}))
                        else: st.success(res_s)


                    # 💡 タブ9の末尾に追加:タブ10連携用のバックグラウンド保存
                    if "tab9_results" not in st.session_state:
                        st.session_state.tab9_results = {}
                    
                    if self_vals:
                        target_shop_id = str(selected_shop_id_str).strip()

                        if v_area_total > v_nat_total * 1.2:
                            area_eval_comment = "新台の導入スピードが極めて速く、最新鋭の機械構成が求められる激戦区です。"              
                        elif v_area_total >= v_nat_total:
                            area_eval_comment = "全国平均以上の鮮度を維持しており、一定の機械投資競争が発生している市場です。"
                        else:
                            area_eval_comment = "中古機や長期設置機が主流であり、新台よりも運用力や遊技環境が重視される傾向にあります。"

                        st.session_state.tab9_results[target_shop_id] = {
                            "全体評価": self_vals["全体"],
                            "エリア平均": v_area_total,
                            "エリア評価コメント": area_eval_comment,
                            "部門分析": {
                                "通常P": get_dept_analysis(self_vals["パチンコ通常"], area_row["パチンコ通常"], "通常P", rank_dicts["パチンコ通常"][target_shop_id]),
                                "通常S": get_dept_analysis(self_vals["スロット通常"], area_row["スロット通常"], "通常S", rank_dicts["スロット通常"][target_shop_id]),
                                "低貸P": get_dept_analysis(self_vals["パチンコ低貸"], area_row["パチンコ低貸"], "低貸P", rank_dicts["パチンコ低貸"][target_shop_id]),
                                "低貸S": get_dept_analysis(self_vals["スロット低貸"], area_row["スロット低貸"], "低貸S", rank_dicts["スロット低貸"][target_shop_id]),
                            }
                        }


                except Exception as e:
                    st.error(f"システムエラー: {e}")
                    import traceback
                    st.sidebar.error(traceback.format_exc())




            # =========================================================
            # タブ10:商圏戦略考察
            # =========================================================
            with tabs["📈 商圏戦略考察"]:
                st.header("📈 商圏戦略考察(総括レポート)")
                
                # 自店IDの型と空白を完全にクリーンアップして統一
                target_shop_id = str(selected_shop_id).strip()
                
                # 【修正ポイント】border=True を排除し、青い枠線・コンテナが発生しないように修正
                with st.container():
                    
                    # ---------------------------------------------------------
                    # 🏁 1. 市場ポジション (タブ2)
                    # ---------------------------------------------------------
                    st.markdown("### 🏁 市場ポジション (タブ2)")
                    
                    # データ型の安全なキャストとバックアップ作成
                    calc_df = neighbor_df.copy()
                    dept_order = ["P通常", "P低貸", "S通常", "S低貸"]
                    
                    for c in ["総台数", "P台数", "S台数"] + dept_order:
                        calc_df[c] = pd.to_numeric(calc_df[c], errors='coerce').fillna(0)
                    
                    # --- 【移植①】商圏環境アセスメントの計算と表示 ---
                    super_large_count = len(calc_df[calc_df["総台数"] >= 1000])
                    large_shops_count = len(calc_df[(calc_df["総台数"] >= 750) & (calc_df["総台数"] < 1000)])
                    mid_shops_count = len(calc_df[(calc_df["総台数"] >= 400) & (calc_df["総台数"] < 750)])
                    small_shops_count = len(calc_df[calc_df["総台数"] < 400])
                    total_shops = len(calc_df)
                    
                    # 各種平均値の計算
                    avg_total_val = calc_df["総台数"].mean()
                    avg_p_norm_val = calc_df["P通常"].mean()
                    avg_s_norm_val = calc_df["S通常"].mean()
                    avg_normal_total_val = (calc_df["P通常"] + calc_df["S通常"]).mean()
                    
                    total_all_val = calc_df["総台数"].sum()
                    p_norm_rat_val  = (calc_df["P通常"].sum() / total_all_val * 100) if total_all_val > 0 else 0
                    p_low_rat_val   = (calc_df["P低貸"].sum() / total_all_val * 100) if total_all_val > 0 else 0
                    s_norm_rat_val  = (calc_df["S通常"].sum() / total_all_val * 100) if total_all_val > 0 else 0
                    s_low_rat_val   = (calc_df["S低貸"].sum() / total_all_val * 100) if total_all_val > 0 else 0
                    
                    # 全国平均の総台数を取得(基準値として提示)
                    n_avg_val = int(round(nation_avg["総台数"])) if "nation_avg" in locals() or "nation_avg" in globals() else 0

                    if total_shops > 0:
                        st.markdown("#### 📊 商圏環境アセスメント")
                        if super_large_count >= 2 or (super_large_count >= 1 and large_shops_count >= 1):
                            st.error(
                                f"**【超激戦区:複数メガ・ラージ主導市場】**\n\n"
                                f"商圏内に1000台超の超大型店が {super_large_count} 店舗、750台超の大型店が {large_shops_count} 店舗存在します。\n\n"
                                f"当エリアの平均台数({int(round(avg_total_val))}台)は、**全国平均({n_avg_val}台)を大きく凌駕する破格のスケール**です。資本力に極振りした旗艦店同士がメイン機種の導入数や出玉(運用)で殴り合う、全国屈指のヘビーなパワーゲーム市場と言えます。\n\n"
                                f"中小規模店が真っ向勝負を挑むのは自滅を意味するため、特定部門への特化や中古機を絡めた「低投資・高効率」な筋肉質営業へのシフトが必須となります。"
                            )
                        elif super_large_count == 1 or large_shops_count >= 2:
                            st.error(
                                f"**【一強突出または大型対抗市場】**\n\n"
                                f"1000台クラス、または750台クラスの地域1番店が市場のシェアを大きく囲い込んでいます。\n\n"
                                f"**全国平均({n_avg_val}台)という基準を大幅に超えるメガ店舗**が市場のプラットフォーム(ユーザーの第1選択肢)化しているため、新台入替日の集客格差や特定日の吸い込みが顕著に出やすい傾向があります。\n\n"
                                f"周辺の競合店は、1番店が「メーカー付き合い」で導入せざるを得ない不人気台の隙間を縫う局地戦か、低貸比率を高めて客数を担保する防衛戦が中心となります。"
                            )
                        elif large_shops_count == 1 or mid_shops_count >= 3:
                            st.warning(
                                f"**【要警戒エリア:中堅・有力店混在市場】**\n\n"
                                f"400台〜750台クラスの中堅・有力店舗({mid_shops_count}店舗)がひひめき合い、決定的な勝者がまだ不在の市場です。\n\n"
                                f"各店の規模は**全国平均({n_avg_val}台)と同等か一回り上回る水準**であり、仕掛けを行う曜日や特定日ごとに客足が激しく流動する「奪い合い」の性質が非常に強いエリアです。\n\n"
                                f"油断すると一気にシェアを捲られるため、自店の「強み(パチンコなのかスロットなのか)」を明確にし、特定の曜日や特定日で確実に勝てる仕組み作りが求められます。"
                            )
                        elif mid_shops_count >= 1 or small_shops_count >= 3:
                            st.info(
                                f"**【標準・地域安定市場:小規模店中心】**\n\n"
                                f"400台未満のコンパクトな店舗({small_shops_count}店舗)が中心の市場です。\n\n"
                                f"市場全体の平均規模は**全国平均({n_avg_val}台)を下回るか、ほぼ同水準のコンパクトな設計**になっており、メガ店舗による強引なシェア強奪のリスクは低い環境です。その分、地元ユーザーの定着率(常連化)が命綱となります。\n\n"
                                f"過度な最新台投資は即座に首を絞めるため、遊技台の資産価値(中古運用の見極め)と、スタッフの接客・コミュニティ化による差別化が極めて有効に機能します。"
                            )
                        else:
                            st.success(
                                f"**【ニッチ・超過>©過疎市場】**\n\n"
                                f"競合店舗数が非常に少なく、極めて穏やかな市場環境、あるいは競合不在のニッチエリアです。\n\n"
                                f"各店の規模は**全国平均({n_avg_val}台)を大きく下回る小規模店が主体**であり、競合対策にコストを割く必要がない反面、エリア全体の総人口や遊技人口そのものが収縮しているリスクがあります。\n\n"
                                f"仕掛けによる客数増を強引に狙うより、適切な台数規模への減台や、遊技環境の快適性を高めて1人あたりの滞在時間を延ばす「粗利コントロール型」の営業が適しています。"
                            )

                        # 商圏キャパシティ
                        if total_all_val >= 5000:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all_val:,}台** の超巨大マーケットです。")
                        elif total_all_val >= 2500:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all_val:,}台** の中規模マーケットです。")
                        else:
                            st.markdown(f"💡 **市場キャパシティ分析:** 商圏総台数 **{total_all_val:,}台** のスモールマーケットです。")
                    
                    st.markdown("---")
                    
                    # --- 【移植②】対象店舗の個別詳細レポート(エラー回避・安全再計算版) ---
                    calc_df["通常貸合計"] = calc_df["P通常"] + calc_df["S通常"]
                    calc_df["全体順位_calc"] = calc_df["総台数"].rank(ascending=False, method="min").astype(int)
                    calc_df["通常順位_calc"] = calc_df["通常貸合計"].rank(ascending=False, method="min").astype(int)
                    calc_df["P通常順位_calc"] = calc_df["P通常"].rank(ascending=False, method="min").astype(int)
                    calc_df["S通常順位_calc"] = calc_df["S通常"].rank(ascending=False, method="min").astype(int)
                    
                    for dept in dept_order:
                        calc_df[f"{dept}比率_calc"] = (calc_df[dept] / calc_df["総台数"].replace(0, 1) * 100)

                    # 選択された店舗の行データを取得
                    target_row = calc_df[calc_df["店舗ID"].astype(str) == target_shop_id]
                    
                    if not target_row.empty:
                        shop_data = target_row.iloc[0]
                        shop_name = shop_data["店舗名"]
                        
                        st.markdown(f"#### 🎯 {shop_name} AI分析レポート")
                        
                        with st.container():
                            # 平均との差分を正確に動的計算
                            s_diff_total = shop_data["総台数"] - avg_total_val
                            s_diff_normal = shop_data["通常貸合計"] - avg_normal_total_val
                            s_diff_p_norm = shop_data["P通常"] - avg_p_norm_val
                            s_diff_s_norm = shop_data["S通常"] - avg_s_norm_val

                            st.markdown("**【市場内ランクと乖離】**")
                            st.markdown(f"* 総合順位: **第{shop_data['全体順位_calc']}位** (平均比 {s_diff_total:+.0f}台)")
                            st.markdown(f"* 通常貸順位: **第{shop_data['通常順位_calc']}位** (平均比 {s_diff_normal:+.0f}台)")
                            st.markdown(f"* P通常: {shop_data['P通常順位_calc']}位 ({s_diff_p_norm:+.0f}台) / S通常: {shop_data['S通常順位_calc']}位 ({s_diff_s_norm:+.0f}台)")
                            
                            st.markdown("")
                            
                            # ポジショニング分析の動的出力
                            st.markdown("**【ポジショニング分析】**")
                            if shop_data["全体順位_calc"] == 1:
                                st.markdown(f"✅ **商圏リーダー:** 台数規模でエリア単独首位。平均を {int(s_diff_total)}台 上回る圧倒的な物量が武器です。")
                            elif shop_data["全体順位_calc"] <= 3:
                                st.markdown(f"✅ **主要有力店:** エリア上位の規模。平均比 +{int(s_diff_total)}台 と、市場への影響力が高いポジションです。")
                            else:
                                st.markdown(f"✅ **中堅・専門店:** 規模は平均比 {int(s_diff_total)}台。特定の貸玉や部門での差別化戦略をとっています。")
                            
                            # 部門別シェア比較(市場平均比)の動的出力
                            st.markdown("**【部門別シェア比較(市場平均比)】**")
                            comp_p_norm_rat = shop_data["P通常比率_calc"]
                            comp_p_low_rat  = shop_data["P低貸比率_calc"]
                            comp_s_norm_rat = shop_data["S通常比率_calc"]
                            comp_s_low_rat  = shop_data["S低貸比率_calc"]
                            
                            comp_dept_analysis = []
                            if comp_p_norm_rat > p_norm_rat_val + 5:
                                comp_dept_analysis.append(f"📈 **P通常特化型:** 市場平均({p_norm_rat_val:.1f}%)に対し、{comp_p_norm_rat:.1f}%と高い構成。4円ユーザーの受け皿となっています。")
                            if comp_s_norm_rat > s_norm_rat_val + 5:
                                comp_dept_analysis.append(f"📈 **S通常特化型:** 市場平均({s_norm_rat_val:.1f}%)に対し、{comp_s_norm_rat:.1f}%とスロット通常貸を極めて重視。勝負志向の強い顧客層を抱えています。")
                            if comp_p_low_rat > p_low_rat_val + 5:
                                comp_dept_analysis.append(f"📉 **P低貸過多:** 市場平均({p_low_rat_val:.1f}%)を大きく上回る{comp_p_low_rat:.1f}%の構成。薄利多売の傾向が強く、集客はできても収益性に課題がある可能性があります。")
                            if comp_s_low_rat > s_low_rat_val + 5:
                                comp_dept_analysis.append(f"📉 **S低貸重視:** 市場平均({s_low_rat_val:.1f}%)に対し、{comp_s_low_rat:.1f}%が低貸。滞在型ユーザーが多い構成です。")
                            
                            if not comp_dept_analysis:
                                st.markdown("⚖️ **市場標準構成:** 全部門において市場平均に近いバランスの取れた構成です。")
                            else:
                                for analysis in comp_dept_analysis:
                                    st.markdown(analysis)
                            
                            # 戦略・分析の動的出力
                            st.markdown("**【戦略・分析】**")
                            if s_diff_normal > 0:
                                st.markdown(f"💡 **収益力:** 通常貸部門が平均を {int(s_diff_normal)}台 上回る強力な布陣。収益基盤が安定しています。")
                            else:
                                st.markdown(f"💡 **客数依存:** 通常貸が平均比 {int(s_diff_normal)}台 と不足。低貸による客数確保への依存が強い構成です。")
                    else:
                        st.caption("対象店舗の個別詳細データを読み込めませんでした。")
                        
                    st.divider() # セクション間の区切り線

                    # ---------------------------------------------------------
                    # 🎰 2. 設置機種構成 (タブ3)
                    # ---------------------------------------------------------
                    st.markdown("### 🎰 設置機種構成 (タブ3)")
                    
                    # 共通セッションステートから対象店舗のデータを取得
                    clean_shop_id = str(target_shop_id).strip()
                    tab3_master = st.session_state.get("tab3_results", {}).get(clean_shop_id, None)
                    
                    if tab3_master and "departments" in tab3_master:
                        st.markdown("##### 🤖 AI判定:4部門の商圏アセスメントと自店詳細診断")
                        
                        # 4部門をループ処理で綺麗に出力
                        for dept_key, dept_info in tab3_master["departments"].items():
                            with st.expander(f"📊 {dept_info['label']} の市場アセスメント・自店診断", expanded=False):
                                
                                # A. 商圏環境アセスメントの出力(タブ3と同じ警告色が連動します)
                                st.markdown("**【商圏環境アセスメント】**")
                                if dept_info["assessment_text"]:
                                    if dept_info["assessment_status"] == "error":
                                        st.error(dept_info["assessment_text"])
                                    elif dept_info["assessment_status"] == "warning":
                                        st.warning(dept_info["assessment_text"])
                                    elif dept_info["assessment_status"] == "success":
                                        st.success(dept_info["assessment_text"])
                                    else:
                                        st.info(dept_info["assessment_text"])
                                else:
                                    st.caption("この部門の商圏環境アセスメントデータは存在しません。")
                                
                                st.markdown("---")
                                
                                # B. 自店の各種重要数値メトリクス
                                st.markdown("**【自店の主要指標】**")
                                t3_col1, t3_col2, t3_col3, t3_col4 = st.columns(4)
                                t3_col1.metric("部門設置台数", f"{dept_info['total_seats']}台")
                                t3_col2.metric("部門エリアシェア", f"{dept_info['share']:.1f}%")
                                t3_col3.metric("全国TOP10台数", f"{dept_info['top10_units']}台", f"商圏内 {dept_info['top10_rank']}位")
                                t3_col4.metric("独自保有機種数", f"{dept_info['only_count']}機種")
                                
                                st.markdown("")
                                
                                # C. AIによる詳細戦略レポート
                                st.markdown("**【AI詳細戦略診断】**")
                                st.info(dept_info["full_report"])
                    else:
                        # まだセッションにデータがないか、タブ3側で計算が走っていない場合の安全なフォールバック
                        tab3_data = analysis_comments.get("tab3", {})
                        if isinstance(tab3_data, dict) and clean_shop_id in tab3_data:
                            with st.expander("🔍 自店の設置機種構成・分析詳細", expanded=False):
                                st.info(tab3_data[clean_shop_id])
                        elif isinstance(tab3_data, str) and tab3_data.strip():
                            with st.expander("🔍 設置機種構成・分析詳細", expanded=False):
                                st.info(tab3_data)
                        else:
                            st.caption("設置機種構成のアセスメントおよび詳細データがまだ生成されていません。一度アプリを再起動するか、データソースを確認してください。")
                            
                    st.divider()



                    # ---------------------------------------------------------
                    # 💵 3. 貸玉・タイプ戦略 (タブ4)
                    # ---------------------------------------------------------
                    st.markdown("### 💵 貸玉・タイプ戦略 (タブ4)")

                    # 共通のキー定義とラベルマップ
                    tab4_depts = ["通常P", "低貸P", "通常S", "低貸S"]
                    labels = {"通常P": "🔴 通常P", "低貸P": "🟢 低貸P", "通常S": "🔵 通常S", "低貸S": "🟡 低貸S"}

                    # セッションデータの取得
                    clean_shop_id = str(target_shop_id).strip()
                    tab4_master = st.session_state.get("tab4_results", {}).get(clean_shop_id, None)
                    market_notes = st.session_state.get("tab4_market_notes", {})

                    if tab4_master and "departments" in tab4_master:
                        st.markdown("##### 🤖 AI判定:4部門の貸玉営業スタイルと詳細診断")
                        
                        # 4部門をループ処理で綺麗に出力
                        for dept_key in tab4_depts:
                            dept_data = None
                            if dept_key in tab4_master["departments"]:
                                dept_data = tab4_master["departments"][dept_key]
                            else:
                                for k, v in tab4_master["departments"].items():
                                    if dept_key in k:
                                        dept_data = v
                                        break
                            
                            display_label = labels.get(dept_key, dept_key)
                            
                            with st.expander(f"📊 {display_label} の市場アセスメント・自店診断", expanded=False):
                                
                                # A. 周辺市場(エリア)アセスメントの出力(タブ3と同じように最上部に警告色で連動)
                                st.markdown("**【周辺市場(エリア)アセスメント】**")
                                area_content = market_notes.get(dept_key, "")
                                
                                # 💡 【補強】もしルートAが空でも、個別データ内に保存されたアセスメントがあればそこから補完する
                                if (not area_content or not area_content.strip()) and dept_data:
                                    area_content = dept_data.get("market_assessment", "")
                                
                                if isinstance(area_content, str) and area_content.strip():
                                    st.warning(area_content)
                                else:
                                    st.caption("この部門の周辺市場(エリア)アセスメントデータは存在しません。")                                
                                st.markdown("---")
                                
                                # B. 自店の各種重要数値メトリクス(タブ3と同様の4列構成)
                                st.markdown("**【対象店舗の主要指標】**")
                                if dept_data:
                                    t4_col1, t4_col2, t4_col3, t4_col4 = st.columns(4)
                                    t4_col1.metric("部門設置台数", f"{dept_data.get('total_seats', 0)}台")
                                    
                                    # シェア、傾向ステータス、設定傾向を画面キャプチャの項目通りにマッピング
                                    share_val = dept_data.get('share', None)
                                    share_text = f"{share_val:.1f}%" if share_val is not None else "- %"
                                    t4_col2.metric("営業スタイル判定", f"{dept_data.get('risk_label', 'トレンド追随')}")
                                    
                                    st.markdown("")
                                    
                                    # C. AIによる店舗別の動向・トレンド分析
                                    st.markdown("**【AI個別店舗分析】**")
                                    if dept_data.get("trend_text"):
                                        st.info(dept_data["trend_text"])
                                    else:
                                        st.caption("店舗独自の詳細分析データはありません。")
                                    
                                    # D. 戦略ヒント(アドバイス)
                                    if dept_data.get("advice_text"):
                                        st.success(f"**💡 戦略ヒント:** {dept_data['advice_text']}")
                                else:
                                    st.caption("この部門の事前計算データ(departments)は存在しません。")
                    else:
                        # まだセッションにデータがないか、タブ4側で計算が走っていない場合の安全なフォールバック
                        tab4_data = analysis_comments.get("tab4", {})
                        if isinstance(tab4_data, dict) and clean_shop_id in tab4_data:
                            with st.expander("🔍 自店の貸玉・タイプ戦略・分析詳細", expanded=False):
                                st.info(tab4_data[clean_shop_id])
                        elif isinstance(tab4_data, str) and tab4_data.strip():
                            with st.expander("🔍 貸玉・タイプ戦略・分析詳細", expanded=False):
                                st.info(tab4_data)
                        else:
                            # どちらもない場合は、既存のエリアアセスメント(市場傾向)を単体でフォールバック表示
                            if market_notes:
                                st.markdown("##### 📝 保存済みの市場アセスメント(エリア傾向)")
                                for dept_key in tab4_depts:
                                    area_content = market_notes.get(dept_key, "")
                                    if isinstance(area_content, str) and area_content.strip():
                                        with st.expander(f"🔍 {labels.get(dept_key, dept_key)} エリア傾向詳細", expanded=False):
                                            st.warning(area_content)
                            else:
                                st.caption("貸玉・タイプ戦略のアセスメントおよび詳細データがまだ生成されていません。一度タブ4を開いてデータを生成するか、再起動してください。")
                                
                    st.divider()

                    # ---------------------------------------------------------
                    # ✨ 4. 新台導入状況 (タブ6)
                    # ---------------------------------------------------------
                    st.markdown("### ✨ 新台導入状況 (タブ6)")
                    
                    if "tab6_results" in st.session_state and target_shop_id in st.session_state.tab6_results:
                        all_patterns = st.session_state.tab6_results.get(target_shop_id, {})
                        current_shop_name = neighbor_df[neighbor_df["店舗ID"] == selected_shop_id]["店舗名"].iloc[0] if not neighbor_df.empty else "対象店舗"
                        
                        if all_patterns:
                            st.markdown(f"📊 **{current_shop_name} の新台導入戦略(全条件)**")

                            for pattern_key, res6 in all_patterns.items():
                                shop_analyses = res6.get("shop_analyses", {})

                                # --- 展開した際の一番上に表示 ---
                                with st.expander(f"📌 {res6.get('kind','不明')} × {res6.get('unit','不明')} ({res6.get('axis','不明')})", expanded=False):

                                    # ★アセスメントをexpanderの先頭に移動
                                    if "market_assessment" in res6:
                                        st.markdown("##### ⚠️ 市場環境アセスメント")
                                        st.error(f"{res6['market_assessment']} {res6['assessment_detail']}")

                                    if shop_analyses and current_shop_name in shop_analyses:
                                        self_info = shop_analyses[current_shop_name]

                                        st.markdown(f"##### 🏢 店舗分析:{current_shop_name}")
                                        st.info(self_info["trend_analysis"])

                                        st.markdown("##### 💡 戦略へのヒント")
                                        st.success(self_info["strategy_hint"])
                                        st.caption(f"実績: {self_info['導入台数']} ({self_info['導入比率']}) | エリア台数順位: {self_info['qty_rank']}位")
                        else:
                            st.caption("新台分析の自動計算データが見つかりません。")
                    else:
                        st.caption("新台分析データがまだ生成されていません。先にタブ6を選択してデータを生成してください。")

                    st.divider()


                    # ---------------------------------------------------------
                    # 📱 5. スマート機状況 (タブ7)
                    # ---------------------------------------------------------
                    st.markdown("### 📱 スマート機状況 (分析レポート)")
                    
                    if "tab7_results" in st.session_state and target_shop_id in st.session_state.tab7_results:
                        all_smart_patterns = st.session_state.tab7_results.get(target_shop_id, {})
                        current_shop_name = neighbor_df[neighbor_df["店舗ID"] == selected_shop_id]["店舗名"].iloc[0] if not neighbor_df.empty else "対象店舗"
                        
                        if all_smart_patterns:
                            st.markdown(f"📊 **{current_shop_name} のスマート遊技機普及状況(カテゴリ別)**")
                            for sub_label, info7 in all_smart_patterns.items():
                                with st.expander(f"📌 {sub_label} 分析結果 - {info7['status']}", expanded=False):
                                    
                                    # エリア評価の表示(キーが存在するか確認)
                                    if "area_status" in info7:
                                        st.warning(f"**エリア全体評価:** {info7['area_status']}\n\n{info7['area_msg']}")
 
                                    st.info(f"**店舗の立ち位置:** {info7['status']}\n\n{info7['base_msg']}")
                                   
                                    if info7.get("caption_msg"):
                                        st.caption(f"💡 {info7['caption_msg']}")
                                    
                                    sm_col1, sm_col2 = st.columns(2)
                                    with sm_col1:
                                        st.metric(label="スマート機台数", value=f"{info7['s_qty']}台", delta=f"{info7['diff_qty']:+.1f}台 (平均差)")
                                        st.caption(f"エリア台数順位: {info7['q_rank']}位 / {info7['num_shops']}店")
                                    with sm_col2:
                                        st.metric(label="スマート比率", value=f"{info7['s_ratio']:.1f}%", delta=f"{info7['diff_ratio']:+.1f}% (平均差)")
                                        st.caption(f"エリア比率順位: {info7['r_rank']}位 / {info7['num_shops']}店")
                        else:
                            st.caption("スマート機分析の自動計算データが見つかりません。")
                    else:
                        st.caption("スマート機分析データがまだ生成されていません。先にタブ7を選択してデータを生成してください。")

                    st.divider()



                    # ---------------------------------------------------------
                    # 💰 6. 資産評価 (タブ9)
                    # ---------------------------------------------------------
                    st.markdown("### 💎 資産価値状況")

                    # タブ9の計算結果から、該当店舗のデータを取得
                    sid_key = str(target_shop_id).strip()

                    if "tab9_results" in st.session_state and sid_key in st.session_state.tab9_results:
                        res = st.session_state.tab9_results[sid_key]
                        
                        # 1. アセスメント(全体評価論評)の表示
                        st.error(f"**【全体評価】** {res.get('エリア評価コメント', '')}")

                        # タブ9のマスターデータから、店舗個別の「総合評価」と「ステータスタグ」を表示
                        master = st.session_state.get('shop_analysis_master', {})
                        if sid_key in master:
                            shop_info = master[sid_key]
                            st.error(f"**【{shop_info.get('ステータスタグ', '評価済')}】**")
                            st.write(f"**分析コメント:** {shop_info.get('総合評価', '評価データがありません')}")
                        
                        # 2. 数値サマリー
                        st.info(f"**【資産価値】** ¥{res['全体評価']:,.0f} (エリア平均: ¥{res['エリア平均']:,.0f})")
                        
                        # 3. 部門別詳細コメントの展開
                        with st.expander("📌 部門別分析詳細", expanded=True):
                            # 部門分析のキーとラベルのマッピング
                            dept_labels = {
                                "通常P": "🔴 通常パチンコ",
                                "通常S": "🔵 通常スロット",
                                "低貸P": "🟢 低貸パチンコ",
                                "低貸S": "🟡 低貸スロット"
                            }
                            
                            for key, label in dept_labels.items():
                                if key in res['部門分析']:
                                    st.markdown(f"**{label}**")
                                    st.markdown(res['部門分析'][key])
                                    st.markdown("---")

                    else:
                        st.warning("資産価値分析データが未生成です。先にタブ9(資産価値分析)を開いてデータを計算してください。")

                    st.divider()


                # =========================================================
                # --- [最下段] 総括の締め ---
                st.divider()
                st.subheader("💡 総合考察")

                # 確実に選択された店舗名を取得しておく
                current_shop_name = neighbor_df[neighbor_df["店舗ID"] == selected_shop_id_str]["店舗名"].iloc[0] if not neighbor_df.empty else "対象店舗"
                target_shop_id = str(selected_shop_id_str).strip()

                # =========================================================
                # ⚙️ 1. 各種データのリアルタイム多次元集計ロジック
                # =========================================================
                p_normal_seats = 0
                p_low_seats = 0
                s_normal_seats = 0
                s_low_seats = 0

                # 出力表示用の変数もあらかじめ空文字で初期化(NameErrorを絶対に起こさない安全弁)
                p_normal_comment = ""
                p_low_comment = ""
                s_normal_comment = ""
                s_low_comment = ""

                tab4_all = st.session_state.get("tab4_results", {})
                if isinstance(tab4_all, dict) and target_shop_id in tab4_all and "departments" in tab4_all[target_shop_id]:
                    depts_data = tab4_all[target_shop_id]["departments"]
                    if isinstance(depts_data, dict):
                        p_normal_seats = depts_data.get("通常P", {}).get("total_seats", 0) if isinstance(depts_data.get("通常P"), dict) else 0
                        p_low_seats = depts_data.get("低貸P", {}).get("total_seats", 0) if isinstance(depts_data.get("低貸P"), dict) else 0
                        s_normal_seats = depts_data.get("通常S", {}).get("total_seats", 0) if isinstance(depts_data.get("通常S"), dict) else 0
                        s_low_seats = depts_data.get("低貸S", {}).get("total_seats", 0) if isinstance(depts_data.get("低貸S"), dict) else 0

                total_shop_seats = p_normal_seats + p_low_seats + s_normal_seats + s_low_seats
                if total_shop_seats == 0 and not neighbor_df.empty:
                    shop_row = neighbor_df[neighbor_df["店舗ID"] == selected_shop_id_str]
                    if "総台数" in shop_row.columns:
                        total_shop_seats = int(shop_row["総台数"].iloc[0])

                p_total = p_normal_seats + p_low_seats
                s_total = s_normal_seats + s_low_seats
                low_total = p_low_seats + s_low_seats
                
                p_ratio = (p_total / total_shop_seats * 100) if total_shop_seats > 0 else 50
                s_ratio = (s_total / total_shop_seats * 100) if total_shop_seats > 0 else 50
                low_ratio = (low_total / total_shop_seats * 100) if total_shop_seats > 0 else 20

                # ①【規模区分】の厳密判定
                if total_shop_seats >= 800:
                    scale_label = "超大型メガホール"
                elif total_shop_seats >= 500:
                    scale_label = "大型中核店舗"
                elif total_shop_seats >= 300:
                    scale_label = "中堅標準店舗"
                else:
                    scale_label = "小型局地特化店"

                # ②【新台投資スタンス】の抽出(★他店データとの混同バグを完全に修正)
                tab6_all = st.session_state.get("tab6_results", {})
                shop_new_machine = tab6_all.get(target_shop_id, {}) if isinstance(tab6_all, dict) else {}
                
                new_machine_style = "市場追随型(平均並み)"
                is_aggressive_new = False
                is_conservative_new = False
                
                if shop_new_machine:
                    target_shop_text = str(shop_new_machine)
                    if any(x in target_shop_text for x in ["積極", "過剰", "先行", "物量", "上回る"]):
                        new_machine_style = "積極投資・最速導入型"
                        is_aggressive_new = True
                    elif any(x in target_shop_text for x in ["慎重", "抑え", "下回る", "中古", "低投資", "絞り", "効率重視"]):
                        new_machine_style = "厳選投資・抑止型(新台切り捨て)"
                        is_conservative_new = True
                
                # 実績台数が極端に少ない場合、強制的に抑止型へ
                if "5台" in str(shop_new_machine) or "1.5%" in str(shop_new_machine):
                    new_machine_style = "厳選投資・抑止型(新台切り捨て)"
                    is_conservative_new = True
                    is_aggressive_new = False

                # ③【スマート機普及度】の抽出
                tab7_all = st.session_state.get("tab7_results", {})
                shop_smart = tab7_all.get(target_shop_id, {}) if isinstance(tab7_all, dict) else {}
                smart_status = "標準普及"
                if isinstance(shop_smart, dict) and shop_smart:
                    if "全体" in shop_smart:
                        smart_status = shop_smart.get("全体", {}).get("status", "分析済") if isinstance(shop_smart.get("全体"), dict) else "標準普及"
                    else:
                        first_key = list(shop_smart.keys())[0] if shop_smart.keys() else "全体"
                        smart_status = shop_smart.get(first_key, {}).get("status", "分析済") if isinstance(shop_smart.get(first_key), dict) else "標準普及"

                # ④【資産価値総合評価】の抽出
                tab9_all = st.session_state.get('shop_analysis_master', {})
                shop_asset = tab9_all.get(target_shop_id, {}) if isinstance(tab9_all, dict) else {}
                
                asset_eval = "未評価"
                status_tag = "標準/効率運用"
                
                if isinstance(shop_asset, dict) and shop_asset:
                    asset_eval = shop_asset.get("総合評価", "アセットデータ解析中。")
                    status_tag = shop_asset.get('ステータスタグ', '標準/効率運用')
                    
                    # 部門別コメントを安全に引っこ抜く
                    dept_comments = shop_asset.get("部門別コメント", {})
                    if isinstance(dept_comments, dict):
                        p_normal_comment = dept_comments.get("通常P", "")
                        p_low_comment = dept_comments.get("低貸P", "")
                        s_normal_comment = dept_comments.get("通常S", "")
                        s_low_comment = dept_comments.get("低貸S", "")
                
                # ⚙️ 属性判定用フラグの再定義
                is_leader = ("1位" in asset_eval or "上位" in asset_eval or total_shop_seats >= 700) and not ("低予算" in str(shop_asset))
                is_low_asset = "懸念" in status_tag or "注意" in status_tag or "警告" in status_tag or "C" in status_tag or "D" in status_tag
                is_low_budget_all = "低予算" in str(shop_asset) or "長期設置機" in str(shop_asset) or is_conservative_new


                # =========================================================
                # 🧠 2. 設置機種属性(王道撤退・マニアック局地戦)の超詳細ロジック
                # =========================================================
                if is_low_budget_all or "効率重視" in str(shop_new_machine):
                    gambling_style = "マイルド周辺機・独自マニアック型"
                    gambling_desc = "新台(北斗・最新スマスロ等)の王道ルートを完全に諦め、中古価格の安いバラエティ機やAタイプ、マニアックな独自機種のファンをピンポイントで囲い込む『低投資・生存限界ゲリラ戦』の様相を呈しています。"
                    
                    popularity_score = "王道主要機の撤退・エッジ特化構成"
                    popularity_desc = "商圏の3大メイン機(北斗・ジャグラー・海)の最新・最高水準での増台競争から完全にドロップアウトしています。その代わりに、他店が外した中古貢献終了機やマニアックな低価格アセットで島を構築し、特定のコアファン(オタク層・ニッチ顧客)の滞留時間だけで店を回す尖った構成です。"
                else:
                    # 🛠️ 通常の射幸性タイプ(既存ロジックのバックアップ)
                    if s_ratio >= 60 and is_aggressive_new:
                        gambling_style = "超高射幸性・スマスロ特化型"
                        gambling_desc = "万枚突破率特化スマスロに原資を投入した構成です。"
                    elif s_ratio >= 50 and p_ratio >= 40 and is_aggressive_new:
                        gambling_style = "高射幸性・新台トレンドハイブリッド型"
                        gambling_desc = "通常Pの最新ミドルと通常Sの最新トレンド双方を最速で敷き詰めた構成です。"
                    elif p_ratio >= 60 and low_ratio < 30:
                        gambling_style = "ミドルパチンコ主導・粗利回収型"
                        gambling_desc = "4パチのミドルスペックが主軸の構成です。"
                    elif low_ratio >= 50:
                        gambling_style = "低射幸性・時間消費(まったり)型"
                        gambling_desc = "低貸が全館の半分以上を占める地域密着スタイルです。"
                    else:
                        gambling_style = "王道マイルド・定番バランス型"
                        gambling_desc = "ジャグラー、海物語などの定番機が中央を固める理想的なポートフォリオです。"

                    # 🛠️ 通常の人気機種網羅性
                    if is_low_asset:
                        popularity_score = "一部深刻な不足・中古低貢献機による穴埋め状態"
                        popularity_desc = "主力メイン機種の台数が適正値を大幅に下回っています。"
                    else:
                        popularity_score = "良好(商圏主要3大メイン機を適正網羅)"
                        popularity_desc = "商圏のユーザーが好む3大看板が配置されています。"


                # =========================================================
                # 🖥️ 3. 画面への動的レンダリング(Webデザイン構築)
                # =========================================================
                st.markdown(f"### 🤖 AI最高経営カルテ:{current_shop_name} 総合アセット分析報告書")
                
                with st.container(border=True):
                    
                    # --- ① 規模・設置構成サマリー ---
                    st.markdown("#### 📐 【規模・設置構成】マーケットポジションと基本業態")
                    m1, m2, m3, m4 = st.columns(4)
                    with m1:
                        st.metric(label="総設置台数", value=f"{total_shop_seats} 台")
                        st.caption(f"市場規模区分: `{scale_label}`")
                    with m2:
                        st.metric(label="パチンコ(P)総台数", value=f"{p_total} 台")
                        st.caption(f"部門比率: `{p_ratio:.1f}%`")
                    with m3:
                        st.metric(label="スロット(S)総台数", value=f"{s_total} 台")
                        st.caption(f"部門比率: `{s_ratio:.1f}%`")
                    with m4:
                        st.metric(label="低貸玉(ライト)総台数", value=f"{low_total} 台")
                        st.caption(f"低貸比率: `{low_ratio:.1f}%`")
                    
                    st.divider()

                    # --- ② パチンコ・スロット・貸玉別区分詳細 ---
                    st.markdown("#### 🎰 【部門・貸玉別区分】4象限マトリクス稼働状況")
                    col_p, col_s = st.columns(2)
                    with col_p:
                        st.markdown(f"##### 🔴 パチンコ部門カルテ(通常・低貸)")
                        st.markdown(f"**通常P(ミドル/ライトミドル等)**: `{p_normal_seats} 台`")
                        if p_normal_comment: st.caption(f"💬 現場メモ: {p_normal_comment}")
                        st.markdown(f"**低貸P(1パチ/2パチ等)**: `{p_low_seats} 台`")
                        if p_low_comment: st.caption(f"💬 現場メモ: {p_low_comment}")
                    with col_s:
                        st.markdown(f"##### 🔵 スロット部門カルテ(通常・低貸)")
                        st.markdown(f"**通常S(20スロ/スマスロ等)**: `{s_normal_seats} 台`")
                        if s_normal_comment: st.caption(f"💬 現場メモ: {s_normal_comment}")
                        st.markdown(f"**低貸S(5スロ/低貸スマスロ等)**: `{s_low_seats} 台`")
                        if s_low_comment: st.caption(f"💬 現場メモ: {s_low_comment}")
                    
                    st.divider()

                    # --- ③ 設置機種・タイプ別構成 ---
                    st.markdown("#### 🎯 【設置機種・タイプ別構成】射幸性トレンドと人気機種網羅度")
                    c_gam, c_pop = st.columns(2)
                    with c_gam:
                        st.warning(f"**⚡ 機種属性(射幸性比率)**\n\n判定: **`{gambling_style}`**\n\n{gambling_desc}")
                    with c_pop:
                        st.info(f"**🔥 看板機種・人気機種の網羅性**\n\n判定: **`{popularity_score}`**\n\n{popularity_desc}")
                    
                    st.divider()

                    # --- ④ 新台・スマート機・資産価値 ---
                    st.markdown("#### 💵 【投資3大指標】新台・スマート機・資産価値の相関分析")
                    c_new, c_smart, c_asset = st.columns(3)
                    with c_new:
                        st.warning(f"**新台導入スタンス(タブ6)**\n\n`{new_machine_style}`")
                    with c_smart:
                        st.success(f"**スマート機普及度(タブ7)**\n\n`{smart_status}`")
                    with c_asset:
                        st.info(f"**資産価値総合評価(タブ9)**\n\n`【{status_tag}】`")
                    st.caption(f"📜 **アセットマスターデータ総括:** {asset_eval}")
                    
                    st.divider()

                    # =========================================================
                    # 💡 5. AIによる深掘り現状考察 & 16パターン超精密アドバイス
                    # =========================================================
                    st.markdown("### 📝 AI特別深掘り現状考察 & 実践アクションプラン")

                    # --- パターン判定マトリクスによる超詳細個別コメントの動的流し込み ---
                    if is_leader and "超高射幸性" in gambling_style:
                        # 👑 パターン1:超高射幸性メガリーダー(市場完全制圧型だがボラ大)
                        st.markdown("##### 🌋 現状考察:圧倒的資本を『スマスロ万枚トレンド』に全張りした、商圏の猛猛たる絶対王者")
                        st.markdown(f"**{current_shop_name}** は設置台数 `{total_shop_seats}台` という圧倒的なスケールメリットを最大の武器に、スマスロの超高射幸性セグメントへ全原資を突っ込んでいます。新台({new_machine_style})とスマート機普及({smart_status})のスピードで競合を完膚なきまでに叩き潰しており、粗利総額・若年層シェアともにエリアトップを独走しています。しかし、その強さの裏には『一撃の波が荒すぎて、平日に粗利を少し強めに抜くだけで瞬時に客層が飛びかねない』という、爆弾を抱えた営業状態でもあります。")
                        
                        st.markdown("##### 🔴 パチンコ部門(通常P・低貸P)への具体的アクション")
                        st.markdown("通常Pのミドル機(エヴァ等)への投資は現状維持、または半歩減速で構いません。それよりも、通常S(スロット)で勝利を収めたユーザー、あるいは軍資金がショートしかけたユーザーを店外へ流出させないために、**通常Pのライトミドル・甘デジ部門のベース調整を手動で『遊べる調整(薄利)』へ叩き込んでください。** スロットのハイリスクな島の周囲に、パチンコの『避難所』としての安心感を演出することが、全館での滞留時間(アウト)を最大化させる唯一の鍵です。")
                        
                        st.markdown("##### 🔵 スロット部門(通常S・低貸S)への具体的アクション")
                        st.markdown("荒波AT機の比率が過剰({s_ratio:.1f}%)であるため、平日の稼働の土台となる『マイジャグラーV』等のAタイプ部門の信頼度が生命線となります。週末にスマスロで大きく回収した利益を、**平日のジャグラーの『設定4・5』の散布へ惜しみなく還元してください。** 『この店はスマスロは怖いが、ジャグラーは毎日座れる』という口コミを地域住民(シニア〜サラリーマン層)に定着させ、営業の足腰を筋肉質に補強しましょう。")
                        
                        st.markdown("##### 💵 新台・スマート機・資産の次期投資バランスプラン")
                        st.markdown("スマート機({smart_status})の物量制圧はすでに達成されているため、次期はマイナー新台の付き合い購入を15%カットしてください。浮いた機械代を、低貸部門(低貸S)への『型落ちスマスロの大量移設(セカンドユース)』の工事費へ回し、大手が手を出せない**『地域最大・低貸スマスロコーナー』**を新設して、商圏全体のライトスロッター市場まで完全に根こそぎ総取り(完全防衛網の構築)してください。")

                    elif is_leader and "バランス" in gambling_style:
                        # ⚖️ パターン2:王道定番メガリーダー(海・ジャグラー鉄板型)
                        st.markdown("##### ⚖️ 現状考察:海物語・ジャグラーの『圧倒的常連支持』をアセット化した、高残存・鉄壁の要塞店舗")
                        st.markdown(f"**{current_shop_name}** は、設置規模 `{total_shop_seats}台` の巨体でありながら、機種構成が海物語シリーズとジャグラーシリーズという市場の2大絶対王道ノーマル・確変機で100%強固に固められています。資産価値({status_tag})が非常に高く、中古市場に売りに出しても高値で引く手あまたの超優良アセット(筋肉質アセット)を保有しています。商圏内のシニア層や主婦層のライフライン(生活習慣)として機能していますが、弱点は**『若年層向けのフック(刺激)が致命的に不足しており、夜間の高単価スロットの売上を取りこぼしている』**点にあります。")
                        
                        st.markdown("##### 🔴 パチンコ部門(通常P・低貸P)への具体的アクション")
                        st.markdown("4パチ・1パチ問わず、海物語の設置比率はエリア最高水準です。ここは絶対に競合に触らせてはいけない『聖域』。競合が新台スマパチで仕掛けてきても一切無視し、自店の海のメイン島の『命釘のストレスを徹底的に排除する運用』を継続してください。ただし、ミドル実力機(エヴァ等)の特定列だけ、週末にむけて『アケ調整』を行い、シニア層だけでなく会社帰りのサラリーマン層が『仕事帰りに一勝負できる店』としての認知を意図的に作り上げてください。")
                        
                        st.markdown("##### 🔵 スロット部門(通常S・低貸S)への具体的アクション")
                        st.markdown("ジャグラーが強い分、スマスロ(北斗の拳等)の塊(カタマリ)運用が弱点となっています。バラエティのスマスロを細かく買うのは完全に死に金となります。スロットの総台数に対して、看板機種である**『スマスロ北斗の拳』の設置比率を現在の1.2倍まで中古で買い増してください。** その特定列だけ、曜日を絞った『設定5・6の投入プロモーション』を愚直に実行し、死んでいる若年層向けアクティブスロッターの動線を無理矢理にでも引っ張る『部分的なトゲ(アクセント)』を機種一覧に作り出す必要があります。")
                        
                        st.markdown("##### 💵 新台・スマート機・資産の次期投資バランスプラン")
                        st.markdown("新台({new_machine_style})を抑え、資産を高く保つ今のスタイルはROI視点で満点です。今後は、スマート機普及({smart_status})の遅れを逆手に取り、競合のメガ店が『新台の償却負担』で勝手に自滅(回収営業で客を飛ばす)するタイミングを待ってください。大手から溢れたユーザーを、自店の圧倒的な『遊べる定番調整』で受け止め、貯まった利益で半年後に価格の崩落した『実力中古スマスロ』を最安値で大量導入する『時間差・後出しジャンケン戦略』を推奨します。")

                    elif not is_leader and is_low_asset:
                        # 🚨 パターン3:中小型・投資停滞・アセット枯渇型
                        st.markdown("##### 🚨 現状考察:投資の冷え込みが『アセットの致命的劣化』を招いている、顧客離脱寸前の投資停滞ホール")
                        st.markdown(f"**{current_shop_name}** は総台数 `{total_shop_seats}台` と小ぶりなうえ、新台導入({new_machine_style})を極限まで抑えていますが、これは効率的な筋肉質経営ではなく、**『全4部門において予算が完全に枯渇し、市場の人気主要機種(核)を揃えられていない危険な投資停滞状態』**です。")
                        st.markdown("データ上、すべての区分で『【低予算】長期設置機メインの構成』というアラートが出ており、中古価値の残っていない低貢献台や一世代前の型落ち機で設置機種一覧の穴埋めをせざるを得ない形跡が顕著です。大手の隙間を縫うどころか、ユーザーから『魅力的な台が何もない店』と見限られ、稼働の生命線(イン枚数)がジリ貧になる一歩手前の、非常に緊迫したアセット状態と言えます。")
                        
                        st.markdown("##### 🔴 パチンコ部門(通常P・低貸P)への具体的アクション")
                        st.markdown("通常P・低貸Pともに最新のミドル機を追う必要は一切ありません。現在、島に並んでいる『中古価格すらつかない完全に死んでいるP機』を即座に間引き、撤去してください。その空いたスペースに、中古市場で1台数万円まで価格が下落した**『旧作の海物語シリーズ(P大海物語4スペシャルなど)』や、実績のある甘デジの定番機(シンフォギアシリーズの旧作など)**をピンポイントで買い増してください。新台ではなく、シニア層が『この機種なら安心して時間を潰せる』と思える、設置機種一覧の最低限の『見栄えと安心感』を早急に修復することが先決です。")
                        
                        st.markdown("##### 🔵 スロット部門(通常S・低貸S)への具体的アクション")
                        st.markdown("通常Sの荒波スマスロ(ヴァルヴレイヴ等)で競合と張り合うのは、予算的に絶対に不可能です。現在バラエティに散らばっている、誰も回していないメダルAT機をすべて売却(即損切り)し、その原資を**『アイムジャグラーEX』など、中古価格が最も安定しており、かつ客層を選ばないAタイプ部門の補強に全額集中**させてください。台数は少なくても構いません。**『この店はスマスロは弱いが、アイムジャグラーだけはいつも満台で、ベースも遊べる状態になっている』**という、地域住民のラストリゾート(最後の避難所)としてのニッチな信頼を死ぬ気で勝ち取りに行ってください。")
                        
                        st.markdown("##### 💵 新台・スマート機・資産の次期投資バランスプラン")
                        st.markdown("スマート機普及({smart_status})の数値を無理に追うために高額な新台スマスロを1台買うくらいなら、その予算で**『実績のある中古メダル機・Aタイプ機を10台』**買ってください。全方位で競合大手に負けている今、正面衝突は100%不可能です。タブ4等に記録される『手動のユーザー考察メモ(自店に残ってくれている常連の年齢層や、競合が回収に走った曜日)』を徹底的に分析し、**大手が絶対に設定を入れないようなマイナーな定番機種に、自店はピンポイントで『設定4・5』を仕込むような、ゲリラ的なスピード営業**への移行を強く推奨します。")
                    else:
                        # 🏹 パターン4:中小型・筋肉質手堅い型(高ROIゲリラ戦特化)
                        st.markdown("##### 🏹 現状考察:大手の隙間を縫う『中古2周目・局地戦特化型』の超高効率・筋肉質営業店舗")
                        st.markdown(f"**{current_shop_name}** は総台数 `{total_shop_seats}台` と小ぶりながら、無駄な新台入替({new_machine_style})を極限まで排除し、資産価値({status_tag})をA〜Sランクの極めて高い水準でキープしています。大手がメーカーへの貢献度(付き合い)のために数千万円単位でドブに捨てている機械代の負担を、自店は完全にゼロ化できており、コンサルティング視点で最も利益率(ROI)が高い、素晴らしい『ステルス筋肉質経営』を確立しています。")
                        
                        st.markdown("##### 🔴 パチンコ部門(通常P・低貸P)への具体的アクション")
                        st.markdown("通常Pは『海物語』と『定番ライトミドル』の少数精鋭運用を維持してください。大手競合が『新台スマパチの大量導入』を煽ってきたとしても、自店の顧客(シニア・主婦)には響きません。むしろ、大手が新台の回収のために海の調整を締めたタイミングを見計らい、自店の**1パチ(低貸P)の人気定番機の釘をアケてください。** 大手の回収営業にウンザリしたライトユーザーを、自店の圧倒的な居心地の良さと遊べる調整でごっそり囲い込み、商圏内の『低貸のシェア』を裏から乗っ取ってしまいましょう。")
                        
                        st.markdown("##### 🔵 スロット部門(通常S・低貸S)への具体的アクション")
                        st.markdown("通常Sは『マイジャグラーV』などの定番Aタイプが主軸ですが、これに加えて、市場で大ヒットしたあと導入から3ヶ月以上が経過し、中古価格が15万円以下まで大暴落した**『実力証明済みのスマスロ主要機(例:北斗や定番AT機)』を中古市場からピンポイントで2〜3台ずつ拾ってきてください。** 新台当時の10分の1の投資コストで導入できるため、導入初日から『設定5・6』を毎日投入してもお釣りが来ます。新台の看板を掲げずとも、『あの店、新台はないけど北斗に毎日6が入っている』というコアなスロッター間のSNS口コミを誘発させ、大手を急襲するカウンター営業を仕掛けてください。")
                        
                        st.markdown("##### 💵 新台・スマート機・資産の次期投資バランスプラン")
                        st.markdown("スマート機普及({smart_status})に関しては、新台で追うのではなく**『中古2周目(値下がり機)のダイレクト配置』**に徹底してこだわってください。また、データ上の数値だけでは見えない武器として、**タブ4等に日々蓄積される『手動のユーザー考察メモ・スタッフの手動メモ(常連客の生の不満や競合の客層変化)』のテキストを週次で精査してください。** 大型店がマニュアル営業で取りこぼす『細やかな島レイアウトの変更』や『接客・コミュニティ価値』というアナログ戦闘力を最大化することで、大手の鈍重な動きを完全に翻弄する、エリア唯一無二のポジションを死守してください。")

                    st.markdown("---")
                    st.caption(f"※本特別レポートは、Webアプリ内の全分析ロジック(タブ2〜タブ9:規模・パチスロ貸玉区分・機種構成・射幸性・人気機網羅・新台状況・スマート比率・アセット価値)を完全網羅し、100%リアルタイムにクロス分析して自動生成されています。競合店舗の追加や数値データの変動により、内容も即座にダイナミックに変更されます。")

                st.success("各分析結果に基づき、商圏内での競合バランスを考慮した運用を推奨します。")



    # =========================================================
    # --- B. 店舗検索画面 (IDがない場合) ---
    else:
        st.title("🎰 店舗データ検索システム")
        
        st.sidebar.header("🔍 絞り込み条件")
        if not df.empty and "都道府県ID" in df.columns:
            pref_master = df[["都道府県ID", "都道府県名"]].drop_duplicates().sort_values("都道府県ID")
            pref_options = ["すべて"] + pref_master["都道府県名"].tolist()
        else:
            pref_options = ["すべて"]
            
        sel_pref = st.sidebar.selectbox("都道府県 (ID順)", pref_options)
        s_group = st.sidebar.text_input("グループ名検索")
        s_name = st.sidebar.text_input("店舗名検索")
        
        f_df = df.copy()
        if not f_df.empty:
            if sel_pref != "すべて": f_df = f_df[f_df["都道府県名"] == sel_pref]
            if s_group: f_df = f_df[f_df["グループ名"].str.contains(s_group, na=False)]
            if s_name: f_df = f_df[f_df["店舗名"].str.contains(s_name, na=False)]

        st.write(f"該当件数: {len(f_df)} 件")
        button_placeholder = st.empty() 

        if not f_df.empty:
            if "資産価値" not in f_df.columns: f_df["資産価値"] = 0
            f_df["稼働率_表示"] = f_df["稼働率"].apply(format_pct)
            f_df["資産価値_表示"] = f_df["資産価値"].apply(format_yen)
            
            show_cols = ["都道府県名", "店舗名", "グループ名", "総台数", "住所", "稼働率_表示", "資産価値_表示"]
            
            # 選択イベントの取得
            event = st.dataframe(
                f_df[show_cols], 
                on_select="rerun", 
                selection_mode="single-row", 
                use_container_width=True, 
                hide_index=True
            )

            if len(event.selection.rows) > 0:
                idx = event.selection.rows[0]
                selected_row = f_df.iloc[idx]
                with button_placeholder.container():
                    st.markdown("---")
                    col_btn1, col_btn2 = st.columns([3, 1])
                    with col_btn1:
                        st.success(f"現在 **{selected_row['店舗名']}** が選択されています。詳細を開きますか?")
                    with col_btn2:
                        # ブラウザのURLを取得して、パラメータ付きのリンクを作成
                        # target="_blank" が別タブで開く指示です
                        detail_url = f"/?id={selected_row['店舗ID']}"
                        st.markdown(
                            f'<a href="{detail_url}" target="_blank" class="open-detail-btn">🚀 詳細を開く</a>', 
                            unsafe_allow_html=True
                        )
                    st.markdown("---")


# --- 4. メインコントロール部 ---
st.set_page_config(page_title="Pachinko Data Insight", layout="wide")

st.markdown("""

    <style>

    .open-detail-btn {

        display: inline-flex;

        align-items: center;

        justify-content: center;

        background-color: #ff4b4b;

        color: white !important;

        padding: 0.5rem 1rem;

        border-radius: 0.5rem;

        text-decoration: none;

        font-weight: bold;

        border: none;

        width: 100%;

        transition: 0.3s;

    }

    .open-detail-btn:hover {

        background-color: #ff3333;

        box-shadow: 0 4px 8px rgba(0,0,0,0.2);

    }

    </style>

    """, unsafe_allow_html=True)

df, raw_dfs = get_final_master_data()

query_params = st.query_params

if "group_id" in query_params:
    default_mode_index = 1  # グループ別分析
elif "id" in query_params:
    default_mode_index = 0  # 店舗別分析
else:
    default_mode_index = 0  # デフォルト(店舗別分析)

with st.sidebar:
    st.title("🛡️ 分析メニュー")
    # index を指定することで、URLにパラメータがある場合に自動でラジオボタンを切り替える
    mode = st.radio(
        "表示モード切替", 
        ["店舗別分析", "グループ別分析", "機種別分析"],
        index=default_mode_index
    )
    st.markdown("---")
    if st.button("データを最新に更新"):
        st.cache_data.clear()
        st.rerun()

# 選択されたモードに応じて関数を呼び出す
if mode == "店舗別分析":
    show_shop_analysis(df, raw_dfs)
elif mode == "グループ別分析":
    show_group_analysis(df)
elif mode == "機種別分析":
    show_machine_analysis(raw_dfs)