File size: 88,682 Bytes
e6a18b7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import logging
import traceback
import re
import random
from typing import Dict, List, Optional, Any
import json

from scene_detail_templates import SCENE_DETAIL_TEMPLATES
from object_template_fillers import OBJECT_TEMPLATE_FILLERS
from viewpoint_templates import VIEWPOINT_TEMPLATES
from cultural_templates import CULTURAL_TEMPLATES
from lighting_conditions import LIGHTING_CONDITIONS
from confidence_templates import CONFIDENCE_TEMPLATES

class TemplateLoadingError(Exception):
    """模板載入或處理相關錯誤的自訂例外"""
    pass

class TemplateFillError(Exception):
    pass

class TemplateManager:
    """
    模板管理器 - 負責描述模板的載入、管理和填充

    此class 管理所有用於場景描述生成的模板資源,提供模板填充功能,
    並根據場景類型、物體檢測結果和上下文的資訊給出適當的描述內容。
    """

    def __init__(self, custom_templates_db: Optional[Dict] = None):
        """
        初始化模板管理器

        Args:
            custom_templates_db: 可選的自定義模板數據庫,如果提供則會與默認模板合併
        """
        self.logger = logging.getLogger(self.__class__.__name__)
        self.template_registry = {}  

        try:
            # 載入模板數據庫
            self.templates = self._load_templates()

            # 如果提供了自定義模板,則進行合併
            if custom_templates_db:
                self._merge_custom_templates(custom_templates_db)

            # 驗證模板完整性
            self._validate_templates()

            self.logger.info("TemplateManager initialized successfully with %d template categories",
                        len(self.templates))

        except Exception as e:
            error_msg = f"Failed to initialize TemplateManager: {str(e)}"
            self.logger.error(f"{error_msg}\n{traceback.format_exc()}")
            # 初始化基本的空模板
            self.templates = self._initialize_fallback_templates()

    def _load_templates(self) -> Dict:
        """
        載入所有描述模板

        Returns:
            Dict: 包含所有模板類別的字典
        """
        try:
            templates = {}

            # 載入場景詳細描述模板
            self.logger.debug("Loading scene detail templates")
            try:
                templates["scene_detail_templates"] = SCENE_DETAIL_TEMPLATES
            except NameError:
                self.logger.warning("SCENE_DETAIL_TEMPLATES not defined, using empty dict")
                templates["scene_detail_templates"] = {}

            # 載入物體模板填充器
            self.logger.debug("Loading object template fillers")
            try:
                templates["object_template_fillers"] = OBJECT_TEMPLATE_FILLERS
            except NameError:
                self.logger.warning("OBJECT_TEMPLATE_FILLERS not defined, using empty dict")
                templates["object_template_fillers"] = {}

            # 載入視角模板
            self.logger.debug("Loading viewpoint templates")
            try:
                templates["viewpoint_templates"] = VIEWPOINT_TEMPLATES
            except NameError:
                self.logger.warning("VIEWPOINT_TEMPLATES not defined, using empty dict")
                templates["viewpoint_templates"] = {}

            # 載入文化模板
            self.logger.debug("Loading cultural templates")
            try:
                templates["cultural_templates"] = CULTURAL_TEMPLATES
            except NameError:
                self.logger.warning("CULTURAL_TEMPLATES not defined, using empty dict")
                templates["cultural_templates"] = {}

            # 從照明條件模組載入照明模板
            self.logger.debug("Loading lighting templates")
            try:
                templates["lighting_templates"] = self._extract_lighting_templates()
            except Exception as e:
                self.logger.warning(f"Failed to extract lighting templates: {str(e)}")
                templates["lighting_templates"] = {}

            # 載入信心度模板
            self.logger.debug("Loading confidence templates")
            try:
                templates["confidence_templates"] = CONFIDENCE_TEMPLATES
            except NameError:
                self.logger.warning("CONFIDENCE_TEMPLATES not defined, using empty dict")
                templates["confidence_templates"] = {}

            # 初始化默認模板(當成備份)
            self._initialize_default_templates(templates)

            self.logger.info("Successfully loaded %d template categories", len(templates))
            return templates

        except Exception as e:
            error_msg = f"Unexpected error during template loading: {str(e)}"
            self.logger.error(f"{error_msg}\n{traceback.format_exc()}")
            # 返回基本模板
            return self._initialize_fallback_templates()

    def _initialize_template_registry(self) -> Dict[str, Dict[str, Any]]:
        """
        初始化模板,包含各種場景類型的結構化模板

        Returns:
            Dict[str, Dict[str, Any]]: 模板註冊表字典
        """
        try:
            template_registry = {
                "indoor_detailed": {
                    "scene_type": "indoor",
                    "complexity": "high",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "This indoor scene presents a comprehensive view of a well-organized living space."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "functional_areas",
                            "detail_level": "detailed"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_category",
                            "include_counts": True
                        },
                        {
                            "type": "conclusion",
                            "style": "analytical"
                        }
                    ]
                },

                "indoor_moderate": {
                    "scene_type": "indoor",
                    "complexity": "medium",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "The indoor environment displays organized functional areas."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "main_areas",
                            "detail_level": "moderate"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_function",
                            "include_counts": False
                        },
                        {
                            "type": "conclusion",
                            "style": "descriptive"
                        }
                    ]
                },

                "indoor_simple": {
                    "scene_type": "indoor",
                    "complexity": "low",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "An indoor space with visible furniture and household items."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "basic_areas",
                            "detail_level": "simple"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "general",
                            "include_counts": False
                        }
                    ]
                },

                "outdoor_detailed": {
                    "scene_type": "outdoor",
                    "complexity": "high",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "This outdoor scene captures a dynamic urban environment with multiple activity zones."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "activity_areas",
                            "detail_level": "detailed"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_location",
                            "include_counts": True
                        },
                        {
                            "type": "conclusion",
                            "style": "environmental"
                        }
                    ]
                },

                "outdoor_moderate": {
                    "scene_type": "outdoor",
                    "complexity": "medium",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "The outdoor scene shows organized public spaces and pedestrian areas."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "public_areas",
                            "detail_level": "moderate"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_type",
                            "include_counts": False
                        },
                        {
                            "type": "conclusion",
                            "style": "observational"
                        }
                    ]
                },

                "outdoor_simple": {
                    "scene_type": "outdoor",
                    "complexity": "low",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "An outdoor area with pedestrians and urban elements."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "basic_areas",
                            "detail_level": "simple"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "general",
                            "include_counts": False
                        }
                    ]
                },

                "commercial_detailed": {
                    "scene_type": "commercial",
                    "complexity": "high",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "This commercial environment demonstrates organized retail and customer service areas."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "service_areas",
                            "detail_level": "detailed"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_function",
                            "include_counts": True
                        },
                        {
                            "type": "conclusion",
                            "style": "business"
                        }
                    ]
                },

                "transportation_detailed": {
                    "scene_type": "transportation",
                    "complexity": "high",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "This transportation hub features organized passenger facilities and transit infrastructure."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "transit_areas",
                            "detail_level": "detailed"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "by_transit_function",
                            "include_counts": True
                        },
                        {
                            "type": "conclusion",
                            "style": "infrastructure"
                        }
                    ]
                },

                "default": {
                    "scene_type": "general",
                    "complexity": "medium",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "The scene displays various elements organized across functional areas."
                        },
                        {
                            "type": "zone_analysis",
                            "priority": "general_areas",
                            "detail_level": "moderate"
                        },
                        {
                            "type": "object_summary",
                            "grouping": "general",
                            "include_counts": False
                        },
                        {
                            "type": "conclusion",
                            "style": "general"
                        }
                    ]
                }
            }

            self.logger.debug(f"Initialized template registry with {len(template_registry)} templates")
            return template_registry

        except Exception as e:
            error_msg = f"Error initializing template registry: {str(e)}"
            self.logger.error(f"{error_msg}\n{traceback.format_exc()}")
            # 返回最基本的註冊表
            return {
                "default": {
                    "scene_type": "general",
                    "complexity": "low",
                    "structure": [
                        {
                            "type": "opening",
                            "content": "Scene analysis completed with identified objects and areas."
                        }
                    ]
                }
            }

    def get_template_by_scene_type(self, scene_type: str, detected_objects: List[Dict],
                              functional_zones: Dict) -> str:
        """
        根據場景類型選擇合適的模板並進行標準化處理

        Args:
            scene_type: 場景類型
            detected_objects: 檢測到的物件列表
            functional_zones: 功能區域字典

        Returns:
            str: 標準化後的模板字符串
        """
        try:
            # 獲取場景的物件統計信息
            object_stats = self._analyze_scene_composition(detected_objects)
            zone_count = len(functional_zones) if functional_zones else 0

            # 根據場景複雜度和類型選擇模板
            if scene_type in self.templates:
                scene_templates = self.templates[scene_type]

                # 根據複雜度選擇合適的模板變體
                if zone_count >= 3 and object_stats.get("total_objects", 0) >= 10:
                    template_key = "complex"
                elif zone_count >= 2 or object_stats.get("total_objects", 0) >= 5:
                    template_key = "moderate"
                else:
                    template_key = "simple"

                if template_key in scene_templates:
                    raw_template = scene_templates[template_key]
                else:
                    raw_template = scene_templates.get("default", scene_templates[list(scene_templates.keys())[0]])
            else:
                # 如果沒有特定場景的模板,使用通用模板
                raw_template = self._get_generic_template(object_stats, zone_count)

            # 標準化模板中的佔位符和格式
            standardized_template = self._standardize_template_format(raw_template)
            return standardized_template

        except Exception as e:
            logger.error(f"Error selecting template for scene type '{scene_type}': {str(e)}")
            return self._get_fallback_template()

    def _analyze_scene_composition(self, detected_objects: List[Dict]) -> Dict:
        """
        分析場景組成以確定模板複雜度

        Args:
            detected_objects: 檢測到的物件列表

        Returns:
            Dict: 場景組成統計信息
        """
        try:
            total_objects = len(detected_objects)

            # 統計不同類型的物件
            object_categories = {}
            for obj in detected_objects:
                class_name = obj.get("class_name", "unknown")
                object_categories[class_name] = object_categories.get(class_name, 0) + 1

            # 計算場景多樣性
            unique_categories = len(object_categories)

            return {
                "total_objects": total_objects,
                "unique_categories": unique_categories,
                "category_distribution": object_categories,
                "complexity_score": min(total_objects * 0.3 + unique_categories * 0.7, 10)
            }

        except Exception as e:
            logger.warning(f"Error analyzing scene composition: {str(e)}")
            return {"total_objects": 0, "unique_categories": 0, "complexity_score": 0}

    def _get_generic_template(self, object_stats: Dict, zone_count: int) -> str:
        """
        獲取通用模板

        Args:
            object_stats: 物件統計信息
            zone_count: 功能區域數量

        Returns:
            str: 通用模板字符串
        """
        try:
            complexity_score = object_stats.get("complexity_score", 0)

            if complexity_score >= 7 or zone_count >= 3:
                return "This scene presents a comprehensive view featuring {functional_area} with {primary_objects}. The spatial organization demonstrates {spatial_arrangement} across multiple {activity_areas}, creating a dynamic environment with diverse elements and clear functional zones."
            elif complexity_score >= 4 or zone_count >= 2:
                return "The scene displays {functional_area} containing {primary_objects}. The arrangement shows {spatial_organization} with distinct areas serving different purposes within the overall space."
            else:
                return "A {scene_description} featuring {primary_objects} arranged in {basic_layout} within the visible area."

        except Exception as e:
            logger.warning(f"Error getting generic template: {str(e)}")
            return self._get_fallback_template()

    def _get_fallback_template(self) -> str:
        """
        獲取備用模板

        Returns:
            str: 備用模板字符串
        """
        return "A scene featuring various elements and organized areas of activity within the visible space."

    def _standardize_template_format(self, template: str) -> str:
        """
        標準化模板格式,確保佔位符和表達方式符合自然語言要求

        Args:
            template: 原始模板字符串

        Returns:
            str: 標準化後的模板字符串
        """
        try:
            if not template:
                return self._get_fallback_template()

            import re
            standardized = template

            # 標準化佔位符格式,移除技術性標記
            placeholder_mapping = {
                r'\{zone_\d+\}': '{functional_area}',
                r'\{object_group_\d+\}': '{primary_objects}',
                r'\{region_\d+\}': '{spatial_area}',
                r'\{category_\d+\}': '{object_category}',
                r'\{area_\d+\}': '{activity_area}',
                r'\{section_\d+\}': '{scene_section}'
            }

            for pattern, replacement in placeholder_mapping.items():
                standardized = re.sub(pattern, replacement, standardized)

            # 標準化常見的技術性術語
            term_replacements = {
                'functional_zones': 'areas of activity',
                'object_detection': 'visible elements',
                'category_regions': 'organized sections',
                'spatial_distribution': 'arrangement throughout the space',
                'viewpoint_analysis': 'perspective view'
            }

            for tech_term, natural_term in term_replacements.items():
                standardized = standardized.replace(tech_term, natural_term)

            # 確保模板語法的自然性
            standardized = self._improve_template_readability(standardized)

            return standardized

        except Exception as e:
            logger.warning(f"Error standardizing template format: {str(e)}")
            return template if template else self._get_fallback_template()

    def _improve_template_readability(self, template: str) -> str:
        """
        改善模板的可讀性和自然性

        Args:
            template: 模板字符串

        Returns:
            str: 改善後的模板字符串
        """
        try:
            import re

            # 移除多餘的空格和換行
            improved = re.sub(r'\s+', ' ', template).strip()

            # 改善句子連接
            improved = improved.replace(' . ', '. ')
            improved = improved.replace(' , ', ', ')
            improved = improved.replace(' ; ', '; ')

            # 確保適當的句號結尾
            if improved and not improved.endswith(('.', '!', '?')):
                improved += '.'

            # 改善常見的表達問題
            readability_fixes = [
                (r'\bthe the\b', 'the'),
                (r'\ba a\b', 'a'),
                (r'\ban an\b', 'an'),
                (r'\bwith with\b', 'with'),
                (r'\bin in\b', 'in'),
                (r'\bof of\b', 'of'),
                (r'\band and\b', 'and')
            ]

            for pattern, replacement in readability_fixes:
                improved = re.sub(pattern, replacement, improved, flags=re.IGNORECASE)

            return improved

        except Exception as e:
            logger.warning(f"Error improving template readability: {str(e)}")
            return template

    def _extract_lighting_templates(self) -> Dict:
        """
        從照明條件模組提取照明描述模板

        Returns:
            Dict: 照明模板字典
        """
        try:
            lighting_templates = {}

            # 從 LIGHTING_CONDITIONS 提取時間描述
            time_descriptions = LIGHTING_CONDITIONS.get("time_descriptions", {})

            for time_key, time_data in time_descriptions.items():
                if isinstance(time_data, dict) and "general" in time_data:
                    lighting_templates[time_key] = time_data["general"]
                else:
                    # 如果數據結構不符合預期,使用備用描述
                    lighting_templates[time_key] = f"The scene is captured during {time_key.replace('_', ' ')}."

            # 確保至少有基本的照明模板
            if not lighting_templates:
                self.logger.warning("No lighting templates found, using defaults")
                lighting_templates = self._get_default_lighting_templates()

            self.logger.debug("Extracted %d lighting templates", len(lighting_templates))
            return lighting_templates

        except Exception as e:
            self.logger.warning(f"Error extracting lighting templates: {str(e)}, using defaults")
            return self._get_default_lighting_templates()

    def _get_default_lighting_templates(self) -> Dict:
        """獲取默認照明模板"""
        return {
            "day_clear": "The scene is captured during clear daylight conditions.",
            "day_overcast": "The scene is captured during overcast daylight.",
            "night": "The scene is captured at night with artificial lighting.",
            "dawn": "The scene is captured during dawn with soft natural lighting.",
            "dusk": "The scene is captured during dusk with diminishing natural light.",
            "unknown": "The lighting conditions are not clearly identifiable."
        }

    def _initialize_default_templates(self, templates: Dict):
        """
        初始化默認模板作為備份機制

        Args:
            templates: 要檢查和補充的模板字典
        """
        try:
            # 置信度模板備份
            if "confidence_templates" not in templates or not templates["confidence_templates"]:
                templates["confidence_templates"] = {
                    "high": "{description} {details}",
                    "medium": "This appears to be {description} {details}",
                    "low": "This might be {description}, but the confidence is low. {details}"
                }

            # 場景詳細模板備份
            if "scene_detail_templates" not in templates or not templates["scene_detail_templates"]:
                templates["scene_detail_templates"] = {
                    "default": ["A scene with various elements and objects."]
                }

            # 物體填充模板備份
            if "object_template_fillers" not in templates or not templates["object_template_fillers"]:
                templates["object_template_fillers"] = {
                    "default": ["various items", "different objects", "multiple elements"]
                }

            # 視角模板備份
            if "viewpoint_templates" not in templates or not templates["viewpoint_templates"]:
                templates["viewpoint_templates"] = {
                    "eye_level": {
                        "prefix": "From eye level, ",
                        "observation": "the scene is viewed straight ahead.",
                        "short_desc": "at eye level"
                    },
                    "aerial": {
                        "prefix": "From above, ",
                        "observation": "the scene is viewed from a bird's-eye perspective.",
                        "short_desc": "from above"
                    },
                    "low_angle": {
                        "prefix": "From a low angle, ",
                        "observation": "the scene is viewed from below looking upward.",
                        "short_desc": "from below"
                    },
                    "elevated": {
                        "prefix": "From an elevated position, ",
                        "observation": "the scene is viewed from a higher vantage point.",
                        "short_desc": "from an elevated position"
                    }
                }

            # 文化模板備份
            if "cultural_templates" not in templates or not templates["cultural_templates"]:
                templates["cultural_templates"] = {
                    "asian": {
                        "elements": ["traditional architectural elements", "cultural signage", "Asian design features"],
                        "description": "The scene displays distinctive Asian cultural characteristics with {elements}."
                    },
                    "european": {
                        "elements": ["classical architecture", "European design elements", "historic features"],
                        "description": "The scene exhibits European architectural and cultural elements including {elements}."
                    }
                }

            self.logger.debug("Default templates initialized as backup")

        except Exception as e:
            self.logger.error(f"Error initializing default templates: {str(e)}")

    def _merge_custom_templates(self, custom_templates: Dict):
        """
        合併自定義模板到現有模板庫

        Args:
            custom_templates: 自定義模板字典
        """
        try:
            for template_category, custom_content in custom_templates.items():
                if template_category in self.templates:
                    if isinstance(self.templates[template_category], dict) and isinstance(custom_content, dict):
                        self.templates[template_category].update(custom_content)
                        self.logger.debug(f"Merged custom templates for category: {template_category}")
                    else:
                        self.templates[template_category] = custom_content
                        self.logger.debug(f"Replaced templates for category: {template_category}")
                else:
                    self.templates[template_category] = custom_content
                    self.logger.debug(f"Added new template category: {template_category}")

            self.logger.info("Successfully merged custom templates")

        except Exception as e:
            self.logger.warning(f"Error merging custom templates: {str(e)}")

    def _validate_templates(self):
        """
        驗證模板完整性和有效性
        """
        try:
            required_categories = [
                "scene_detail_templates",
                "object_template_fillers",
                "viewpoint_templates",
                "cultural_templates",
                "lighting_templates",
                "confidence_templates"
            ]

            missing_categories = []
            for category in required_categories:
                if category not in self.templates:
                    missing_categories.append(category)
                elif not self.templates[category]:
                    self.logger.warning(f"Template category '{category}' is empty")

            if missing_categories:
                error_msg = f"Missing required template categories: {missing_categories}"
                self.logger.warning(error_msg)
                # 為缺失的類別創建空模板
                for category in missing_categories:
                    self.templates[category] = {}

            # 驗證視角模板結構
            self._validate_viewpoint_templates()

            # 驗證文化模板結構
            self._validate_cultural_templates()

            self.logger.debug("Template validation completed successfully")

        except Exception as e:
            error_msg = f"Template validation failed: {str(e)}"
            self.logger.error(f"{error_msg}\n{traceback.format_exc()}")

    def _validate_viewpoint_templates(self):
        """驗證視角模板結構"""
        viewpoint_templates = self.templates.get("viewpoint_templates", {})

        for viewpoint, template_data in viewpoint_templates.items():
            if not isinstance(template_data, dict):
                self.logger.warning(f"Invalid viewpoint template structure for '{viewpoint}'")
                continue

            required_keys = ["prefix", "observation"]
            for key in required_keys:
                if key not in template_data:
                    self.logger.warning(f"Missing '{key}' in viewpoint template '{viewpoint}'")

    def _validate_cultural_templates(self):
        """驗證文化模板結構"""
        cultural_templates = self.templates.get("cultural_templates", {})

        for culture, template_data in cultural_templates.items():
            if not isinstance(template_data, dict):
                self.logger.warning(f"Invalid cultural template structure for '{culture}'")
                continue

            if "elements" not in template_data or "description" not in template_data:
                self.logger.warning(f"Missing required keys in cultural template '{culture}'")

    def get_template(self, category: str, key: Optional[str] = None) -> Any:
        """
        獲取指定類別的模板

        Args:
            category: 模板類別名稱
            key: 可選的具體模板鍵值

        Returns:
            Any: 請求的模板內容,如果不存在則返回空字典或空字符串
        """
        try:
            if category not in self.templates:
                self.logger.warning(f"Template category '{category}' not found")
                return {} if key is None else ""

            if key is None:
                return self.templates[category]

            category_templates = self.templates[category]
            if not isinstance(category_templates, dict):
                self.logger.warning(f"Template category '{category}' is not a dictionary")
                return ""

            if key not in category_templates:
                self.logger.warning(f"Template key '{key}' not found in category '{category}'")
                return ""

            return category_templates[key]

        except Exception as e:
            error_msg = f"Error retrieving template {category}.{key}: {str(e)}"
            self.logger.error(error_msg)
            return {} if key is None else ""

    def fill_template(self, template: str, detected_objects: List[Dict], scene_type: str,
             places365_info: Optional[Dict] = None,
             object_statistics: Optional[Dict] = None) -> str:
        """
        填充模板中的佔位符,增強容錯處理

        Args:
            template: 包含佔位符的模板字符串
            detected_objects: 檢測到的物體列表
            scene_type: 場景類型
            places365_info: Places365場景分類信息
            object_statistics: 物體統計信息

        Returns:
            str: 填充後的模板字符串,確保語法正確
        """
        try:
            self.logger.debug(f"Filling template for scene_type: {scene_type}")

            if not template or not template.strip():
                return "A scene with various elements."

            # 預處理模板,移除可能的問題模式
            template = self._preprocess_template(template)

            # 查找模板中的佔位符
            placeholders = re.findall(r'\{([^}]+)\}', template)
            filled_template = template

            # 獲取模板填充器
            fillers = self.templates.get("object_template_fillers", {})

            # 基於物體統計信息生成替換內容
            statistics_based_replacements = self._generate_statistics_replacements(object_statistics)

            # 生成默認替換內容
            default_replacements = self._generate_default_replacements()

            # 添加Places365上下文信息
            places365_replacements = self._generate_places365_replacements(places365_info)

            # 添加功能區域信息到場景數據中以便後續使用
            scene_functional_zones = None
            if hasattr(self, '_current_functional_zones'):
                scene_functional_zones = self._current_functional_zones

            # 合併所有替換內容(優先順序是統計信息 > Places365 > 默認)
            all_replacements = {**default_replacements, **places365_replacements, **statistics_based_replacements}

            # 填充每個佔位符
            for placeholder in placeholders:
                try:
                    replacement = self._get_placeholder_replacement(
                        placeholder, fillers, all_replacements, detected_objects, scene_type
                    )

                    # 確保替換內容不為空且有意義
                    if not replacement or not replacement.strip():
                        replacement = self._get_emergency_replacement(placeholder)

                    filled_template = filled_template.replace(f"{{{placeholder}}}", replacement)

                except Exception as placeholder_error:
                    self.logger.warning(f"Failed to replace placeholder '{placeholder}': {str(placeholder_error)}")
                    # 使用緊急替換值
                    emergency_replacement = self._get_emergency_replacement(placeholder)
                    filled_template = filled_template.replace(f"{{{placeholder}}}", emergency_replacement)

            # 修復可能的語法問題
            filled_template = self._postprocess_filled_template(filled_template)

            self.logger.debug("Template filling completed successfully")
            return filled_template

        except Exception as e:
            error_msg = f"Error filling template: {str(e)}"
            self.logger.error(f"{error_msg}\n{traceback.format_exc()}")
            # 返回安全的備用內容
            return self._generate_fallback_description(scene_type, detected_objects)

    def _preprocess_template(self, template: str) -> str:
        """
        預處理模板,修復常見問題

        Args:
            template: 原始模板字符串

        Returns:
            str: 預處理後的模板
        """
        try:
            # 移除可能導致問題的模式
            template = re.sub(r'\{[^}]*\}\s*,\s*\{[^}]*\}', '{combined_elements}', template)

            # 確保模板不以逗號開始
            template = re.sub(r'^[,\s]*', '', template)

            return template.strip()

        except Exception as e:
            self.logger.warning(f"Error preprocessing template: {str(e)}")
            return template

    def _get_emergency_replacement(self, placeholder: str) -> str:
        """
        獲取緊急替換值,確保不會產生語法錯誤

        Args:
            placeholder: 佔位符名稱

        Returns:
            str: 安全的替換值
        """
        emergency_replacements = {
            "crossing_pattern": "pedestrian walkways",
            "pedestrian_behavior": "people moving through the area",
            "traffic_pattern": "vehicle movement",
            "scene_setting": "this location",
            "urban_elements": "city features",
            "street_elements": "urban components"
        }

        if placeholder in emergency_replacements:
            return emergency_replacements[placeholder]

        # 基於佔位符名稱生成合理的替換
        cleaned = placeholder.replace('_', ' ')
        if len(cleaned.split()) > 1:
            return cleaned
        else:
            return f"various {cleaned}"

    def _postprocess_filled_template(self, filled_template: str) -> str:
        """
        後處理填充完成的模板,修復語法問題

        Args:
            filled_template: 填充後的模板字符串

        Returns:
            str: 修復後的模板字符串
        """
        try:
            # 修復 "In , " 模式
            filled_template = re.sub(r'\bIn\s*,\s*', 'In this scene, ', filled_template)
            filled_template = re.sub(r'\bAt\s*,\s*', 'At this location, ', filled_template)
            filled_template = re.sub(r'\bWithin\s*,\s*', 'Within this area, ', filled_template)

            # 修復連續逗號
            filled_template = re.sub(r',\s*,', ',', filled_template)

            # 修復開頭的逗號
            filled_template = re.sub(r'^[,\s]*', '', filled_template)

            # 確保首字母大寫
            if filled_template and not filled_template[0].isupper():
                filled_template = filled_template[0].upper() + filled_template[1:]

            # 確保以句號結尾
            if filled_template and not filled_template.endswith(('.', '!', '?')):
                filled_template += '.'

            return filled_template.strip()

        except Exception as e:
            self.logger.warning(f"Error postprocessing filled template: {str(e)}")
            return filled_template

    def _generate_fallback_description(self, scene_type: str, detected_objects: List[Dict]) -> str:
        """
        生成備用描述,當模板填充完全失敗時使用

        Args:
            scene_type: 場景類型
            detected_objects: 檢測到的物體列表

        Returns:
            str: 備用描述
        """
        try:
            object_count = len(detected_objects)

            if object_count == 0:
                return f"A {scene_type.replace('_', ' ')} scene."
            elif object_count == 1:
                return f"A {scene_type.replace('_', ' ')} scene with one visible element."
            else:
                return f"A {scene_type.replace('_', ' ')} scene with {object_count} visible elements."

        except Exception as e:
            self.logger.warning(f"Error generating fallback description: {str(e)}")
            return "A scene with various elements."

    def _generate_statistics_replacements(self, object_statistics: Optional[Dict]) -> Dict[str, str]:
        """
        基於物體統計信息生成模板替換內容

        Args:
            object_statistics: 物體統計信息

        Returns:
            Dict[str, str]: 統計信息基礎的替換內容
        """
        replacements = {}

        if not object_statistics:
            return replacements

        try:
            # 處理植物元素
            if "potted plant" in object_statistics:
                count = object_statistics["potted plant"]["count"]
                if count == 1:
                    replacements["plant_elements"] = "a potted plant"
                elif count <= 3:
                    replacements["plant_elements"] = f"{count} potted plants"
                else:
                    replacements["plant_elements"] = f"multiple potted plants ({count} total)"

            # 處理座位
            if "chair" in object_statistics:
                count = object_statistics["chair"]["count"]
                if count == 1:
                    replacements["seating"] = "a chair"
                elif count <= 4:
                    replacements["seating"] = f"{count} chairs"
                else:
                    replacements["seating"] = f"numerous chairs ({count} total)"

            # 處理人員
            if "person" in object_statistics:
                count = object_statistics["person"]["count"]
                if count == 1:
                    replacements["people_and_vehicles"] = "a person"
                    replacements["pedestrian_flow"] = "an individual walking"
                elif count <= 5:
                    replacements["people_and_vehicles"] = f"{count} people"
                    replacements["pedestrian_flow"] = f"{count} people walking"
                else:
                    replacements["people_and_vehicles"] = f"many people ({count} individuals)"
                    replacements["pedestrian_flow"] = f"a crowd of {count} people"

            # 處理桌子設置
            if "dining table" in object_statistics:
                count = object_statistics["dining table"]["count"]
                if count == 1:
                    replacements["table_setup"] = "a dining table"
                    replacements["table_description"] = "a dining surface"
                else:
                    replacements["table_setup"] = f"{count} dining tables"
                    replacements["table_description"] = f"{count} dining surfaces"

            self.logger.debug(f"Generated {len(replacements)} statistics-based replacements")

        except Exception as e:
            self.logger.warning(f"Error generating statistics replacements: {str(e)}")

        return replacements

    def _generate_places365_replacements(self, places365_info: Optional[Dict]) -> Dict[str, str]:
        """
        基於Places365信息生成模板替換內容

        Args:
            places365_info: Places365場景分類信息

        Returns:
            Dict[str, str]: Places365基礎的替換內容
        """
        replacements = {}

        if not places365_info or places365_info.get('confidence', 0) <= 0.35:
            replacements["places365_context"] = ""
            replacements["places365_atmosphere"] = ""
            return replacements

        try:
            scene_label = places365_info.get('scene_label', '').replace('_', ' ')
            attributes = places365_info.get('attributes', [])

            # 生成場景上下文
            if scene_label:
                replacements["places365_context"] = f"characteristic of a {scene_label}"
            else:
                replacements["places365_context"] = ""

            # 生成氛圍描述
            if 'natural_lighting' in attributes:
                replacements["places365_atmosphere"] = "with natural illumination"
            elif 'artificial_lighting' in attributes:
                replacements["places365_atmosphere"] = "under artificial lighting"
            else:
                replacements["places365_atmosphere"] = ""

            self.logger.debug("Generated Places365-based replacements")

        except Exception as e:
            self.logger.warning(f"Error generating Places365 replacements: {str(e)}")
            replacements["places365_context"] = ""
            replacements["places365_atmosphere"] = ""

        return replacements

    def _generate_default_replacements(self) -> Dict[str, str]:
        """
        生成默認的模板替換內容

        Returns:
            Dict[str, str]: 默認替換內容
        """
        return {

            "scene_introduction": "this scene",
            "location_prefix": "this location",
            "setting_description": "this setting",
            "area_description": "this area",
            "environment_description": "this environment",
            "spatial_introduction": "this space",

            # 室內相關
            "furniture": "various furniture pieces",
            "seating": "comfortable seating",
            "electronics": "entertainment devices",
            "bed_type": "a bed",
            "bed_location": "room",
            "bed_description": "sleeping arrangements",
            "extras": "personal items",
            "table_setup": "a dining table and chairs",
            "table_description": "a dining surface",
            "dining_items": "dining furniture and tableware",
            "appliances": "kitchen appliances",
            "kitchen_items": "cooking utensils and dishware",
            "cooking_equipment": "cooking equipment",
            "office_equipment": "work-related furniture and devices",
            "desk_setup": "a desk and chair",
            "computer_equipment": "electronic devices",

            # 室外/城市相關
            "traffic_description": "vehicles and pedestrians",
            "people_and_vehicles": "people and various vehicles",
            "street_elements": "urban infrastructure",
            "park_features": "benches and greenery",
            "outdoor_elements": "natural features",
            "park_description": "outdoor amenities",
            "store_elements": "merchandise displays",
            "shopping_activity": "customers browse and shop",
            "store_items": "products for sale",

            # 高級餐廳相關
            "design_elements": "elegant decor",
            "lighting": "stylish lighting fixtures",

            # 亞洲商業街相
            "storefront_features": "compact shops",
            "pedestrian_flow": "people walking",
            "asian_elements": "distinctive cultural elements",
            "cultural_elements": "traditional design features",
            "signage": "colorful signs",
            "street_activities": "busy urban activity",

            # 金融區相關
            "buildings": "tall buildings",
            "traffic_elements": "vehicles",
            "skyscrapers": "high-rise buildings",
            "road_features": "wide streets",
            "architectural_elements": "modern architecture",
            "city_landmarks": "prominent structures",

            # 十字路口相關
            "crossing_pattern": "clearly marked pedestrian crossings",
            "pedestrian_behavior": "careful pedestrian movement",
            "pedestrian_density": "multiple groups of pedestrians",
            "traffic_pattern": "well-regulated traffic flow",
            "pedestrian_flow": "steady pedestrian movement",
            "traffic_description": "active urban traffic",
            "people_and_vehicles": "pedestrians and vehicles",
            "street_elements": "urban infrastructure elements",

            # 交通相關
            "transit_vehicles": "public transportation vehicles",
            "passenger_activity": "commuter movement",
            "transportation_modes": "various transit options",
            "passenger_needs": "waiting areas",
            "transit_infrastructure": "transit facilities",
            "passenger_movement": "commuter flow",

            # 購物區相關
            "retail_elements": "shops and displays",
            "store_types": "various retail establishments",
            "walkway_features": "pedestrian pathways",
            "commercial_signage": "store signs",
            "consumer_behavior": "shopping activities",

            # 空中視角相關
            "commercial_layout": "organized retail areas",
            "pedestrian_pattern": "people movement patterns",
            "gathering_features": "public gathering spaces",
            "movement_pattern": "crowd flow patterns",
            "urban_elements": "city infrastructure",
            "public_activity": "social interaction",

            # 文化特定元素
            "stall_elements": "vendor booths",
            "lighting_features": "decorative lights",
            "food_elements": "food offerings",
            "vendor_stalls": "market stalls",
            "nighttime_activity": "evening commerce",
            "cultural_lighting": "traditional lighting",
            "night_market_sounds": "lively market sounds",
            "evening_crowd_behavior": "nighttime social activity",
            "architectural_elements": "cultural buildings",
            "religious_structures": "sacred buildings",
            "decorative_features": "ornamental designs",
            "cultural_practices": "traditional activities",
            "temple_architecture": "religious structures",
            "sensory_elements": "atmospheric elements",
            "visitor_activities": "cultural experiences",
            "ritual_activities": "ceremonial practices",
            "cultural_symbols": "meaningful symbols",
            "architectural_style": "historical buildings",
            "historic_elements": "traditional architecture",
            "urban_design": "city planning elements",
            "social_behaviors": "public interactions",
            "european_features": "European architectural details",
            "tourist_activities": "visitor activities",
            "local_customs": "regional practices",

            # 時間特定元素
            "lighting_effects": "artificial lighting",
            "shadow_patterns": "light and shadow",
            "urban_features": "city elements",
            "illuminated_elements": "lit structures",
            "evening_activities": "nighttime activities",
            "light_sources": "lighting points",
            "lit_areas": "illuminated spaces",
            "shadowed_zones": "darker areas",
            "illuminated_signage": "bright signs",
            "colorful_lighting": "multicolored lights",
            "neon_elements": "neon signs",
            "night_crowd_behavior": "evening social patterns",
            "light_displays": "lighting installations",
            "building_features": "architectural elements",
            "nightlife_activities": "evening entertainment",
            "lighting_modifier": "bright",

            # 混合環境元素
            "transitional_elements": "connecting features",
            "indoor_features": "interior elements",
            "outdoor_setting": "exterior spaces",
            "interior_amenities": "inside comforts",
            "exterior_features": "outside elements",
            "inside_elements": "interior design",
            "outside_spaces": "outdoor areas",
            "dual_environment_benefits": "combined settings",
            "passenger_activities": "waiting behaviors",
            "transportation_types": "transit vehicles",
            "sheltered_elements": "covered areas",
            "exposed_areas": "open sections",
            "waiting_behaviors": "passenger activities",
            "indoor_facilities": "inside services",
            "platform_features": "transit platform elements",
            "transit_routines": "transportation procedures",

            # 專門場所元素
            "seating_arrangement": "spectator seating",
            "playing_surface": "athletic field",
            "sporting_activities": "sports events",
            "spectator_facilities": "viewer accommodations",
            "competition_space": "sports arena",
            "sports_events": "athletic competitions",
            "viewing_areas": "audience sections",
            "field_elements": "field markings and equipment",
            "game_activities": "competitive play",
            "construction_equipment": "building machinery",
            "building_materials": "construction supplies",
            "construction_activities": "building work",
            "work_elements": "construction tools",
            "structural_components": "building structures",
            "site_equipment": "construction gear",
            "raw_materials": "building supplies",
            "construction_process": "building phases",
            "medical_elements": "healthcare equipment",
            "clinical_activities": "medical procedures",
            "facility_design": "healthcare layout",
            "healthcare_features": "medical facilities",
            "patient_interactions": "care activities",
            "equipment_types": "medical devices",
            "care_procedures": "health services",
            "treatment_spaces": "clinical areas",
            "educational_furniture": "learning furniture",
            "learning_activities": "educational practices",
            "instructional_design": "teaching layout",
            "classroom_elements": "school equipment",
            "teaching_methods": "educational approaches",
            "student_engagement": "learning participation",
            "learning_spaces": "educational areas",
            "educational_tools": "teaching resources",
            "knowledge_transfer": "learning exchanges"
        }

    def _generate_objects_summary(self, detected_objects: List[Dict]) -> str:
        """
        基於檢測物件生成自然語言摘要,按重要性排序

        Args:
            detected_objects: 檢測到的物件列表

        Returns:
            str: 物件摘要描述
        """
        try:
            # detected_objects 裡有幾個 traffic light)
            tl_count = len([obj for obj in detected_objects if obj.get("class_name","") == "traffic light"])
            # print(f"[DEBUG] _generate_objects_summary 傳入的 detected_objects 中 traffic light: {tl_count} 個")
            for obj in detected_objects:
                if obj.get("class_name","") == "traffic light":
                    print(f"    - conf={obj.get('confidence',0):.4f}, bbox={obj.get('bbox')}, region={obj.get('region')}")

            if not detected_objects:
                return "various elements"

            # calculate object statistic
            object_counts = {}
            total_confidence = 0

            for obj in detected_objects:
                class_name = obj.get("class_name", "unknown")
                confidence = obj.get("confidence", 0.5)

                if class_name not in object_counts:
                    object_counts[class_name] = {"count": 0, "total_confidence": 0}

                object_counts[class_name]["count"] += 1
                object_counts[class_name]["total_confidence"] += confidence
                total_confidence += confidence

            # 計算平均置信度並排序
            sorted_objects = []
            for class_name, stats in object_counts.items():
                avg_confidence = stats["total_confidence"] / stats["count"]
                count = stats["count"]

                # 重要性評分:結合數量和置信度
                importance_score = (count * 0.6) + (avg_confidence * 0.4)
                sorted_objects.append((class_name, count, importance_score))

            # 按重要性排序,取前5個最重要的物件
            sorted_objects.sort(key=lambda x: x[2], reverse=True)
            top_objects = sorted_objects[:5]

            # 生成自然語言描述
            descriptions = []
            for class_name, count, _ in top_objects:
                clean_name = class_name.replace('_', ' ')
                if count == 1:
                    article = "an" if clean_name[0].lower() in 'aeiou' else "a"
                    descriptions.append(f"{article} {clean_name}")
                else:
                    descriptions.append(f"{count} {clean_name}s")

            # 組合描述
            if len(descriptions) == 1:
                return descriptions[0]
            elif len(descriptions) == 2:
                return f"{descriptions[0]} and {descriptions[1]}"
            else:
                return ", ".join(descriptions[:-1]) + f", and {descriptions[-1]}"

        except Exception as e:
            self.logger.warning(f"Error generating objects summary: {str(e)}")
            return "various elements"

    def _get_placeholder_replacement(self, placeholder: str, fillers: Dict,
                           all_replacements: Dict, detected_objects: List[Dict],
                           scene_type: str) -> str:
        """
        獲取特定佔位符的替換內容,確保永遠不返回空值
        """
        try:
            # 優先處理動態內容生成的佔位符
            dynamic_placeholders = [
                'primary_objects', 'detected_objects_summary', 'main_objects',
                'functional_area', 'functional_zones_description', 'scene_elements'
            ]

            if placeholder in dynamic_placeholders:
                dynamic_content = self._generate_objects_summary(detected_objects)
                if dynamic_content and dynamic_content.strip():
                    return dynamic_content.strip()

            # 檢查預定義替換內容
            if placeholder in all_replacements:
                replacement = all_replacements[placeholder]
                if replacement and replacement.strip():
                    return replacement.strip()

            # 檢查物體模板填充器
            if placeholder in fillers:
                options = fillers[placeholder]
                if options and isinstance(options, list):
                    valid_options = [opt.strip() for opt in options if opt and str(opt).strip()]
                    if valid_options:
                        num_items = min(len(valid_options), random.randint(1, 3))
                        selected_items = random.sample(valid_options, num_items)

                        if len(selected_items) == 1:
                            return selected_items[0]
                        elif len(selected_items) == 2:
                            return f"{selected_items[0]} and {selected_items[1]}"
                        else:
                            return ", ".join(selected_items[:-1]) + f", and {selected_items[-1]}"

            # 基於檢測對象生成動態內容
            scene_specific_replacement = self._generate_scene_specific_content(
                placeholder, detected_objects, scene_type
            )
            if scene_specific_replacement and scene_specific_replacement.strip():
                return scene_specific_replacement.strip()

            # 通用備用字典 - 擴展版本
            fallback_replacements = {
                # 交通和城市相關
                "crossing_pattern": "pedestrian crosswalks",
                "pedestrian_behavior": "people moving carefully",
                "traffic_pattern": "vehicle movement",
                "urban_elements": "city infrastructure",
                "street_elements": "urban features",
                "intersection_features": "traffic management systems",
                "pedestrian_density": "groups of people",
                "pedestrian_flow": "pedestrian movement",
                "traffic_description": "vehicle traffic",
                "people_and_vehicles": "pedestrians and cars",

                # 場景設置相關
                "scene_setting": "this urban environment",
                "location_context": "the area",
                "spatial_context": "the scene",
                "environmental_context": "this location",

                # 常見的家具和設備
                "furniture": "various furniture pieces",
                "seating": "seating arrangements",
                "electronics": "electronic devices",
                "appliances": "household appliances",

                # 活動和行為
                "activities": "various activities",
                "interactions": "people interacting",
                "movement": "movement patterns",

                # 照明和氛圍
                "lighting_conditions": "ambient lighting",
                "atmosphere": "the overall atmosphere",
                "ambiance": "environmental ambiance",

                # 空間描述
                "spatial_arrangement": "spatial organization",
                "layout": "the layout",
                "composition": "visual composition",

                # 物體和元素
                "objects": "various objects",
                "elements": "scene elements",
                "features": "notable features",
                "details": "observable details"
            }

            if placeholder in fallback_replacements:
                return fallback_replacements[placeholder]

            # 基於場景類型的智能默認值
            scene_based_defaults = self._get_scene_based_default(placeholder, scene_type)
            if scene_based_defaults:
                return scene_based_defaults

            # 最終備用:將下劃線轉換為有意義的短語
            cleaned_placeholder = placeholder.replace('_', ' ')

            # 對常見模式提供更好的默認值
            if placeholder.endswith('_pattern'):
                return f"{cleaned_placeholder.replace(' pattern', '')} arrangement"
            elif placeholder.endswith('_behavior'):
                return f"{cleaned_placeholder.replace(' behavior', '')} activity"
            elif placeholder.endswith('_description'):
                return f"{cleaned_placeholder.replace(' description', '')} elements"
            elif placeholder.endswith('_elements'):
                return cleaned_placeholder
            elif placeholder.endswith('_features'):
                return cleaned_placeholder
            else:
                return cleaned_placeholder if cleaned_placeholder != placeholder else "various elements"

        except Exception as e:
            self.logger.warning(f"Error getting replacement for placeholder '{placeholder}': {str(e)}")
            # 確保即使在異常情況下也返回有意義的內容
            return placeholder.replace('_', ' ') if placeholder else "scene elements"

    def _get_scene_based_default(self, placeholder: str, scene_type: str) -> Optional[str]:
        """
        基於場景類型提供智能默認值

        Args:
            placeholder: 佔位符名稱
            scene_type: 場景類型

        Returns:
            Optional[str]: 場景特定的默認值或None
        """
        try:
            # 針對不同場景類型的特定默認值
            scene_defaults = {
                "urban_intersection": {
                    "crossing_pattern": "marked crosswalks",
                    "pedestrian_behavior": "pedestrians crossing carefully",
                    "traffic_pattern": "controlled traffic flow"
                },
                "city_street": {
                    "traffic_description": "urban vehicle traffic",
                    "street_elements": "city infrastructure",
                    "people_and_vehicles": "pedestrians and vehicles"
                },
                "living_room": {
                    "furniture": "comfortable living room furniture",
                    "seating": "sofas and chairs",
                    "electronics": "entertainment equipment"
                },
                "kitchen": {
                    "appliances": "kitchen appliances",
                    "cooking_equipment": "cooking tools and equipment"
                },
                "office_workspace": {
                    "office_equipment": "work furniture and devices",
                    "desk_setup": "desk and office chair"
                }
            }

            if scene_type in scene_defaults and placeholder in scene_defaults[scene_type]:
                return scene_defaults[scene_type][placeholder]

            return None

        except Exception as e:
            self.logger.warning(f"Error getting scene-based default for '{placeholder}' in '{scene_type}': {str(e)}")
            return None

    def _generate_scene_specific_content(self, placeholder: str, detected_objects: List[Dict],
                                       scene_type: str) -> Optional[str]:
        """
        基於場景特定邏輯生成佔位符內容

        Args:
            placeholder: 佔位符名稱
            detected_objects: 檢測到的物體列表
            scene_type: 場景類型

        Returns:
            Optional[str]: 生成的內容或None
        """
        try:
            if placeholder == "furniture":
                # 提取家具物品
                furniture_ids = [56, 57, 58, 59, 60, 61]  # 家具類別ID
                furniture_objects = [obj for obj in detected_objects if obj.get("class_id") in furniture_ids]

                if furniture_objects:
                    furniture_names = [obj.get("class_name", "furniture") for obj in furniture_objects[:3]]
                    unique_names = list(set(furniture_names))
                    return ", ".join(unique_names) if len(unique_names) > 1 else unique_names[0]
                return "various furniture items"

            elif placeholder == "electronics":
                # 提取電子設備
                electronics_ids = [62, 63, 64, 65, 66, 67, 68, 69, 70]  # 電子設備類別ID
                electronics_objects = [obj for obj in detected_objects if obj.get("class_id") in electronics_ids]

                if electronics_objects:
                    electronics_names = [obj.get("class_name", "electronic device") for obj in electronics_objects[:3]]
                    unique_names = list(set(electronics_names))
                    return ", ".join(unique_names) if len(unique_names) > 1 else unique_names[0]
                return "electronic devices"

            elif placeholder == "people_count":
                # 計算人數
                people_count = len([obj for obj in detected_objects if obj.get("class_id") == 0])

                if people_count == 0:
                    return "no people"
                elif people_count == 1:
                    return "one person"
                elif people_count < 5:
                    return f"{people_count} people"
                else:
                    return "several people"

            elif placeholder == "seating":
                # 提取座位物品
                seating_ids = [56, 57]  # chair, sofa
                seating_objects = [obj for obj in detected_objects if obj.get("class_id") in seating_ids]

                if seating_objects:
                    seating_names = [obj.get("class_name", "seating") for obj in seating_objects[:2]]
                    unique_names = list(set(seating_names))
                    return ", ".join(unique_names) if len(unique_names) > 1 else unique_names[0]
                return "seating arrangements"

            # 如果沒有匹配的特定邏輯,返回None
            return None

        except Exception as e:
            self.logger.warning(f"Error generating scene-specific content for '{placeholder}': {str(e)}")
            return None

    def get_confidence_template(self, confidence_level: str) -> str:
        """
        獲取指定信心度級別的模板

        Args:
            confidence_level: 信心度級別 ('high', 'medium', 'low')

        Returns:
            str: 信心度模板字符串
        """
        try:
            confidence_templates = self.templates.get("confidence_templates", {})

            if confidence_level in confidence_templates:
                return confidence_templates[confidence_level]

            # 備用模板
            fallback_templates = {
                "high": "{description} {details}",
                "medium": "This appears to be {description} {details}",
                "low": "This might be {description}, but the confidence is low. {details}"
            }

            return fallback_templates.get(confidence_level, "{description} {details}")

        except Exception as e:
            self.logger.warning(f"Error getting confidence template for '{confidence_level}': {str(e)}")
            return "{description} {details}"

    def get_lighting_template(self, lighting_type: str) -> str:
        """
        獲取指定照明類型的模板

        Args:
            lighting_type: 照明類型

        Returns:
            str: 照明描述模板
        """
        try:
            lighting_templates = self.templates.get("lighting_templates", {})

            if lighting_type in lighting_templates:
                return lighting_templates[lighting_type]

            # 備用模板
            return f"The scene is captured with {lighting_type.replace('_', ' ')} lighting conditions."

        except Exception as e:
            self.logger.warning(f"Error getting lighting template for '{lighting_type}': {str(e)}")
            return "The lighting conditions are not clearly identifiable."

    def get_viewpoint_template(self, viewpoint: str) -> Dict[str, str]:
        """
        獲取指定視角的模板

        Args:
            viewpoint: 視角類型

        Returns:
            Dict[str, str]: 包含prefix、observation等鍵的視角模板字典
        """
        try:
            viewpoint_templates = self.templates.get("viewpoint_templates", {})

            if viewpoint in viewpoint_templates:
                return viewpoint_templates[viewpoint]

            # 備用模板
            fallback_templates = {
                "eye_level": {
                    "prefix": "From eye level, ",
                    "observation": "the scene is viewed straight ahead.",
                    "short_desc": "at eye level"
                },
                "aerial": {
                    "prefix": "From above, ",
                    "observation": "the scene is viewed from a bird's-eye perspective.",
                    "short_desc": "from above"
                },
                "low_angle": {
                    "prefix": "From a low angle, ",
                    "observation": "the scene is viewed from below looking upward.",
                    "short_desc": "from below"
                },
                "elevated": {
                    "prefix": "From an elevated position, ",
                    "observation": "the scene is viewed from a higher vantage point.",
                    "short_desc": "from an elevated position"
                }
            }

            return fallback_templates.get(viewpoint, fallback_templates["eye_level"])

        except Exception as e:
            self.logger.warning(f"Error getting viewpoint template for '{viewpoint}': {str(e)}")
            return {
                "prefix": "",
                "observation": "the scene is viewed normally.",
                "short_desc": "normally"
            }

    def get_cultural_template(self, cultural_context: str) -> Dict[str, Any]:
        """
        獲取指定文化語境的模板

        Args:
            cultural_context: 文化語境

        Returns:
            Dict[str, Any]: 文化模板字典
        """
        try:
            cultural_templates = self.templates.get("cultural_templates", {})

            if cultural_context in cultural_templates:
                return cultural_templates[cultural_context]

            # 備用模板
            return {
                "elements": ["cultural elements"],
                "description": f"The scene displays {cultural_context} cultural characteristics."
            }

        except Exception as e:
            self.logger.warning(f"Error getting cultural template for '{cultural_context}': {str(e)}")
            return {
                "elements": ["various elements"],
                "description": "The scene displays cultural characteristics."
            }

    def get_scene_detail_templates(self, scene_type: str, viewpoint: Optional[str] = None) -> List[str]:
        """
        獲取場景詳細描述模板

        Args:
            scene_type: 場景類型
            viewpoint: 可選的視角類型

        Returns:
            List[str]: 場景描述模板列表
        """
        try:
            scene_templates = self.templates.get("scene_detail_templates", {})

            # 首先嘗試獲取特定視角的模板
            if viewpoint:
                viewpoint_key = f"{scene_type}_{viewpoint}"
                if viewpoint_key in scene_templates:
                    return scene_templates[viewpoint_key]

            # 然後嘗試獲取場景類型的通用模板
            if scene_type in scene_templates:
                return scene_templates[scene_type]

            # 最後使用默認模板
            if "default" in scene_templates:
                return scene_templates["default"]

            # 備用模板
            return ["A scene with various elements and objects."]

        except Exception as e:
            self.logger.warning(f"Error getting scene detail templates for '{scene_type}': {str(e)}")
            return ["A scene with various elements and objects."]

    def reload_templates(self):
        """
        重新載入所有模板
        """
        try:
            self.template_manager.reload_templates()
            self.logger.info("Templates reloaded successfully")
        except Exception as e:
            self.logger.error(f"Error reloading templates: {str(e)}")

    def get_template_categories(self) -> List[str]:
        """
        獲取所有可用的模板類別名稱

        Returns:
            List[str]: 模板類別名稱列表
        """
        return list(self.templates.keys())

    def template_exists(self, category: str, key: Optional[str] = None) -> bool:
        """
        檢查模板是否存在

        Args:
            category: 模板類別
            key: 可選的模板鍵值

        Returns:
            bool: 模板是否存在
        """
        try:
            if category not in self.templates:
                return False

            if key is None:
                return True

            category_templates = self.templates[category]
            if isinstance(category_templates, dict):
                return key in category_templates

            return False

        except Exception as e:
            self.logger.warning(f"Error checking template existence for {category}.{key}: {str(e)}")
            return False

    def apply_template(self, template: Union[str, Dict[str, Any]], scene_data: Dict[str, Any]) -> str:
        """
        應用選定的模板來生成場景描述

        Args:
            template: 模板字符串或模板內容字典
            scene_data: 場景分析的資料字典

        Returns:
            str: 最終生成的場景描述
        """
        try:
            # 如果傳入的是字符串模板,直接使用填充邏輯
            if isinstance(template, str):
                self.logger.debug("Processing string template directly")

                # 提取場景數據
                detected_objects = scene_data.get("detected_objects", [])
                scene_type = scene_data.get("scene_type", "general")
                places365_info = scene_data.get("places365_info")
                object_statistics = scene_data.get("object_statistics")
                functional_zones = scene_data.get("functional_zones", {})

                # 暫存功能區域資訊供填充邏輯使用
                self._current_functional_zones = functional_zones

                # 使用現有的填充邏輯
                filled_description = self.fill_template(
                    template,
                    detected_objects,
                    scene_type,
                    places365_info,
                    object_statistics
                )

                # 清理暫存資訊
                if hasattr(self, '_current_functional_zones'):
                    delattr(self, '_current_functional_zones')

                return filled_description

            # 如果傳入的是字典結構模板
            elif isinstance(template, dict):
                self.logger.debug("Processing structured template")
                return self._process_structured_template(template, scene_data)

            # 如果是模板名稱字符串且需要從registry獲取
            elif hasattr(self, 'template_registry') and template in self.template_registry:
                template_dict = self.template_registry[template]
                return self._process_structured_template(template_dict, scene_data)

            else:
                self.logger.warning(f"Invalid template format or template not found: {type(template)}")
                return self._generate_fallback_scene_description(scene_data)

        except Exception as e:
            self.logger.error(f"Error applying template: {str(e)}")
            return self._generate_fallback_scene_description(scene_data)

    def _process_structured_template(self, template: Dict[str, Any], scene_data: Dict[str, Any]) -> str:
        """
        處理結構化模板字典

        Args:
            template: 結構化模板字典
            scene_data: 場景分析資料

        Returns:
            str: 生成的場景描述
        """
        try:
            # 提取 scene_data 中各區塊資料
            zone_data = scene_data.get("functional_zones", scene_data.get("zones", {}))
            object_data = scene_data.get("detected_objects", [])
            scene_context = scene_data.get("scene_context", "")

            # 獲取模板結構
            structure = template.get("structure", [])
            if not structure:
                self.logger.warning("Template has no structure defined")
                return self._generate_fallback_scene_description(scene_data)

            description_parts = []

            # 按照模板結構生成描述
            for section in structure:
                section_type = section.get("type", "")
                content = section.get("content", "")

                if section_type == "opening":
                    description_parts.append(content)

                elif section_type == "zone_analysis":
                    zone_descriptions = self._generate_zone_descriptions(zone_data, section)
                    if zone_descriptions:
                        description_parts.extend(zone_descriptions)

                elif section_type == "object_summary":
                    object_summary = self._generate_object_summary(object_data, section)
                    if object_summary:
                        description_parts.append(object_summary)

                elif section_type == "conclusion":
                    conclusion = self._generate_conclusion(template, zone_data, object_data)
                    if conclusion:
                        description_parts.append(conclusion)

            # 合併並標準化輸出
            final_description = self._standardize_final_description(" ".join(description_parts))
            self.logger.info("Successfully applied structured template")
            return final_description

        except Exception as e:
            self.logger.error(f"Error processing structured template: {str(e)}")
            return self._generate_fallback_scene_description(scene_data)

    def _generate_fallback_scene_description(self, scene_data: Dict[str, Any]) -> str:
        """
        生成備用場景描述

        Args:
            scene_data: 場景分析資料

        Returns:
            str: 備用場景描述
        """
        try:
            detected_objects = scene_data.get("detected_objects", [])
            zones = scene_data.get("functional_zones", scene_data.get("zones", {}))
            scene_type = scene_data.get("scene_type", "general")

            object_count = len(detected_objects)
            zone_count = len(zones)

            if zone_count > 0 and object_count > 0:
                return f"Scene analysis completed with {zone_count} functional areas containing {object_count} identified objects."
            elif object_count > 0:
                return f"Scene analysis identified {object_count} objects in this {scene_type.replace('_', ' ')} environment."
            else:
                return f"Scene analysis completed for this {scene_type.replace('_', ' ')} environment."

        except Exception as e:
            self.logger.warning(f"Error generating fallback description: {str(e)}")
            return "Scene analysis completed with detected objects and functional areas."


    def _generate_zone_descriptions(self, zone_data: Dict[str, Any], section: Dict[str, Any]) -> List[str]:
        """
        生成功能區域描述
        """
        try:
            descriptions = []

            if not zone_data:
                return descriptions

            # 直接處理區域資料(zone_data 本身就是區域字典)
            sorted_zones = sorted(zone_data.items(),
                                key=lambda x: len(x[1].get("objects", [])),
                                reverse=True)

            for zone_name, zone_info in sorted_zones:
                description = zone_info.get("description", "")
                objects = zone_info.get("objects", [])

                if objects:
                    # 使用現有描述或生成基於物件的描述
                    if description and not any(tech in description.lower() for tech in ['zone', 'area', 'region']):
                        zone_desc = description
                    else:
                        # 生成更自然的區域描述
                        clean_zone_name = zone_name.replace('_', ' ').replace(' area', '').replace(' zone', '')
                        object_list = ', '.join(objects[:3])

                        if 'crossing' in zone_name or 'pedestrian' in zone_name:
                            zone_desc = f"In the central crossing area, there are {object_list}."
                        elif 'vehicle' in zone_name or 'traffic' in zone_name:
                            zone_desc = f"The vehicle movement area includes {object_list}."
                        elif 'control' in zone_name:
                            zone_desc = f"Traffic control elements include {object_list}."
                        else:
                            zone_desc = f"The {clean_zone_name} contains {object_list}."

                        if len(objects) > 3:
                            zone_desc += f" Along with {len(objects) - 3} additional elements."

                    descriptions.append(zone_desc)

            return descriptions

        except Exception as e:
            logger.error(f"Error generating zone descriptions: {str(e)}")
            return []

    def _generate_object_summary(self, object_data: List[Dict], section: Dict[str, Any]) -> str:
        """
        生成物件摘要描述
        """
        try:
            if not object_data:
                return ""

            # 統計物件類型並計算重要性
            object_stats = {}
            for obj in object_data:
                class_name = obj.get("class_name", "unknown")
                confidence = obj.get("confidence", 0.5)

                if class_name not in object_stats:
                    object_stats[class_name] = {"count": 0, "total_confidence": 0}

                object_stats[class_name]["count"] += 1
                object_stats[class_name]["total_confidence"] += confidence

            # 按重要性排序(結合數量和置信度)
            sorted_objects = []
            for class_name, stats in object_stats.items():
                count = stats["count"]
                avg_confidence = stats["total_confidence"] / count
                importance = count * 0.6 + avg_confidence * 0.4
                sorted_objects.append((class_name, count, importance))

            sorted_objects.sort(key=lambda x: x[2], reverse=True)

            # 生成自然語言描述
            descriptions = []
            for class_name, count, _ in sorted_objects[:5]:
                clean_name = class_name.replace('_', ' ')
                if count == 1:
                    article = "an" if clean_name[0].lower() in 'aeiou' else "a"
                    descriptions.append(f"{article} {clean_name}")
                else:
                    descriptions.append(f"{count} {clean_name}s")

            if len(descriptions) == 1:
                return f"The scene features {descriptions[0]}."
            elif len(descriptions) == 2:
                return f"The scene features {descriptions[0]} and {descriptions[1]}."
            else:
                main_items = ", ".join(descriptions[:-1])
                return f"The scene features {main_items}, and {descriptions[-1]}."

        except Exception as e:
            self.logger.error(f"Error generating object summary: {str(e)}")
            return ""

    def _generate_conclusion(self, template: Dict[str, Any], zone_data: Dict[str, Any],
                            object_data: List[Dict]) -> str:
        """
        生成結論描述
        """
        try:
            scene_type = template.get("scene_type", "general")
            zones_count = len(zone_data)
            objects_count = len(object_data)

            if scene_type == "indoor":
                conclusion = f"This indoor environment demonstrates clear functional organization with {zones_count} distinct areas and {objects_count} identified objects."
            elif scene_type == "outdoor":
                conclusion = f"This outdoor scene shows dynamic activity patterns across {zones_count} functional zones with {objects_count} detected elements."
            else:
                conclusion = f"The scene analysis reveals {zones_count} functional areas containing {objects_count} identifiable objects."

            return conclusion

        except Exception as e:
            logger.error(f"Error generating conclusion: {str(e)}")
            return ""

    def _standardize_final_description(self, description: str) -> str:
        """
        對最終描述進行標準化處理

        Args:
            description: 原始描述文本

        Returns:
            str: 標準化後的描述文本
        """
        try:
            # 移除多餘空格
            description = " ".join(description.split())

            # 確保句子間有適當間距
            description = description.replace(". ", ". ")

            # 移除任何殘留的技術性標識符
            technical_patterns = [
                r'zone_\d+', r'area_\d+', r'region_\d+',
                r'_zone', r'_area', r'_region'
            ]

            for pattern in technical_patterns:
                description = re.sub(pattern, '', description, flags=re.IGNORECASE)

            return description.strip()

        except Exception as e:
            logger.error(f"Error standardizing final description: {str(e)}")
            return description